Completed
Pull Request — master (#155)
by Jesus
02:25
created

lib.php ➔ bigbluebuttonbn_get_completion_state()   B

Complexity

Conditions 8
Paths 7

Size

Total Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
nc 7
nop 4
dl 0
loc 36
rs 8.0995
c 0
b 0
f 0
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
 * Library calls for Moodle and BigBlueButton.
19
 *
20
 * @package   mod_bigbluebuttonbn
21
 * @copyright 2010 onwards, Blindside Networks Inc
22
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 * @author    Jesus Federico  (jesus [at] blindsidenetworks [dt] com)
24
 * @author    Fred Dixon  (ffdixon [at] blindsidenetworks [dt] com)
25
 */
26
27
defined('MOODLE_INTERNAL') || die;
28
29
global $CFG;
30
31
require_once($CFG->dirroot.'/calendar/lib.php');
32
require_once($CFG->dirroot.'/message/lib.php');
33
require_once($CFG->dirroot.'/mod/lti/OAuth.php');
34
require_once($CFG->dirroot.'/tag/lib.php');
35
require_once($CFG->libdir.'/accesslib.php');
36
require_once($CFG->libdir.'/completionlib.php');
37
require_once($CFG->libdir.'/datalib.php');
38
require_once($CFG->libdir.'/enrollib.php');
39
require_once($CFG->libdir.'/filelib.php');
40
require_once($CFG->libdir.'/formslib.php');
41
42
// JWT is included in Moodle 3.7 core, but a local package is still needed for backward compatibility.
43
if (!class_exists('\Firebase\JWT\JWT')) {
44
    if (file_exists($CFG->libdir.'/php-jwt/src/JWT.php')) {
45
        require_once($CFG->libdir.'/php-jwt/src/JWT.php');
46
    } else {
47
        require_once($CFG->dirroot.'/mod/bigbluebuttonbn/vendor/firebase/php-jwt/src/JWT.php');
48
    }
49
}
50
51
if (!isset($CFG->bigbluebuttonbn)) {
52
    $CFG->bigbluebuttonbn = array();
53
}
54
55
if (file_exists(dirname(__FILE__).'/config.php')) {
56
    require_once(dirname(__FILE__).'/config.php');
57
}
58
59
/*
60
 * DURATIONCOMPENSATION: Feature removed by configuration
61
 */
62
$CFG->bigbluebuttonbn['scheduled_duration_enabled'] = 0;
63
/*
64
 * Remove this block when restored
65
 */
66
67
 /** @var BIGBLUEBUTTONBN_DEFAULT_SERVER_URL string of default bigbluebutton server url */
68
const BIGBLUEBUTTONBN_DEFAULT_SERVER_URL = 'http://test-install.blindsidenetworks.com/bigbluebutton/';
69
/** @var BIGBLUEBUTTONBN_DEFAULT_SHARED_SECRET string of default bigbluebutton server shared secret */
70
const BIGBLUEBUTTONBN_DEFAULT_SHARED_SECRET = '8cd8ef52e8e101574e400365b55e11a6';
71
/** @var BIGBLUEBUTTONBN_LOG_EVENT_ADD string defines the bigbluebuttonbn Add event */
72
const BIGBLUEBUTTONBN_LOG_EVENT_ADD = 'Add';
73
/** @var BIGBLUEBUTTONBN_LOG_EVENT_EDIT string defines the bigbluebuttonbn Edit event */
74
const BIGBLUEBUTTONBN_LOG_EVENT_EDIT = 'Edit';
75
/** @var BIGBLUEBUTTONBN_LOG_EVENT_CREATE string defines the bigbluebuttonbn Create event */
76
const BIGBLUEBUTTONBN_LOG_EVENT_CREATE = 'Create';
77
/** @var BIGBLUEBUTTONBN_LOG_EVENT_JOIN string defines the bigbluebuttonbn Join event */
78
const BIGBLUEBUTTONBN_LOG_EVENT_JOIN = 'Join';
79
/** @var BIGBLUEBUTTONBN_LOG_EVENT_PLAYED string defines the bigbluebuttonbn Playback event */
80
const BIGBLUEBUTTONBN_LOG_EVENT_PLAYED = 'Played';
81
/** @var BIGBLUEBUTTONBN_LOG_EVENT_LOGOUT string defines the bigbluebuttonbn Logout event */
82
const BIGBLUEBUTTONBN_LOG_EVENT_LOGOUT = 'Logout';
83
/** @var BIGBLUEBUTTONBN_LOG_EVENT_IMPORT string defines the bigbluebuttonbn Import event */
84
const BIGBLUEBUTTONBN_LOG_EVENT_IMPORT = 'Import';
85
/** @var BIGBLUEBUTTONBN_LOG_EVENT_DELETE string defines the bigbluebuttonbn Delete event */
86
const BIGBLUEBUTTONBN_LOG_EVENT_DELETE = 'Delete';
87
/** @var BIGBLUEBUTTON_LOG_EVENT_CALLBACK string defines the bigbluebuttonbn Callback event */
88
const BIGBLUEBUTTON_LOG_EVENT_CALLBACK = 'Callback';
89
/** @var BIGBLUEBUTTON_LOG_EVENT_SUMMARY string defines the bigbluebuttonbn Summary event */
90
const BIGBLUEBUTTON_LOG_EVENT_SUMMARY = 'Summary';
91
/**
92
 * Indicates API features that the bigbluebuttonbn supports.
93
 *
94
 * @uses FEATURE_IDNUMBER
95
 * @uses FEATURE_GROUPS
96
 * @uses FEATURE_GROUPINGS
97
 * @uses FEATURE_GROUPMEMBERSONLY
98
 * @uses FEATURE_MOD_INTRO
99
 * @uses FEATURE_BACKUP_MOODLE2
100
 * @uses FEATURE_COMPLETION_TRACKS_VIEWS
101
 * @uses FEATURE_COMPLETION_HAS_RULES
102
 * @uses FEATURE_GRADE_HAS_GRADE
103
 * @uses FEATURE_GRADE_OUTCOMES
104
 * @uses FEATURE_SHOW_DESCRIPTION
105
 * @param string $feature
106
 * @return mixed True if yes (some features may use other values)
107
 */
108
function bigbluebuttonbn_supports($feature) {
109
    if (!$feature) {
110
        return null;
111
    }
112
    $features = array(
113
        (string) FEATURE_IDNUMBER => true,
114
        (string) FEATURE_GROUPS => true,
115
        (string) FEATURE_GROUPINGS => true,
116
        (string) FEATURE_GROUPMEMBERSONLY => true,
117
        (string) FEATURE_MOD_INTRO => true,
118
        (string) FEATURE_BACKUP_MOODLE2 => true,
119
        (string) FEATURE_COMPLETION_TRACKS_VIEWS => true,
120
        (string) FEATURE_COMPLETION_HAS_RULES => true,
121
        (string) FEATURE_GRADE_HAS_GRADE => false,
122
        (string) FEATURE_GRADE_OUTCOMES => false,
123
        (string) FEATURE_SHOW_DESCRIPTION => true,
124
    );
125
    if (isset($features[(string) $feature])) {
126
        return $features[$feature];
127
    }
128
    return null;
129
}
130
131
/**
132
 * Obtains the automatic completion state for this bigbluebuttonbn based on any conditions
133
 * in bigbluebuttonbn settings.
134
 *
135
 * @param object $course Course
136
 * @param object $cm Course-module
137
 * @param int $userid User ID
138
 * @param bool $type Type of comparison (or/and; can be used as return value if no conditions)
139
 *
140
 * @return bool True if completed, false if not. (If no conditions, then return
141
 *   value depends on comparison type)
142
 */
143
function bigbluebuttonbn_get_completion_state($course, $cm, $userid, $type) {
0 ignored issues
show
Unused Code introduced by
The parameter $course is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
144
    global $DB;
145
146
    // Get bigbluebuttonbn details.
147
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $cm->instance));
148
    if (!$bigbluebuttonbn) {
149
        throw new Exception("Can't find bigbluebuttonbn {$cm->instance}");
150
    }
151
152
    // Default return value.
153
    $result = $type;
154
155
    if ($bigbluebuttonbn->completionattendance) {
156
        $sql  = "SELECT * FROM {bigbluebuttonbn_logs} ";
157
        $sql .= "WHERE bigbluebuttonbnid = ? AND userid = ? AND log = ?";
158
        $logs = $DB->get_records_sql($sql, array($bigbluebuttonbn->id, $userid, BIGBLUEBUTTON_LOG_EVENT_SUMMARY));
159
        if (!$logs) {
160
            // As completion by attendance was required, the activity hasn't been completed.
161
            return false;
162
        }
163
        $attendancecount = 0;
164
        foreach ($logs as $log) {
165
            $summary = json_decode($log->meta);
166
            $attendancecount += $summary->data->duration;
167
        }
168
        $attendancecount /= 60;
169
        $value = $bigbluebuttonbn->completionattendance <= $attendancecount;
170
        if ($type == COMPLETION_AND) {
171
            $result = $result && $value;
172
        } else {
173
            $result = $result || $value;
174
        }
175
    }
176
177
    return $result;
178
}
179
180
/**
181
 * Given an object containing all the necessary data,
182
 * (defined by the form in mod_form.php) this function
183
 * will create a new instance and return the id number
184
 * of the new instance.
185
 *
186
 * @param object $bigbluebuttonbn  An object from the form in mod_form.php
187
 * @return int The id of the newly inserted bigbluebuttonbn record
188
 */
189 View Code Duplication
function bigbluebuttonbn_add_instance($bigbluebuttonbn) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
190
    global $DB;
191
    // Excecute preprocess.
192
    bigbluebuttonbn_process_pre_save($bigbluebuttonbn);
193
    // Pre-set initial values.
194
    $bigbluebuttonbn->presentation = bigbluebuttonbn_get_media_file($bigbluebuttonbn);
195
    // Insert a record.
196
    $bigbluebuttonbn->id = $DB->insert_record('bigbluebuttonbn', $bigbluebuttonbn);
197
    // Encode meetingid.
198
    $bigbluebuttonbn->meetingid = bigbluebuttonbn_unique_meetingid_seed();
199
    // Set the meetingid column in the bigbluebuttonbn table.
200
    $DB->set_field('bigbluebuttonbn', 'meetingid', $bigbluebuttonbn->meetingid, array('id' => $bigbluebuttonbn->id));
201
    // Log insert action.
202
    bigbluebuttonbn_log($bigbluebuttonbn, BIGBLUEBUTTONBN_LOG_EVENT_ADD);
203
    // Complete the process.
204
    bigbluebuttonbn_process_post_save($bigbluebuttonbn);
205
    return $bigbluebuttonbn->id;
206
}
207
208
/**
209
 * Given an object containing all the necessary data,
210
 * (defined by the form in mod_form.php) this function
211
 * will update an existing instance with new data.
212
 *
213
 * @param object $bigbluebuttonbn  An object from the form in mod_form.php
214
 * @return bool Success/Fail
215
 */
216 View Code Duplication
function bigbluebuttonbn_update_instance($bigbluebuttonbn) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
217
    global $DB;
218
    // Excecute preprocess.
219
    bigbluebuttonbn_process_pre_save($bigbluebuttonbn);
220
    // Pre-set initial values.
221
    $bigbluebuttonbn->id = $bigbluebuttonbn->instance;
222
    $bigbluebuttonbn->presentation = bigbluebuttonbn_get_media_file($bigbluebuttonbn);
223
    // Update a record.
224
    $DB->update_record('bigbluebuttonbn', $bigbluebuttonbn);
225
    // Get the meetingid column in the bigbluebuttonbn table.
226
    $bigbluebuttonbn->meetingid = (string)$DB->get_field('bigbluebuttonbn', 'meetingid', array('id' => $bigbluebuttonbn->id));
227
    // Log update action.
228
    bigbluebuttonbn_log($bigbluebuttonbn, BIGBLUEBUTTONBN_LOG_EVENT_EDIT);
229
    // Complete the process.
230
    bigbluebuttonbn_process_post_save($bigbluebuttonbn);
231
    return true;
232
}
233
234
/**
235
 * Given an ID of an instance of this module,
236
 * this function will permanently delete the instance
237
 * and any data that depends on it.
238
 *
239
 * @param int $id Id of the module instance
240
 *
241
 * @return bool Success/Failure
242
 */
243
function bigbluebuttonbn_delete_instance($id) {
244
    global $DB;
245
246
    if (!$bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $id))) {
247
        return false;
248
    }
249
250
    // TODO: End the meeting if it is running.
251
252
    $result = true;
253
254
    // Delete any dependent records here.
255
    if (!$DB->delete_records('bigbluebuttonbn', array('id' => $bigbluebuttonbn->id))) {
256
        $result = false;
257
    }
258
259
    if (!$DB->delete_records('event', array('modulename' => 'bigbluebuttonbn', 'instance' => $bigbluebuttonbn->id))) {
260
        $result = false;
261
    }
262
263
    // Log action performed.
264
    bigbluebuttonbn_delete_instance_log($bigbluebuttonbn);
265
266
    return $result;
267
}
268
269
/**
270
 * Given an ID of an instance of this module,
271
 * this function will permanently delete the data that depends on it.
272
 *
273
 * @param object $bigbluebuttonbn Id of the module instance
274
 *
275
 * @return bool Success/Failure
276
 */
277
function bigbluebuttonbn_delete_instance_log($bigbluebuttonbn) {
278
    global $DB;
279
    $sql  = "SELECT * FROM {bigbluebuttonbn_logs} ";
280
    $sql .= "WHERE bigbluebuttonbnid = ? AND log = ? AND ". $DB->sql_compare_text('meta') . " = ?";
281
    $logs = $DB->get_records_sql($sql, array($bigbluebuttonbn->id, BIGBLUEBUTTONBN_LOG_EVENT_CREATE, "{\"record\":true}"));
282
    $meta = "{\"has_recordings\":" . empty($logs) ? "true" : "false" . "}";
283
    bigbluebuttonbn_log($bigbluebuttonbn, BIGBLUEBUTTONBN_LOG_EVENT_DELETE, [], $meta);
284
}
285
286
/**
287
 * Return a small object with summary information about what a
288
 * user has done with a given particular instance of this module
289
 * Used for user activity reports.
290
 *
291
 * @param object $course
292
 * @param object $user
293
 * @param object $mod
294
 * @param object $bigbluebuttonbn
295
 *
296
 * @return bool
297
 */
298
function bigbluebuttonbn_user_outline($course, $user, $mod, $bigbluebuttonbn) {
0 ignored issues
show
Unused Code introduced by
The parameter $mod is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
299
    if ($completed = bigbluebuttonbn_user_complete($course, $user, $bigbluebuttonbn)) {
300
        return fullname($user) . ' ' . get_string('view_message_has_joined', 'bigbluebuttonbn') . ' ' .
301
            get_string('view_message_session_for', 'bigbluebuttonbn') . ' ' . (string) $completed . ' ' .
302
            get_string('view_message_times', 'bigbluebuttonbn');
303
    }
304
    return '';
305
}
306
307
/**
308
 * Print a detailed representation of what a user has done with
309
 * a given particular instance of this module, for user activity reports.
310
 *
311
 * @param object|int $courseorid
312
 * @param object|int $userorid
313
 * @param object $bigbluebuttonbn
314
 *
315
 * @return bool
316
 */
317
function bigbluebuttonbn_user_complete($courseorid, $userorid, $bigbluebuttonbn) {
318
    global $DB;
319
    if (is_object($courseorid)) {
320
        $course = $courseorid;
321
    } else {
322
        $course = (object)array('id' => $courseorid);
323
    }
324
    if (is_object($userorid)) {
325
        $user = $userorid;
326
    } else {
327
        $user = (object)array('id' => $userorid);
328
    }
329
    $sql = "SELECT COUNT(*) FROM {bigbluebuttonbn_logs} ";
330
    $sql .= "WHERE courseid = ? AND bigbluebuttonbnid = ? AND userid = ? AND (log = ? OR log = ?)";
331
    $result = $DB->count_records_sql($sql, array($course->id, $bigbluebuttonbn->id, $user->id,
332
                                              BIGBLUEBUTTONBN_LOG_EVENT_JOIN, BIGBLUEBUTTONBN_LOG_EVENT_PLAYED));
333
    return $result;
334
}
335
336
/**
337
 * Returns all other caps used in module.
338
 *
339
 * @return string[]
340
 */
341
function bigbluebuttonbn_get_extra_capabilities() {
342
    return array('moodle/site:accessallgroups');
343
}
344
345
/**
346
 * Define items to be reset by course/reset.php
347
 *
348
 * @return array
349
 */
350
function bigbluebuttonbn_reset_course_items() {
351
    $items = array("events" => 0, "tags" => 0, "logs" => 0);
352
    // Include recordings only if enabled.
353
    if ((boolean)\mod_bigbluebuttonbn\locallib\config::recordings_enabled()) {
354
        $items["recordings"] = 0;
355
    }
356
    return $items;
357
}
358
359
/**
360
 * Called by course/reset.php
361
 *
362
 * @param object $mform
363
 * @return void
364
 */
365
function bigbluebuttonbn_reset_course_form_definition(&$mform) {
366
    $items = bigbluebuttonbn_reset_course_items();
367
    $mform->addElement('header', 'bigbluebuttonbnheader', get_string('modulenameplural', 'bigbluebuttonbn'));
368
    foreach ($items as $item => $default) {
369
        $mform->addElement('advcheckbox', "reset_bigbluebuttonbn_{$item}"
370
            , get_string("reset{$item}", 'bigbluebuttonbn')
371
        );
372
        if ($item == 'logs' || $item == 'recordings') {
373
            $mform->addHelpButton("reset_bigbluebuttonbn_{$item}", "reset{$item}", 'bigbluebuttonbn');
374
        }
375
    }
376
}
377
378
/**
379
 * Course reset form defaults.
380
 *
381
 * @param object $course
382
 * @return array
383
 */
384
function bigbluebuttonbn_reset_course_form_defaults($course) {
0 ignored issues
show
Unused Code introduced by
The parameter $course is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
385
    $formdefaults = array();
386
    $items = bigbluebuttonbn_reset_course_items();
387
    // All unchecked by default.
388
    foreach ($items as $item => $default) {
389
        $formdefaults["reset_bigbluebuttonbn_{$item}"] = $default;
390
    }
391
    return $formdefaults;
392
}
393
394
/**
395
 * This function is used by the reset_course_userdata function in moodlelib.
396
 *
397
 * @param array $data the data submitted from the reset course.
398
 * @return array status array
399
 */
400
function bigbluebuttonbn_reset_userdata($data) {
401
    $items = bigbluebuttonbn_reset_course_items();
402
    $status = array();
403
    // Any changes to the list of dates that needs to be rolled should be same during course restore and course reset.
404
    // See MDL-9367.
405
    if (array_key_exists('recordings', $items) && !empty($data->reset_bigbluebuttonbn_recordings)) {
406
        // Remove all the recordings from a BBB server that are linked to the room/activities in this course.
407
        bigbluebuttonbn_reset_recordings($data->courseid);
408
        unset($items['recordings']);
409
        $status[] = bigbluebuttonbn_reset_getstatus('recordings');
410
    }
411
    if (!empty($data->reset_bigbluebuttonbn_tags)) {
412
        // Remove all the tags linked to the room/activities in this course.
413
        bigbluebuttonbn_reset_tags($data->courseid);
414
        unset($items['tags']);
415
        $status[] = bigbluebuttonbn_reset_getstatus('tags');
416
    }
417
    foreach ($items as $item => $default) {
418
        // Remove instances or elements linked to this course, others than recordings or tags.
419
        if (!empty($data->{"reset_bigbluebuttonbn_{$item}"})) {
420
            call_user_func("bigbluebuttonbn_reset_{$item}", $data->courseid);
421
            $status[] = bigbluebuttonbn_reset_getstatus($item);
422
        }
423
    }
424
    return $status;
425
}
426
427
/**
428
 * Returns status used on every defined reset action.
429
 *
430
 * @param string $item
431
 * @return array status array
432
 */
433
function bigbluebuttonbn_reset_getstatus($item) {
434
    return array('component' => get_string('modulenameplural', 'bigbluebuttonbn')
435
        , 'item' => get_string("removed{$item}", 'bigbluebuttonbn')
436
        , 'error' => false);
437
}
438
439
/**
440
 * Used by the reset_course_userdata for deleting events linked to bigbluebuttonbn instances in the course.
441
 *
442
 * @param string $courseid
443
 * @return array status array
444
 */
445
function bigbluebuttonbn_reset_events($courseid) {
446
    global $DB;
447
    // Remove all the events.
448
    return $DB->delete_records('event', array('modulename' => 'bigbluebuttonbn', 'courseid' => $courseid));
449
}
450
451
/**
452
 * Used by the reset_course_userdata for deleting tags linked to bigbluebuttonbn instances in the course.
453
 *
454
 * @param array $courseid
455
 * @return array status array
456
 */
457
function bigbluebuttonbn_reset_tags($courseid) {
458
    global $DB;
459
    // Remove all the tags linked to the room/activities in this course.
460
    if ($bigbluebuttonbns = $DB->get_records('bigbluebuttonbn', array('course' => $courseid))) {
461
        foreach ($bigbluebuttonbns as $bigbluebuttonbn) {
462
            if (!$cm = get_coursemodule_from_instance('bigbluebuttonbn', $bigbluebuttonbn->id, $courseid)) {
463
                continue;
464
            }
465
            $context = context_module::instance($cm->id);
466
            core_tag_tag::delete_instances('mod_bigbluebuttonbn', null, $context->id);
467
        }
468
    }
469
}
470
471
/**
472
 * Used by the reset_course_userdata for deleting bigbluebuttonbn_logs linked to bigbluebuttonbn instances in the course.
473
 *
474
 * @param string $courseid
475
 * @return array status array
476
 */
477
function bigbluebuttonbn_reset_logs($courseid) {
478
    global $DB;
479
    // Remove all the logs.
480
    return $DB->delete_records('bigbluebuttonbn_logs', array('courseid' => $courseid));
481
}
482
483
/**
484
 * Used by the reset_course_userdata for deleting recordings in a BBB server linked to bigbluebuttonbn instances in the course.
485
 *
486
 * @param string $courseid
487
 * @return array status array
488
 */
489
function bigbluebuttonbn_reset_recordings($courseid) {
490
    require_once(__DIR__.'/locallib.php');
491
    // Criteria for search [courseid | bigbluebuttonbn=null | subset=false | includedeleted=true].
492
    $recordings = bigbluebuttonbn_get_recordings($courseid, null, false, true);
493
    // Remove all the recordings.
494
    bigbluebuttonbn_delete_recordings(implode(",", array_keys($recordings)));
495
}
496
497
/**
498
 * List of view style log actions.
499
 *
500
 * @return string[]
501
 */
502
function bigbluebuttonbn_get_view_actions() {
503
    return array('view', 'view all');
504
}
505
506
/**
507
 * List of update style log actions.
508
 *
509
 * @return string[]
510
 */
511
function bigbluebuttonbn_get_post_actions() {
512
    return array('update', 'add', 'delete');
513
}
514
515
/**
516
 * Print an overview of all bigbluebuttonbn instances for the courses.
517
 *
518
 * @param array $courses
519
 * @param array $htmlarray Passed by reference
520
 *
521
 * @return void
522
 */
523
function bigbluebuttonbn_print_overview($courses, &$htmlarray) {
524
    if (empty($courses) || !is_array($courses)) {
525
        return array();
526
    }
527
    $bns = get_all_instances_in_courses('bigbluebuttonbn', $courses);
528
    foreach ($bns as $bn) {
529
        $now = time();
530
        if ($bn->openingtime and (!$bn->closingtime or $bn->closingtime > $now)) {
531
            // A bigbluebuttonbn is scheduled.
532
            if (empty($htmlarray[$bn->course]['bigbluebuttonbn'])) {
533
                $htmlarray[$bn->course]['bigbluebuttonbn'] = '';
534
            }
535
            $htmlarray[$bn->course]['bigbluebuttonbn'] = bigbluebuttonbn_print_overview_element($bn, $now);
536
        }
537
    }
538
}
539
540
/**
541
 * Print an overview of a bigbluebuttonbn instance.
542
 *
543
 * @param array $bigbluebuttonbn
544
 * @param int $now
545
 *
546
 * @return string
547
 */
548
function bigbluebuttonbn_print_overview_element($bigbluebuttonbn, $now) {
549
    global $CFG;
550
    $start = 'started_at';
551
    if ($bigbluebuttonbn->openingtime > $now) {
552
        $start = 'starts_at';
553
    }
554
    $classes = '';
555
    if ($bigbluebuttonbn->visible) {
556
        $classes = 'class="dimmed" ';
557
    }
558
    $str  = '<div class="bigbluebuttonbn overview">'."\n";
559
    $str .= '  <div class="name">'.get_string('modulename', 'bigbluebuttonbn').':&nbsp;'."\n";
560
    $str .= '    <a '.$classes.'href="'.$CFG->wwwroot.'/mod/bigbluebuttonbn/view.php?id='.$bigbluebuttonbn->coursemodule.
561
      '">'.$bigbluebuttonbn->name.'</a>'."\n";
562
    $str .= '  </div>'."\n";
563
    $str .= '  <div class="info">'.get_string($start, 'bigbluebuttonbn').': '.userdate($bigbluebuttonbn->openingtime).
564
        '</div>'."\n";
565
    $str .= '  <div class="info">'.get_string('ends_at', 'bigbluebuttonbn').': '.userdate($bigbluebuttonbn->closingtime)
566
      .'</div>'."\n";
567
    $str .= '</div>'."\n";
568
    return $str;
569
}
570
571
/**
572
 * Given a course_module object, this function returns any
573
 * "extra" information that may be needed when printing
574
 * this activity in a course listing.
575
 * See get_array_of_activities() in course/lib.php.
576
 *
577
 * @param object $coursemodule
578
 *
579
 * @return null|cached_cm_info
580
 */
581
function bigbluebuttonbn_get_coursemodule_info($coursemodule) {
582
    global $DB;
583
584
    $dbparams = ['id' => $coursemodule->instance];
585
    $fields = 'id, name, intro, introformat, completionattendance';
586
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', $dbparams, $fields);
587
    if (!$bigbluebuttonbn) {
588
        return false;
589
    }
590
    $info = new cached_cm_info();
591
    $info->name = $bigbluebuttonbn->name;
592
    if ($coursemodule->showdescription) {
593
        // Convert intro to html. Do not filter cached version, filters run at display time.
594
        $info->content = format_module_intro('bigbluebuttonbn', $bigbluebuttonbn, $coursemodule->id, false);
595
    }
596
    // Populate the custom completion rules as key => value pairs, but only if the completion mode is 'automatic'.
597
    if ($coursemodule->completion == COMPLETION_TRACKING_AUTOMATIC) {
598
        $info->customdata['customcompletionrules']['completionattendance'] = $bigbluebuttonbn->completionattendance;
599
    }
600
601
    return $info;
602
}
603
604
/**
605
 * Callback which returns human-readable strings describing the active completion custom rules for the module instance.
606
 *
607
 * @param cm_info|stdClass $cm object with fields ->completion and ->customdata['customcompletionrules']
608
 * @return array $descriptions the array of descriptions for the custom rules.
609
 */
610
function mod_bigbluebuttonbn_get_completion_active_rule_descriptions($cm) {
611
    // Values will be present in cm_info, and we assume these are up to date.
612
    if (empty($cm->customdata['customcompletionrules'])
613
        || $cm->completion != COMPLETION_TRACKING_AUTOMATIC) {
614
        return [];
615
    }
616
617
    $descriptions = [];
618
    foreach ($cm->customdata['customcompletionrules'] as $key => $val) {
619
        switch ($key) {
620
            case 'completionattendance':
621
                if (!empty($val)) {
622
                    $descriptions[] = get_string('completionattendancedesc', 'bigbluebuttonbn', $val);
623
                }
624
                break;
625
            default:
626
                break;
627
        }
628
    }
629
    return $descriptions;
630
}
631
632
/**
633
 * Runs any processes that must run before a bigbluebuttonbn insert/update.
634
 *
635
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
636
 *
637
 * @return void
638
 **/
639
function bigbluebuttonbn_process_pre_save(&$bigbluebuttonbn) {
640
    bigbluebuttonbn_process_pre_save_instance($bigbluebuttonbn);
641
    bigbluebuttonbn_process_pre_save_checkboxes($bigbluebuttonbn);
642
    bigbluebuttonbn_process_pre_save_common($bigbluebuttonbn);
643
    $bigbluebuttonbn->participants = htmlspecialchars_decode($bigbluebuttonbn->participants);
644
}
645
646
/**
647
 * Runs process for defining the instance (insert/update).
648
 *
649
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
650
 *
651
 * @return void
652
 **/
653
function bigbluebuttonbn_process_pre_save_instance(&$bigbluebuttonbn) {
654
    require_once(__DIR__.'/locallib.php');
655
    $bigbluebuttonbn->timemodified = time();
656
    if ((integer)$bigbluebuttonbn->instance == 0) {
657
        $bigbluebuttonbn->meetingid = 0;
658
        $bigbluebuttonbn->timecreated = time();
659
        $bigbluebuttonbn->timemodified = 0;
660
        // As it is a new activity, assign passwords.
661
        $bigbluebuttonbn->moderatorpass = bigbluebuttonbn_random_password(12);
662
        $bigbluebuttonbn->viewerpass = bigbluebuttonbn_random_password(12, $bigbluebuttonbn->moderatorpass);
663
    }
664
}
665
666
/**
667
 * Runs process for assigning default value to checkboxes.
668
 *
669
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
670
 *
671
 * @return void
672
 **/
673
function bigbluebuttonbn_process_pre_save_checkboxes(&$bigbluebuttonbn) {
674
    if (!isset($bigbluebuttonbn->wait)) {
675
        $bigbluebuttonbn->wait = 0;
676
    }
677
    if (!isset($bigbluebuttonbn->record)) {
678
        $bigbluebuttonbn->record = 0;
679
    }
680
    if (!isset($bigbluebuttonbn->recordallfromstart)) {
681
        $bigbluebuttonbn->recordallfromstart = 0;
682
    }
683
    if (!isset($bigbluebuttonbn->recordhidebutton)) {
684
        $bigbluebuttonbn->recordhidebutton = 0;
685
    }
686
    if (!isset($bigbluebuttonbn->recordings_html)) {
687
        $bigbluebuttonbn->recordings_html = 0;
688
    }
689
    if (!isset($bigbluebuttonbn->recordings_deleted)) {
690
        $bigbluebuttonbn->recordings_deleted = 0;
691
    }
692
    if (!isset($bigbluebuttonbn->recordings_imported)) {
693
        $bigbluebuttonbn->recordings_imported = 0;
694
    }
695
    if (!isset($bigbluebuttonbn->recordings_preview)) {
696
        $bigbluebuttonbn->recordings_preview = 0;
697
    }
698
    if (!isset($bigbluebuttonbn->muteonstart)) {
699
        $bigbluebuttonbn->muteonstart = 0;
700
    }
701
}
702
703
/**
704
 * Runs process for wipping common settings when 'recordings only'.
705
 *
706
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
707
 *
708
 * @return void
709
 **/
710
function bigbluebuttonbn_process_pre_save_common(&$bigbluebuttonbn) {
711
    // Make sure common settings are removed when 'recordings only'.
712
    if ($bigbluebuttonbn->type == BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY) {
713
        $bigbluebuttonbn->groupmode = 0;
714
        $bigbluebuttonbn->groupingid = 0;
715
    }
716
}
717
718
/**
719
 * Runs any processes that must be run after a bigbluebuttonbn insert/update.
720
 *
721
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
722
 *
723
 * @return void
724
 **/
725
function bigbluebuttonbn_process_post_save($bigbluebuttonbn) {
726
    global $DB;
727
    if (!$bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $bigbluebuttonbn->id))) {
728
        return false;
729
    }
730
    if (isset($bigbluebuttonbn->notification) && $bigbluebuttonbn->notification) {
731
        bigbluebuttonbn_process_post_save_notification($bigbluebuttonbn);
732
    }
733
    bigbluebuttonbn_process_post_save_event($bigbluebuttonbn);
734
    bigbluebuttonbn_process_post_save_completion($bigbluebuttonbn);
735
}
736
737
/**
738
 * Generates a message on insert/update which is sent to all users enrolled.
739
 *
740
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
741
 *
742
 * @return void
743
 **/
744
function bigbluebuttonbn_process_post_save_notification(&$bigbluebuttonbn) {
745
    $action = get_string('mod_form_field_notification_msg_modified', 'bigbluebuttonbn');
746
    if (isset($bigbluebuttonbn->add) && !empty($bigbluebuttonbn->add)) {
747
        $action = get_string('mod_form_field_notification_msg_created', 'bigbluebuttonbn');
748
    }
749
    \mod_bigbluebuttonbn\locallib\notifier::notification_process($bigbluebuttonbn, $action);
750
}
751
752
/**
753
 * Generates an event after a bigbluebuttonbn insert/update.
754
 *
755
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
756
 *
757
 * @return void
758
 **/
759
function bigbluebuttonbn_process_post_save_event(&$bigbluebuttonbn) {
760
    global $DB;
761
    $eventid = $DB->get_field('event', 'id', array('modulename' => 'bigbluebuttonbn',
762
        'instance' => $bigbluebuttonbn->id));
763
    // Delete the event from calendar when/if openingtime is NOT set.
764
    if (!isset($bigbluebuttonbn->openingtime) || !$bigbluebuttonbn->openingtime) {
765
        if ($eventid) {
766
            $calendarevent = calendar_event::load($eventid);
767
            $calendarevent->delete();
768
        }
769
        return;
770
    }
771
    // Add evento to the calendar as openingtime is set.
772
    $event = new stdClass();
773
    $event->eventtype = BIGBLUEBUTTON_EVENT_MEETING_START;
774
    $event->type = CALENDAR_EVENT_TYPE_ACTION;
775
    $event->name = get_string('calendarstarts', 'bigbluebuttonbn', $bigbluebuttonbn->name);
776
    $event->description = format_module_intro('bigbluebuttonbn', $bigbluebuttonbn, $bigbluebuttonbn->coursemodule);
777
    $event->courseid = $bigbluebuttonbn->course;
778
    $event->groupid = 0;
779
    $event->userid = 0;
780
    $event->modulename = 'bigbluebuttonbn';
781
    $event->instance = $bigbluebuttonbn->id;
782
    $event->timestart = $bigbluebuttonbn->openingtime;
783
    $event->timeduration = 0;
784
    $event->timesort = $event->timestart;
785
    $event->visible = instance_is_visible('bigbluebuttonbn', $bigbluebuttonbn);
786
    $event->priority = null;
787
    // Update the event in calendar when/if eventid was found.
788
    if ($eventid) {
789
        $event->id = $eventid;
790
        $calendarevent = calendar_event::load($eventid);
791
        $calendarevent->update($event);
792
        return;
793
    }
794
    calendar_event::create($event);
795
}
796
797
/**
798
 * Generates an event after a bigbluebuttonbn activity is completed.
799
 *
800
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
801
 *
802
 * @return void
803
 **/
804
function bigbluebuttonbn_process_post_save_completion($bigbluebuttonbn) {
805
    if (!empty($bigbluebuttonbn->completionexpected)) {
806
        \core_completion\api::update_completion_date_event(
807
            $bigbluebuttonbn->coursemodule,
808
            'bigbluebuttonbn',
809
            $bigbluebuttonbn->id, $bigbluebuttonbn->completionexpected
810
          );
811
    }
812
}
813
814
/**
815
 * Get a full path to the file attached as a preuploaded presentation
816
 * or if there is none, set the presentation field will be set to blank.
817
 *
818
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
819
 *
820
 * @return string
821
 */
822
function bigbluebuttonbn_get_media_file(&$bigbluebuttonbn) {
823
    if (!isset($bigbluebuttonbn->presentation) || $bigbluebuttonbn->presentation == '') {
824
        return '';
825
    }
826
    $context = context_module::instance($bigbluebuttonbn->coursemodule);
827
    // Set the filestorage object.
828
    $fs = get_file_storage();
829
    // Save the file if it exists that is currently in the draft area.
830
    file_save_draft_area_files($bigbluebuttonbn->presentation, $context->id, 'mod_bigbluebuttonbn', 'presentation', 0);
831
    // Get the file if it exists.
832
    $files = $fs->get_area_files($context->id, 'mod_bigbluebuttonbn', 'presentation', 0,
833
        'itemid, filepath, filename', false);
834
    // Check that there is a file to process.
835
    $filesrc = '';
836
    if (count($files) == 1) {
837
        // Get the first (and only) file.
838
        $file = reset($files);
839
        $filesrc = '/'.$file->get_filename();
840
    }
841
    return $filesrc;
842
}
843
844
/**
845
 * Serves the bigbluebuttonbn attachments. Implements needed access control ;-).
846
 *
847
 * @category files
848
 *
849
 * @param stdClass $course        course object
850
 * @param stdClass $cm            course module object
851
 * @param stdClass $context       context object
852
 * @param string   $filearea      file area
853
 * @param array    $args          extra arguments
854
 * @param bool     $forcedownload whether or not force download
855
 * @param array    $options       additional options affecting the file serving
856
 *
857
 * @return false|null false if file not found, does not return if found - justsend the file
858
 */
859
function bigbluebuttonbn_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) {
860
    if (!bigbluebuttonbn_pluginfile_valid($context, $filearea)) {
861
        return false;
862
    }
863
    $file = bigbluebuttonbn_pluginfile_file($course, $cm, $context, $filearea, $args);
864
    if (empty($file)) {
865
        return false;
866
    }
867
    // Finally send the file.
868
    send_stored_file($file, 0, 0, $forcedownload, $options); // download MUST be forced - security!
869
}
870
871
/**
872
 * Helper for validating pluginfile.
873
 * @param stdClass $context       context object
874
 * @param string   $filearea      file area
875
 *
876
 * @return false|null false if file not valid
877
 */
878
function bigbluebuttonbn_pluginfile_valid($context, $filearea) {
879
880
    // Can be in context module or in context_system (if is the presentation by default).
881
    if (!in_array($context->contextlevel, array(CONTEXT_MODULE, CONTEXT_SYSTEM))) {
882
        return false;
883
    }
884
885
    if (!array_key_exists($filearea, bigbluebuttonbn_get_file_areas())) {
886
        return false;
887
    }
888
889
    return true;
890
}
891
892
/**
893
 * Helper for getting pluginfile.
894
 *
895
 * @param stdClass $course        course object
896
 * @param stdClass $cm            course module object
897
 * @param stdClass $context       context object
898
 * @param string   $filearea      file area
899
 * @param array    $args          extra arguments
900
 *
901
 * @return object
902
 */
903
function bigbluebuttonbn_pluginfile_file($course, $cm, $context, $filearea, $args) {
904
    $filename = bigbluebuttonbn_pluginfile_filename($course, $cm, $context, $args);
905
    if (!$filename) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $filename of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
906
        return false;
907
    }
908
    $fullpath = "/$context->id/mod_bigbluebuttonbn/$filearea/0/".$filename;
909
    $fs = get_file_storage();
910
    $file = $fs->get_file_by_hash(sha1($fullpath));
911
    if (!$file || $file->is_directory()) {
912
        return false;
913
    }
914
    return $file;
915
}
916
917
/**
918
 * Helper for give access to the file configured in setting as default presentation.
919
 *
920
 * @param stdClass $course        course object
921
 * @param stdClass $cm            course module object
922
 * @param stdClass $context       context object
923
 * @param array    $args          extra arguments
924
 *
925
 * @return array
926
 */
927
function bigbluebuttonbn_default_presentation_get_file($course, $cm, $context, $args) {
928
929
    // The difference with the standard bigbluebuttonbn_pluginfile_filename() are.
930
    // - Context is system, so we don't need to check the cmid in this case.
931
    // - The area is "presentationdefault_cache".
932
    if (count($args) > 1) {
933
        $cache = cache::make_from_params(cache_store::MODE_APPLICATION,
934
            'mod_bigbluebuttonbn',
935
            'presentationdefault_cache');
936
937
        $noncekey = sha1($context->id);
938
        $presentationnonce = $cache->get($noncekey);
939
        $noncevalue = $presentationnonce['value'];
940
        $noncecounter = $presentationnonce['counter'];
941
        if ($args['0'] != $noncevalue) {
942
            return;
943
        }
944
945
        // The nonce value is actually used twice because BigBlueButton reads the file two times.
946
        $noncecounter += 1;
947
        $cache->set($noncekey, array('value' => $noncevalue, 'counter' => $noncecounter));
948
        if ($noncecounter == 2) {
949
            $cache->delete($noncekey);
950
        }
951
        return($args['1']);
952
    }
953
    require_course_login($course, true, $cm);
954
    if (!has_capability('mod/bigbluebuttonbn:join', $context)) {
955
        return;
956
    }
957
    return implode('/', $args);
958
}
959
960
/**
961
 * Helper for getting pluginfile name.
962
 *
963
 * @param stdClass $course        course object
964
 * @param stdClass $cm            course module object
965
 * @param stdClass $context       context object
966
 * @param array    $args          extra arguments
967
 *
968
 * @return array
969
 */
970
function bigbluebuttonbn_pluginfile_filename($course, $cm, $context, $args) {
971
    global $DB;
972
973
    if ($context->contextlevel == CONTEXT_SYSTEM) {
974
        // Plugin has a file to use as default in general setting.
975
        return(bigbluebuttonbn_default_presentation_get_file($course, $cm, $context, $args));
976
    }
977
978
    if (count($args) > 1) {
979
        if (!$bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $cm->instance))) {
980
            return;
981
        }
982
        $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', 'presentation_cache');
983
        $noncekey = sha1($bigbluebuttonbn->id);
984
        $presentationnonce = $cache->get($noncekey);
985
        $noncevalue = $presentationnonce['value'];
986
        $noncecounter = $presentationnonce['counter'];
987
        if ($args['0'] != $noncevalue) {
988
            return;
989
        }
990
        // The nonce value is actually used twice because BigBlueButton reads the file two times.
991
        $noncecounter += 1;
992
        $cache->set($noncekey, array('value' => $noncevalue, 'counter' => $noncecounter));
993
        if ($noncecounter == 2) {
994
            $cache->delete($noncekey);
995
        }
996
        return $args['1'];
997
    }
998
    require_course_login($course, true, $cm);
999
    if (!has_capability('mod/bigbluebuttonbn:join', $context)) {
1000
        return;
1001
    }
1002
    return implode('/', $args);
1003
}
1004
1005
/**
1006
 * Returns an array of file areas.
1007
 *
1008
 * @category files
1009
 *
1010
 * @return array a list of available file areas
1011
 */
1012
function bigbluebuttonbn_get_file_areas() {
1013
    $areas = array();
1014
    $areas['presentation'] = get_string('mod_form_block_presentation', 'bigbluebuttonbn');
1015
    $areas['presentationdefault'] = get_string('mod_form_block_presentation_default', 'bigbluebuttonbn');
1016
    return $areas;
1017
}
1018
1019
/**
1020
 * Mark the activity completed (if required) and trigger the course_module_viewed event.
1021
 *
1022
 * @param  stdClass $bigbluebuttonbn        bigbluebuttonbn object
1023
 * @param  stdClass $course     course object
1024
 * @param  stdClass $cm         course module object
1025
 * @param  stdClass $context    context object
1026
 * @since Moodle 3.0
1027
 */
1028
function bigbluebuttonbn_view($bigbluebuttonbn, $course, $cm, $context) {
1029
1030
    // Trigger course_module_viewed event.
1031
    $params = array(
1032
        'context' => $context,
1033
        'objectid' => $bigbluebuttonbn->id
1034
    );
1035
1036
    $event = \mod_bigbluebuttonbn\event\bigbluebuttonbn_activity_viewed::create($params);
1037
    $event->add_record_snapshot('course_modules', $cm);
1038
    $event->add_record_snapshot('course', $course);
1039
    $event->add_record_snapshot('bigbluebuttonbn', $bigbluebuttonbn);
1040
    $event->trigger();
1041
1042
    // Completion.
1043
    $completion = new completion_info($course);
1044
    $completion->set_module_viewed($cm);
1045
}
1046
1047
/**
1048
 * Check if the module has any update that affects the current user since a given time.
1049
 *
1050
 * @param  cm_info $cm course module data
1051
 * @param  int $from the time to check updates from
1052
 * @param  array $filter  if we need to check only specific updates
1053
 * @return stdClass an object with the different type of areas indicating if they were updated or not
1054
 * @since Moodle 3.2
1055
 */
1056
function bigbluebuttonbn_check_updates_since(cm_info $cm, $from, $filter = array()) {
1057
    $updates = course_check_module_updates_since($cm, $from, array('content'), $filter);
1058
    return $updates;
1059
}
1060
1061
1062
/**
1063
 * Get icon mapping for font-awesome.
1064
 */
1065
function mod_bigbluebuttonbn_get_fontawesome_icon_map() {
1066
    return [
1067
        'mod_bigbluebuttonbn:icon' => 'icon-bigbluebutton',
1068
    ];
1069
}
1070
1071
/**
1072
 * This function receives a calendar event and returns the action associated with it, or null if there is none.
1073
 *
1074
 * This is used by block_myoverview in order to display the event appropriately. If null is returned then the event
1075
 * is not displayed on the block.
1076
 *
1077
 * @param calendar_event $event
1078
 * @param \core_calendar\action_factory $factory
1079
 * @return \core_calendar\local\event\entities\action_interface|null
1080
 */
1081
function mod_bigbluebuttonbn_core_calendar_provide_event_action(calendar_event $event,
1082
        \core_calendar\action_factory $factory) {
1083
    global $CFG, $DB;
1084
1085
    require_once($CFG->dirroot . '/mod/bigbluebuttonbn/locallib.php');
1086
1087
    // Get mod info.
1088
    $cm = get_fast_modinfo($event->courseid)->instances['bigbluebuttonbn'][$event->instance];
1089
1090
    // Get bigbluebuttonbn activity.
1091
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $event->instance), '*', MUST_EXIST);
1092
1093
    // Get if the user has joined in live session or viewed the recorded.
1094
    $usercomplete = bigbluebuttonbn_user_complete($event->courseid, $event->userid, $bigbluebuttonbn);
1095
    // Get if the room is available.
1096
    list($roomavailable) = bigbluebuttonbn_room_is_available($bigbluebuttonbn);
1097
    // Get if the user can join.
1098
    list($usercanjoin) = bigbluebuttonbn_user_can_join_meeting($bigbluebuttonbn);
1099
    // Get if the time has already passed.
1100
    $haspassed = $bigbluebuttonbn->openingtime < time();
1101
1102
    // Check if the room is closed and the user has already joined this session or played the record.
1103
    if ($haspassed && !$roomavailable && $usercomplete) {
1104
        return null;
1105
    }
1106
1107
    // Check if the user can join this session.
1108
    $actionable = ($roomavailable && $usercanjoin) || $haspassed;
1109
1110
    // Action data.
1111
    $string = get_string('view_room', 'bigbluebuttonbn');
1112
    $url = new \moodle_url('/mod/bigbluebuttonbn/view.php', array('id' => $cm->id));
1113
    if (groups_get_activity_groupmode($cm) == NOGROUPS) {
1114
        // No groups mode.
1115
        $string = get_string('view_conference_action_join', 'bigbluebuttonbn');
1116
        $url = new \moodle_url('/mod/bigbluebuttonbn/bbb_view.php', array('action' => 'join',
1117
            'id' => $cm->id, 'bn' => $bigbluebuttonbn->id, 'timeline' => 1));
1118
    }
1119
1120
    return $factory->create_instance($string, $url, 1, $actionable);
1121
}
1122
1123
/**
1124
 * Register a bigbluebuttonbn event
1125
 *
1126
 * @param object $bigbluebuttonbn
1127
 * @param string $event
1128
 * @param array  $overrides
1129
 * @param string $meta
1130
 *
1131
 * @return bool Success/Failure
1132
 */
1133
function bigbluebuttonbn_log($bigbluebuttonbn, $event, array $overrides = [], $meta = null) {
1134
    global $DB, $USER;
1135
    $log = new stdClass();
1136
    // Default values.
1137
    $log->courseid = $bigbluebuttonbn->course;
1138
    $log->bigbluebuttonbnid = $bigbluebuttonbn->id;
1139
    $log->userid = $USER->id;
1140
    $log->meetingid = $bigbluebuttonbn->meetingid;
1141
    $log->timecreated = time();
1142
    $log->log = $event;
1143
    $log->meta = $meta;
1144
    // Overrides.
1145
    foreach ($overrides as $key => $value) {
1146
        $log->$key = $value;
1147
    }
1148
    if (!$DB->insert_record('bigbluebuttonbn_logs', $log)) {
1149
        return false;
1150
    }
1151
    return true;
1152
}
1153