Completed
Pull Request — master (#160)
by Jesus
02:07
created

lib.php ➔ bigbluebuttonbn_get_completion_state()   F

Complexity

Conditions 20
Paths 157

Size

Total Lines 73

Duplication

Lines 34
Ratio 46.58 %

Importance

Changes 0
Metric Value
cc 20
nc 157
nop 4
dl 34
loc 73
rs 3.6916
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
    $sql  = "SELECT * FROM {bigbluebuttonbn_logs} ";
156
    $sql .= "WHERE bigbluebuttonbnid = ? AND userid = ? AND log = ?";
157
    $logs = $DB->get_records_sql($sql, array($bigbluebuttonbn->id, $userid, BIGBLUEBUTTON_LOG_EVENT_SUMMARY));
158
159
    if ($bigbluebuttonbn->completionattendance) {
160
        if (!$logs) {
161
            // As completion by attendance was required, the activity hasn't been completed.
162
            return false;
163
        }
164
        $attendancecount = 0;
165
        foreach ($logs as $log) {
166
            $summary = json_decode($log->meta);
167
            $attendancecount += $summary->data->duration;
168
        }
169
        $attendancecount /= 60;
170
        $value = $bigbluebuttonbn->completionattendance <= $attendancecount;
171
        if ($type == COMPLETION_AND) {
172
            $result = $result && $value;
173
        } else {
174
            $result = $result || $value;
175
        }
176
    }
177
178 View Code Duplication
    if ($bigbluebuttonbn->completionengagementchats) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
179
        if (!$logs) {
180
            // As completion by engagement with chat was required, the activity hasn't been completed.
181
            return false;
182
        }
183
        $engagementchatscount = 0;
184
        foreach ($logs as $log) {
185
            $summary = json_decode($log->meta);
186
            $engagementchatscount += $summary->data->engagement->chats;
187
        }
188
        $value = $bigbluebuttonbn->completionengagementchats <= $engagementchatcount;
0 ignored issues
show
Bug introduced by
The variable $engagementchatcount does not exist. Did you mean $engagementchatscount?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
189
        if ($type == COMPLETION_AND) {
190
            $result = $result && $value;
191
        } else {
192
            $result = $result || $value;
193
        }
194
    }
195
196 View Code Duplication
    if ($bigbluebuttonbn->completionengagementtalks) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
197
        if (!$logs) {
198
            // As completion by engagement with chat was required, the activity hasn't been completed.
199
            return false;
200
        }
201
        $engagementtalkscount = 0;
202
        foreach ($logs as $log) {
203
            $summary = json_decode($log->meta);
204
            $engagementtalkscount += $summary->data->engagement->talks;
205
        }
206
        $value = $bigbluebuttonbn->completionengagementtalks <= $engagementtalkscount;
207
        if ($type == COMPLETION_AND) {
208
            $result = $result && $value;
209
        } else {
210
            $result = $result || $value;
211
        }
212
    }
213
214
    return $result;
215
}
216
217
/**
218
 * Given an object containing all the necessary data,
219
 * (defined by the form in mod_form.php) this function
220
 * will create a new instance and return the id number
221
 * of the new instance.
222
 *
223
 * @param object $bigbluebuttonbn  An object from the form in mod_form.php
224
 * @return int The id of the newly inserted bigbluebuttonbn record
225
 */
226 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...
227
    global $DB;
228
    // Excecute preprocess.
229
    bigbluebuttonbn_process_pre_save($bigbluebuttonbn);
230
    // Pre-set initial values.
231
    $bigbluebuttonbn->presentation = bigbluebuttonbn_get_media_file($bigbluebuttonbn);
232
    // Insert a record.
233
    $bigbluebuttonbn->id = $DB->insert_record('bigbluebuttonbn', $bigbluebuttonbn);
234
    // Encode meetingid.
235
    $bigbluebuttonbn->meetingid = bigbluebuttonbn_unique_meetingid_seed();
236
    // Set the meetingid column in the bigbluebuttonbn table.
237
    $DB->set_field('bigbluebuttonbn', 'meetingid', $bigbluebuttonbn->meetingid, array('id' => $bigbluebuttonbn->id));
238
    // Log insert action.
239
    bigbluebuttonbn_log($bigbluebuttonbn, BIGBLUEBUTTONBN_LOG_EVENT_ADD);
240
    // Complete the process.
241
    bigbluebuttonbn_process_post_save($bigbluebuttonbn);
242
    return $bigbluebuttonbn->id;
243
}
244
245
/**
246
 * Given an object containing all the necessary data,
247
 * (defined by the form in mod_form.php) this function
248
 * will update an existing instance with new data.
249
 *
250
 * @param object $bigbluebuttonbn  An object from the form in mod_form.php
251
 * @return bool Success/Fail
252
 */
253 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...
254
    global $DB;
255
    // Excecute preprocess.
256
    bigbluebuttonbn_process_pre_save($bigbluebuttonbn);
257
    // Pre-set initial values.
258
    $bigbluebuttonbn->id = $bigbluebuttonbn->instance;
259
    $bigbluebuttonbn->presentation = bigbluebuttonbn_get_media_file($bigbluebuttonbn);
260
    // Update a record.
261
    $DB->update_record('bigbluebuttonbn', $bigbluebuttonbn);
262
    // Get the meetingid column in the bigbluebuttonbn table.
263
    $bigbluebuttonbn->meetingid = (string)$DB->get_field('bigbluebuttonbn', 'meetingid', array('id' => $bigbluebuttonbn->id));
264
    // Log update action.
265
    bigbluebuttonbn_log($bigbluebuttonbn, BIGBLUEBUTTONBN_LOG_EVENT_EDIT);
266
    // Complete the process.
267
    bigbluebuttonbn_process_post_save($bigbluebuttonbn);
268
    return true;
269
}
270
271
/**
272
 * Given an ID of an instance of this module,
273
 * this function will permanently delete the instance
274
 * and any data that depends on it.
275
 *
276
 * @param int $id Id of the module instance
277
 *
278
 * @return bool Success/Failure
279
 */
280
function bigbluebuttonbn_delete_instance($id) {
281
    global $DB;
282
283
    if (!$bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $id))) {
284
        return false;
285
    }
286
287
    // TODO: End the meeting if it is running.
288
289
    $result = true;
290
291
    // Delete any dependent records here.
292
    if (!$DB->delete_records('bigbluebuttonbn', array('id' => $bigbluebuttonbn->id))) {
293
        $result = false;
294
    }
295
296
    if (!$DB->delete_records('event', array('modulename' => 'bigbluebuttonbn', 'instance' => $bigbluebuttonbn->id))) {
297
        $result = false;
298
    }
299
300
    // Log action performed.
301
    bigbluebuttonbn_delete_instance_log($bigbluebuttonbn);
302
303
    return $result;
304
}
305
306
/**
307
 * Given an ID of an instance of this module,
308
 * this function will permanently delete the data that depends on it.
309
 *
310
 * @param object $bigbluebuttonbn Id of the module instance
311
 *
312
 * @return bool Success/Failure
313
 */
314
function bigbluebuttonbn_delete_instance_log($bigbluebuttonbn) {
315
    global $DB;
316
    $sql  = "SELECT * FROM {bigbluebuttonbn_logs} ";
317
    $sql .= "WHERE bigbluebuttonbnid = ? AND log = ? AND ". $DB->sql_compare_text('meta') . " = ?";
318
    $logs = $DB->get_records_sql($sql, array($bigbluebuttonbn->id, BIGBLUEBUTTONBN_LOG_EVENT_CREATE, "{\"record\":true}"));
319
    $meta = "{\"has_recordings\":" . empty($logs) ? "true" : "false" . "}";
320
    bigbluebuttonbn_log($bigbluebuttonbn, BIGBLUEBUTTONBN_LOG_EVENT_DELETE, [], $meta);
321
}
322
323
/**
324
 * Return a small object with summary information about what a
325
 * user has done with a given particular instance of this module
326
 * Used for user activity reports.
327
 *
328
 * @param object $course
329
 * @param object $user
330
 * @param object $mod
331
 * @param object $bigbluebuttonbn
332
 *
333
 * @return bool
334
 */
335
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...
336
    if ($completed = bigbluebuttonbn_user_complete($course, $user, $bigbluebuttonbn)) {
337
        return fullname($user) . ' ' . get_string('view_message_has_joined', 'bigbluebuttonbn') . ' ' .
338
            get_string('view_message_session_for', 'bigbluebuttonbn') . ' ' . (string) $completed . ' ' .
339
            get_string('view_message_times', 'bigbluebuttonbn');
340
    }
341
    return '';
342
}
343
344
/**
345
 * Print a detailed representation of what a user has done with
346
 * a given particular instance of this module, for user activity reports.
347
 *
348
 * @param object|int $courseorid
349
 * @param object|int $userorid
350
 * @param object $bigbluebuttonbn
351
 *
352
 * @return bool
353
 */
354
function bigbluebuttonbn_user_complete($courseorid, $userorid, $bigbluebuttonbn) {
355
    global $DB;
356
    if (is_object($courseorid)) {
357
        $course = $courseorid;
358
    } else {
359
        $course = (object)array('id' => $courseorid);
360
    }
361
    if (is_object($userorid)) {
362
        $user = $userorid;
363
    } else {
364
        $user = (object)array('id' => $userorid);
365
    }
366
    $sql = "SELECT COUNT(*) FROM {bigbluebuttonbn_logs} ";
367
    $sql .= "WHERE courseid = ? AND bigbluebuttonbnid = ? AND userid = ? AND (log = ? OR log = ?)";
368
    $result = $DB->count_records_sql($sql, array($course->id, $bigbluebuttonbn->id, $user->id,
369
                                              BIGBLUEBUTTONBN_LOG_EVENT_JOIN, BIGBLUEBUTTONBN_LOG_EVENT_PLAYED));
370
    return $result;
371
}
372
373
/**
374
 * Returns all other caps used in module.
375
 *
376
 * @return string[]
377
 */
378
function bigbluebuttonbn_get_extra_capabilities() {
379
    return array('moodle/site:accessallgroups');
380
}
381
382
/**
383
 * Define items to be reset by course/reset.php
384
 *
385
 * @return array
386
 */
387
function bigbluebuttonbn_reset_course_items() {
388
    $items = array("events" => 0, "tags" => 0, "logs" => 0);
389
    // Include recordings only if enabled.
390
    if ((boolean)\mod_bigbluebuttonbn\locallib\config::recordings_enabled()) {
391
        $items["recordings"] = 0;
392
    }
393
    return $items;
394
}
395
396
/**
397
 * Called by course/reset.php
398
 *
399
 * @param object $mform
400
 * @return void
401
 */
402
function bigbluebuttonbn_reset_course_form_definition(&$mform) {
403
    $items = bigbluebuttonbn_reset_course_items();
404
    $mform->addElement('header', 'bigbluebuttonbnheader', get_string('modulenameplural', 'bigbluebuttonbn'));
405
    foreach ($items as $item => $default) {
406
        $mform->addElement('advcheckbox', "reset_bigbluebuttonbn_{$item}"
407
            , get_string("reset{$item}", 'bigbluebuttonbn')
408
        );
409
        if ($item == 'logs' || $item == 'recordings') {
410
            $mform->addHelpButton("reset_bigbluebuttonbn_{$item}", "reset{$item}", 'bigbluebuttonbn');
411
        }
412
    }
413
}
414
415
/**
416
 * Course reset form defaults.
417
 *
418
 * @param object $course
419
 * @return array
420
 */
421
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...
422
    $formdefaults = array();
423
    $items = bigbluebuttonbn_reset_course_items();
424
    // All unchecked by default.
425
    foreach ($items as $item => $default) {
426
        $formdefaults["reset_bigbluebuttonbn_{$item}"] = $default;
427
    }
428
    return $formdefaults;
429
}
430
431
/**
432
 * This function is used by the reset_course_userdata function in moodlelib.
433
 *
434
 * @param array $data the data submitted from the reset course.
435
 * @return array status array
436
 */
437
function bigbluebuttonbn_reset_userdata($data) {
438
    $items = bigbluebuttonbn_reset_course_items();
439
    $status = array();
440
    // Any changes to the list of dates that needs to be rolled should be same during course restore and course reset.
441
    // See MDL-9367.
442
    if (array_key_exists('recordings', $items) && !empty($data->reset_bigbluebuttonbn_recordings)) {
443
        // Remove all the recordings from a BBB server that are linked to the room/activities in this course.
444
        bigbluebuttonbn_reset_recordings($data->courseid);
445
        unset($items['recordings']);
446
        $status[] = bigbluebuttonbn_reset_getstatus('recordings');
447
    }
448
    if (!empty($data->reset_bigbluebuttonbn_tags)) {
449
        // Remove all the tags linked to the room/activities in this course.
450
        bigbluebuttonbn_reset_tags($data->courseid);
451
        unset($items['tags']);
452
        $status[] = bigbluebuttonbn_reset_getstatus('tags');
453
    }
454
    foreach ($items as $item => $default) {
455
        // Remove instances or elements linked to this course, others than recordings or tags.
456
        if (!empty($data->{"reset_bigbluebuttonbn_{$item}"})) {
457
            call_user_func("bigbluebuttonbn_reset_{$item}", $data->courseid);
458
            $status[] = bigbluebuttonbn_reset_getstatus($item);
459
        }
460
    }
461
    return $status;
462
}
463
464
/**
465
 * Returns status used on every defined reset action.
466
 *
467
 * @param string $item
468
 * @return array status array
469
 */
470
function bigbluebuttonbn_reset_getstatus($item) {
471
    return array('component' => get_string('modulenameplural', 'bigbluebuttonbn')
472
        , 'item' => get_string("removed{$item}", 'bigbluebuttonbn')
473
        , 'error' => false);
474
}
475
476
/**
477
 * Used by the reset_course_userdata for deleting events linked to bigbluebuttonbn instances in the course.
478
 *
479
 * @param string $courseid
480
 * @return array status array
481
 */
482
function bigbluebuttonbn_reset_events($courseid) {
483
    global $DB;
484
    // Remove all the events.
485
    return $DB->delete_records('event', array('modulename' => 'bigbluebuttonbn', 'courseid' => $courseid));
486
}
487
488
/**
489
 * Used by the reset_course_userdata for deleting tags linked to bigbluebuttonbn instances in the course.
490
 *
491
 * @param array $courseid
492
 * @return array status array
493
 */
494
function bigbluebuttonbn_reset_tags($courseid) {
495
    global $DB;
496
    // Remove all the tags linked to the room/activities in this course.
497
    if ($bigbluebuttonbns = $DB->get_records('bigbluebuttonbn', array('course' => $courseid))) {
498
        foreach ($bigbluebuttonbns as $bigbluebuttonbn) {
499
            if (!$cm = get_coursemodule_from_instance('bigbluebuttonbn', $bigbluebuttonbn->id, $courseid)) {
500
                continue;
501
            }
502
            $context = context_module::instance($cm->id);
503
            core_tag_tag::delete_instances('mod_bigbluebuttonbn', null, $context->id);
504
        }
505
    }
506
}
507
508
/**
509
 * Used by the reset_course_userdata for deleting bigbluebuttonbn_logs linked to bigbluebuttonbn instances in the course.
510
 *
511
 * @param string $courseid
512
 * @return array status array
513
 */
514
function bigbluebuttonbn_reset_logs($courseid) {
515
    global $DB;
516
    // Remove all the logs.
517
    return $DB->delete_records('bigbluebuttonbn_logs', array('courseid' => $courseid));
518
}
519
520
/**
521
 * Used by the reset_course_userdata for deleting recordings in a BBB server linked to bigbluebuttonbn instances in the course.
522
 *
523
 * @param string $courseid
524
 * @return array status array
525
 */
526
function bigbluebuttonbn_reset_recordings($courseid) {
527
    require_once(__DIR__.'/locallib.php');
528
    // Criteria for search [courseid | bigbluebuttonbn=null | subset=false | includedeleted=true].
529
    $recordings = bigbluebuttonbn_get_recordings($courseid, null, false, true);
530
    // Remove all the recordings.
531
    bigbluebuttonbn_delete_recordings(implode(",", array_keys($recordings)));
532
}
533
534
/**
535
 * List of view style log actions.
536
 *
537
 * @return string[]
538
 */
539
function bigbluebuttonbn_get_view_actions() {
540
    return array('view', 'view all');
541
}
542
543
/**
544
 * List of update style log actions.
545
 *
546
 * @return string[]
547
 */
548
function bigbluebuttonbn_get_post_actions() {
549
    return array('update', 'add', 'delete');
550
}
551
552
/**
553
 * Print an overview of all bigbluebuttonbn instances for the courses.
554
 *
555
 * @param array $courses
556
 * @param array $htmlarray Passed by reference
557
 *
558
 * @return void
559
 */
560
function bigbluebuttonbn_print_overview($courses, &$htmlarray) {
561
    if (empty($courses) || !is_array($courses)) {
562
        return array();
563
    }
564
    $bns = get_all_instances_in_courses('bigbluebuttonbn', $courses);
565
    foreach ($bns as $bn) {
566
        $now = time();
567
        if ($bn->openingtime and (!$bn->closingtime or $bn->closingtime > $now)) {
568
            // A bigbluebuttonbn is scheduled.
569
            if (empty($htmlarray[$bn->course]['bigbluebuttonbn'])) {
570
                $htmlarray[$bn->course]['bigbluebuttonbn'] = '';
571
            }
572
            $htmlarray[$bn->course]['bigbluebuttonbn'] = bigbluebuttonbn_print_overview_element($bn, $now);
573
        }
574
    }
575
}
576
577
/**
578
 * Print an overview of a bigbluebuttonbn instance.
579
 *
580
 * @param array $bigbluebuttonbn
581
 * @param int $now
582
 *
583
 * @return string
584
 */
585
function bigbluebuttonbn_print_overview_element($bigbluebuttonbn, $now) {
586
    global $CFG;
587
    $start = 'started_at';
588
    if ($bigbluebuttonbn->openingtime > $now) {
589
        $start = 'starts_at';
590
    }
591
    $classes = '';
592
    if ($bigbluebuttonbn->visible) {
593
        $classes = 'class="dimmed" ';
594
    }
595
    $str  = '<div class="bigbluebuttonbn overview">'."\n";
596
    $str .= '  <div class="name">'.get_string('modulename', 'bigbluebuttonbn').':&nbsp;'."\n";
597
    $str .= '    <a '.$classes.'href="'.$CFG->wwwroot.'/mod/bigbluebuttonbn/view.php?id='.$bigbluebuttonbn->coursemodule.
598
      '">'.$bigbluebuttonbn->name.'</a>'."\n";
599
    $str .= '  </div>'."\n";
600
    $str .= '  <div class="info">'.get_string($start, 'bigbluebuttonbn').': '.userdate($bigbluebuttonbn->openingtime).
601
        '</div>'."\n";
602
    $str .= '  <div class="info">'.get_string('ends_at', 'bigbluebuttonbn').': '.userdate($bigbluebuttonbn->closingtime)
603
      .'</div>'."\n";
604
    $str .= '</div>'."\n";
605
    return $str;
606
}
607
608
/**
609
 * Given a course_module object, this function returns any
610
 * "extra" information that may be needed when printing
611
 * this activity in a course listing.
612
 * See get_array_of_activities() in course/lib.php.
613
 *
614
 * @param object $coursemodule
615
 *
616
 * @return null|cached_cm_info
617
 */
618
function bigbluebuttonbn_get_coursemodule_info($coursemodule) {
619
    global $DB;
620
621
    $dbparams = ['id' => $coursemodule->instance];
622
    $fields = 'id, name, intro, introformat, completionattendance';
623
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', $dbparams, $fields);
624
    if (!$bigbluebuttonbn) {
625
        return false;
626
    }
627
    $info = new cached_cm_info();
628
    $info->name = $bigbluebuttonbn->name;
629
    if ($coursemodule->showdescription) {
630
        // Convert intro to html. Do not filter cached version, filters run at display time.
631
        $info->content = format_module_intro('bigbluebuttonbn', $bigbluebuttonbn, $coursemodule->id, false);
632
    }
633
    // Populate the custom completion rules as key => value pairs, but only if the completion mode is 'automatic'.
634
    if ($coursemodule->completion == COMPLETION_TRACKING_AUTOMATIC) {
635
        $info->customdata['customcompletionrules']['completionattendance'] = $bigbluebuttonbn->completionattendance;
636
    }
637
638
    return $info;
639
}
640
641
/**
642
 * Callback which returns human-readable strings describing the active completion custom rules for the module instance.
643
 *
644
 * @param cm_info|stdClass $cm object with fields ->completion and ->customdata['customcompletionrules']
645
 * @return array $descriptions the array of descriptions for the custom rules.
646
 */
647
function mod_bigbluebuttonbn_get_completion_active_rule_descriptions($cm) {
648
    // Values will be present in cm_info, and we assume these are up to date.
649
    if (empty($cm->customdata['customcompletionrules'])
650
        || $cm->completion != COMPLETION_TRACKING_AUTOMATIC) {
651
        return [];
652
    }
653
654
    $descriptions = [];
655
    foreach ($cm->customdata['customcompletionrules'] as $key => $val) {
656
        switch ($key) {
657
            case 'completionattendance':
658
                if (!empty($val)) {
659
                    $descriptions[] = get_string('completionattendancedesc', 'bigbluebuttonbn', $val);
660
                    $descriptions[] = get_string('completionengagementdesc', 'bigbluebuttonbn', $val);
661
                }
662
                break;
663
            default:
664
                break;
665
        }
666
    }
667
    return $descriptions;
668
}
669
670
/**
671
 * Runs any processes that must run before a bigbluebuttonbn insert/update.
672
 *
673
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
674
 *
675
 * @return void
676
 **/
677
function bigbluebuttonbn_process_pre_save(&$bigbluebuttonbn) {
678
    bigbluebuttonbn_process_pre_save_instance($bigbluebuttonbn);
679
    bigbluebuttonbn_process_pre_save_checkboxes($bigbluebuttonbn);
680
    bigbluebuttonbn_process_pre_save_common($bigbluebuttonbn);
681
    $bigbluebuttonbn->participants = htmlspecialchars_decode($bigbluebuttonbn->participants);
682
}
683
684
/**
685
 * Runs process for defining the instance (insert/update).
686
 *
687
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
688
 *
689
 * @return void
690
 **/
691
function bigbluebuttonbn_process_pre_save_instance(&$bigbluebuttonbn) {
692
    require_once(__DIR__.'/locallib.php');
693
    $bigbluebuttonbn->timemodified = time();
694
    if ((integer)$bigbluebuttonbn->instance == 0) {
695
        $bigbluebuttonbn->meetingid = 0;
696
        $bigbluebuttonbn->timecreated = time();
697
        $bigbluebuttonbn->timemodified = 0;
698
        // As it is a new activity, assign passwords.
699
        $bigbluebuttonbn->moderatorpass = bigbluebuttonbn_random_password(12);
700
        $bigbluebuttonbn->viewerpass = bigbluebuttonbn_random_password(12, $bigbluebuttonbn->moderatorpass);
701
    }
702
}
703
704
/**
705
 * Runs process for assigning default value to checkboxes.
706
 *
707
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
708
 *
709
 * @return void
710
 **/
711
function bigbluebuttonbn_process_pre_save_checkboxes(&$bigbluebuttonbn) {
712
    if (!isset($bigbluebuttonbn->wait)) {
713
        $bigbluebuttonbn->wait = 0;
714
    }
715
    if (!isset($bigbluebuttonbn->record)) {
716
        $bigbluebuttonbn->record = 0;
717
    }
718
    if (!isset($bigbluebuttonbn->recordallfromstart)) {
719
        $bigbluebuttonbn->recordallfromstart = 0;
720
    }
721
    if (!isset($bigbluebuttonbn->recordhidebutton)) {
722
        $bigbluebuttonbn->recordhidebutton = 0;
723
    }
724
    if (!isset($bigbluebuttonbn->recordings_html)) {
725
        $bigbluebuttonbn->recordings_html = 0;
726
    }
727
    if (!isset($bigbluebuttonbn->recordings_deleted)) {
728
        $bigbluebuttonbn->recordings_deleted = 0;
729
    }
730
    if (!isset($bigbluebuttonbn->recordings_imported)) {
731
        $bigbluebuttonbn->recordings_imported = 0;
732
    }
733
    if (!isset($bigbluebuttonbn->recordings_preview)) {
734
        $bigbluebuttonbn->recordings_preview = 0;
735
    }
736
    if (!isset($bigbluebuttonbn->muteonstart)) {
737
        $bigbluebuttonbn->muteonstart = 0;
738
    }
739
}
740
741
/**
742
 * Runs process for wipping common settings when 'recordings only'.
743
 *
744
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
745
 *
746
 * @return void
747
 **/
748
function bigbluebuttonbn_process_pre_save_common(&$bigbluebuttonbn) {
749
    // Make sure common settings are removed when 'recordings only'.
750
    if ($bigbluebuttonbn->type == BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY) {
751
        $bigbluebuttonbn->groupmode = 0;
752
        $bigbluebuttonbn->groupingid = 0;
753
    }
754
}
755
756
/**
757
 * Runs any processes that must be run after a bigbluebuttonbn insert/update.
758
 *
759
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
760
 *
761
 * @return void
762
 **/
763
function bigbluebuttonbn_process_post_save(&$bigbluebuttonbn) {
764
    if (isset($bigbluebuttonbn->notification) && $bigbluebuttonbn->notification) {
765
        bigbluebuttonbn_process_post_save_notification($bigbluebuttonbn);
766
    }
767
    bigbluebuttonbn_process_post_save_event($bigbluebuttonbn);
768
    bigbluebuttonbn_process_post_save_completion($bigbluebuttonbn);
769
}
770
771
/**
772
 * Generates a message on insert/update which is sent to all users enrolled.
773
 *
774
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
775
 *
776
 * @return void
777
 **/
778
function bigbluebuttonbn_process_post_save_notification(&$bigbluebuttonbn) {
779
    $action = get_string('mod_form_field_notification_msg_modified', 'bigbluebuttonbn');
780
    if (isset($bigbluebuttonbn->add) && !empty($bigbluebuttonbn->add)) {
781
        $action = get_string('mod_form_field_notification_msg_created', 'bigbluebuttonbn');
782
    }
783
    \mod_bigbluebuttonbn\locallib\notifier::notification_process($bigbluebuttonbn, $action);
784
}
785
786
/**
787
 * Generates an event after a bigbluebuttonbn insert/update.
788
 *
789
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
790
 *
791
 * @return void
792
 **/
793
function bigbluebuttonbn_process_post_save_event(&$bigbluebuttonbn) {
794
    global $DB;
795
    $eventid = $DB->get_field('event', 'id', array('modulename' => 'bigbluebuttonbn',
796
        'instance' => $bigbluebuttonbn->id));
797
    // Delete the event from calendar when/if openingtime is NOT set.
798
    if (!isset($bigbluebuttonbn->openingtime) || !$bigbluebuttonbn->openingtime) {
799
        if ($eventid) {
800
            $calendarevent = calendar_event::load($eventid);
801
            $calendarevent->delete();
802
        }
803
        return;
804
    }
805
    // Add evento to the calendar as openingtime is set.
806
    $event = new stdClass();
807
    $event->eventtype = BIGBLUEBUTTON_EVENT_MEETING_START;
808
    $event->type = CALENDAR_EVENT_TYPE_ACTION;
809
    $event->name = get_string('calendarstarts', 'bigbluebuttonbn', $bigbluebuttonbn->name);
810
    $event->description = format_module_intro('bigbluebuttonbn', $bigbluebuttonbn, $bigbluebuttonbn->coursemodule);
811
    $event->courseid = $bigbluebuttonbn->course;
812
    $event->groupid = 0;
813
    $event->userid = 0;
814
    $event->modulename = 'bigbluebuttonbn';
815
    $event->instance = $bigbluebuttonbn->id;
816
    $event->timestart = $bigbluebuttonbn->openingtime;
817
    $event->timeduration = 0;
818
    $event->timesort = $event->timestart;
819
    $event->visible = instance_is_visible('bigbluebuttonbn', $bigbluebuttonbn);
820
    $event->priority = null;
821
    // Update the event in calendar when/if eventid was found.
822
    if ($eventid) {
823
        $event->id = $eventid;
824
        $calendarevent = calendar_event::load($eventid);
825
        $calendarevent->update($event);
826
        return;
827
    }
828
    calendar_event::create($event);
829
}
830
831
/**
832
 * Generates an event after a bigbluebuttonbn activity is completed.
833
 *
834
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
835
 *
836
 * @return void
837
 **/
838
function bigbluebuttonbn_process_post_save_completion($bigbluebuttonbn) {
839
    if (!empty($bigbluebuttonbn->completionexpected)) {
840
        \core_completion\api::update_completion_date_event(
841
            $bigbluebuttonbn->coursemodule,
842
            'bigbluebuttonbn',
843
            $bigbluebuttonbn->id, $bigbluebuttonbn->completionexpected
844
          );
845
    }
846
}
847
848
/**
849
 * Get a full path to the file attached as a preuploaded presentation
850
 * or if there is none, set the presentation field will be set to blank.
851
 *
852
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
853
 *
854
 * @return string
855
 */
856
function bigbluebuttonbn_get_media_file(&$bigbluebuttonbn) {
857
    if (!isset($bigbluebuttonbn->presentation) || $bigbluebuttonbn->presentation == '') {
858
        return '';
859
    }
860
    $context = context_module::instance($bigbluebuttonbn->coursemodule);
861
    // Set the filestorage object.
862
    $fs = get_file_storage();
863
    // Save the file if it exists that is currently in the draft area.
864
    file_save_draft_area_files($bigbluebuttonbn->presentation, $context->id, 'mod_bigbluebuttonbn', 'presentation', 0);
865
    // Get the file if it exists.
866
    $files = $fs->get_area_files($context->id, 'mod_bigbluebuttonbn', 'presentation', 0,
867
        'itemid, filepath, filename', false);
868
    // Check that there is a file to process.
869
    $filesrc = '';
870
    if (count($files) == 1) {
871
        // Get the first (and only) file.
872
        $file = reset($files);
873
        $filesrc = '/'.$file->get_filename();
874
    }
875
    return $filesrc;
876
}
877
878
/**
879
 * Serves the bigbluebuttonbn attachments. Implements needed access control ;-).
880
 *
881
 * @category files
882
 *
883
 * @param stdClass $course        course object
884
 * @param stdClass $cm            course module object
885
 * @param stdClass $context       context object
886
 * @param string   $filearea      file area
887
 * @param array    $args          extra arguments
888
 * @param bool     $forcedownload whether or not force download
889
 * @param array    $options       additional options affecting the file serving
890
 *
891
 * @return false|null false if file not found, does not return if found - justsend the file
892
 */
893
function bigbluebuttonbn_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) {
894
    if (!bigbluebuttonbn_pluginfile_valid($context, $filearea)) {
895
        return false;
896
    }
897
    $file = bigbluebuttonbn_pluginfile_file($course, $cm, $context, $filearea, $args);
898
    if (empty($file)) {
899
        return false;
900
    }
901
    // Finally send the file.
902
    send_stored_file($file, 0, 0, $forcedownload, $options); // download MUST be forced - security!
903
}
904
905
/**
906
 * Helper for validating pluginfile.
907
 * @param stdClass $context       context object
908
 * @param string   $filearea      file area
909
 *
910
 * @return false|null false if file not valid
911
 */
912
function bigbluebuttonbn_pluginfile_valid($context, $filearea) {
913
914
    // Can be in context module or in context_system (if is the presentation by default).
915
    if (!in_array($context->contextlevel, array(CONTEXT_MODULE, CONTEXT_SYSTEM))) {
916
        return false;
917
    }
918
919
    if (!array_key_exists($filearea, bigbluebuttonbn_get_file_areas())) {
920
        return false;
921
    }
922
923
    return true;
924
}
925
926
/**
927
 * Helper for getting pluginfile.
928
 *
929
 * @param stdClass $course        course object
930
 * @param stdClass $cm            course module object
931
 * @param stdClass $context       context object
932
 * @param string   $filearea      file area
933
 * @param array    $args          extra arguments
934
 *
935
 * @return object
936
 */
937
function bigbluebuttonbn_pluginfile_file($course, $cm, $context, $filearea, $args) {
938
    $filename = bigbluebuttonbn_pluginfile_filename($course, $cm, $context, $args);
939
    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...
940
        return false;
941
    }
942
    $fullpath = "/$context->id/mod_bigbluebuttonbn/$filearea/0/".$filename;
943
    $fs = get_file_storage();
944
    $file = $fs->get_file_by_hash(sha1($fullpath));
945
    if (!$file || $file->is_directory()) {
946
        return false;
947
    }
948
    return $file;
949
}
950
951
/**
952
 * Helper for give access to the file configured in setting as default presentation.
953
 *
954
 * @param stdClass $course        course object
955
 * @param stdClass $cm            course module object
956
 * @param stdClass $context       context object
957
 * @param array    $args          extra arguments
958
 *
959
 * @return array
960
 */
961
function bigbluebuttonbn_default_presentation_get_file($course, $cm, $context, $args) {
962
963
    // The difference with the standard bigbluebuttonbn_pluginfile_filename() are.
964
    // - Context is system, so we don't need to check the cmid in this case.
965
    // - The area is "presentationdefault_cache".
966
    if (count($args) > 1) {
967
        $cache = cache::make_from_params(cache_store::MODE_APPLICATION,
968
            'mod_bigbluebuttonbn',
969
            'presentationdefault_cache');
970
971
        $noncekey = sha1($context->id);
972
        $presentationnonce = $cache->get($noncekey);
973
        $noncevalue = $presentationnonce['value'];
974
        $noncecounter = $presentationnonce['counter'];
975
        if ($args['0'] != $noncevalue) {
976
            return;
977
        }
978
979
        // The nonce value is actually used twice because BigBlueButton reads the file two times.
980
        $noncecounter += 1;
981
        $cache->set($noncekey, array('value' => $noncevalue, 'counter' => $noncecounter));
982
        if ($noncecounter == 2) {
983
            $cache->delete($noncekey);
984
        }
985
        return($args['1']);
986
    }
987
    require_course_login($course, true, $cm);
988
    if (!has_capability('mod/bigbluebuttonbn:join', $context)) {
989
        return;
990
    }
991
    return implode('/', $args);
992
}
993
994
/**
995
 * Helper for getting pluginfile name.
996
 *
997
 * @param stdClass $course        course object
998
 * @param stdClass $cm            course module object
999
 * @param stdClass $context       context object
1000
 * @param array    $args          extra arguments
1001
 *
1002
 * @return array
1003
 */
1004
function bigbluebuttonbn_pluginfile_filename($course, $cm, $context, $args) {
1005
    global $DB;
1006
1007
    if ($context->contextlevel == CONTEXT_SYSTEM) {
1008
        // Plugin has a file to use as default in general setting.
1009
        return(bigbluebuttonbn_default_presentation_get_file($course, $cm, $context, $args));
1010
    }
1011
1012
    if (count($args) > 1) {
1013
        if (!$bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $cm->instance))) {
1014
            return;
1015
        }
1016
        $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', 'presentation_cache');
1017
        $noncekey = sha1($bigbluebuttonbn->id);
1018
        $presentationnonce = $cache->get($noncekey);
1019
        $noncevalue = $presentationnonce['value'];
1020
        $noncecounter = $presentationnonce['counter'];
1021
        if ($args['0'] != $noncevalue) {
1022
            return;
1023
        }
1024
        // The nonce value is actually used twice because BigBlueButton reads the file two times.
1025
        $noncecounter += 1;
1026
        $cache->set($noncekey, array('value' => $noncevalue, 'counter' => $noncecounter));
1027
        if ($noncecounter == 2) {
1028
            $cache->delete($noncekey);
1029
        }
1030
        return $args['1'];
1031
    }
1032
    require_course_login($course, true, $cm);
1033
    if (!has_capability('mod/bigbluebuttonbn:join', $context)) {
1034
        return;
1035
    }
1036
    return implode('/', $args);
1037
}
1038
1039
/**
1040
 * Returns an array of file areas.
1041
 *
1042
 * @category files
1043
 *
1044
 * @return array a list of available file areas
1045
 */
1046
function bigbluebuttonbn_get_file_areas() {
1047
    $areas = array();
1048
    $areas['presentation'] = get_string('mod_form_block_presentation', 'bigbluebuttonbn');
1049
    $areas['presentationdefault'] = get_string('mod_form_block_presentation_default', 'bigbluebuttonbn');
1050
    return $areas;
1051
}
1052
1053
/**
1054
 * Mark the activity completed (if required) and trigger the course_module_viewed event.
1055
 *
1056
 * @param  stdClass $bigbluebuttonbn        bigbluebuttonbn object
1057
 * @param  stdClass $course     course object
1058
 * @param  stdClass $cm         course module object
1059
 * @param  stdClass $context    context object
1060
 * @since Moodle 3.0
1061
 */
1062
function bigbluebuttonbn_view($bigbluebuttonbn, $course, $cm, $context) {
1063
1064
    // Trigger course_module_viewed event.
1065
    $params = array(
1066
        'context' => $context,
1067
        'objectid' => $bigbluebuttonbn->id
1068
    );
1069
1070
    $event = \mod_bigbluebuttonbn\event\bigbluebuttonbn_activity_viewed::create($params);
1071
    $event->add_record_snapshot('course_modules', $cm);
1072
    $event->add_record_snapshot('course', $course);
1073
    $event->add_record_snapshot('bigbluebuttonbn', $bigbluebuttonbn);
1074
    $event->trigger();
1075
1076
    // Completion.
1077
    $completion = new completion_info($course);
1078
    $completion->set_module_viewed($cm);
1079
}
1080
1081
/**
1082
 * Check if the module has any update that affects the current user since a given time.
1083
 *
1084
 * @param  cm_info $cm course module data
1085
 * @param  int $from the time to check updates from
1086
 * @param  array $filter  if we need to check only specific updates
1087
 * @return stdClass an object with the different type of areas indicating if they were updated or not
1088
 * @since Moodle 3.2
1089
 */
1090
function bigbluebuttonbn_check_updates_since(cm_info $cm, $from, $filter = array()) {
1091
    $updates = course_check_module_updates_since($cm, $from, array('content'), $filter);
1092
    return $updates;
1093
}
1094
1095
1096
/**
1097
 * Get icon mapping for font-awesome.
1098
 */
1099
function mod_bigbluebuttonbn_get_fontawesome_icon_map() {
1100
    return [
1101
        'mod_bigbluebuttonbn:icon' => 'icon-bigbluebutton',
1102
    ];
1103
}
1104
1105
/**
1106
 * This function receives a calendar event and returns the action associated with it, or null if there is none.
1107
 *
1108
 * This is used by block_myoverview in order to display the event appropriately. If null is returned then the event
1109
 * is not displayed on the block.
1110
 *
1111
 * @param calendar_event $event
1112
 * @param \core_calendar\action_factory $factory
1113
 * @return \core_calendar\local\event\entities\action_interface|null
1114
 */
1115
function mod_bigbluebuttonbn_core_calendar_provide_event_action(calendar_event $event,
1116
        \core_calendar\action_factory $factory) {
1117
    global $CFG, $DB;
1118
1119
    require_once($CFG->dirroot . '/mod/bigbluebuttonbn/locallib.php');
1120
1121
    // Get mod info.
1122
    $cm = get_fast_modinfo($event->courseid)->instances['bigbluebuttonbn'][$event->instance];
1123
1124
    // Get bigbluebuttonbn activity.
1125
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $event->instance), '*', MUST_EXIST);
1126
1127
    // Get if the user has joined in live session or viewed the recorded.
1128
    $usercomplete = bigbluebuttonbn_user_complete($event->courseid, $event->userid, $bigbluebuttonbn);
1129
    // Get if the room is available.
1130
    list($roomavailable) = bigbluebuttonbn_room_is_available($bigbluebuttonbn);
1131
    // Get if the user can join.
1132
    list($usercanjoin) = bigbluebuttonbn_user_can_join_meeting($bigbluebuttonbn);
1133
    // Get if the time has already passed.
1134
    $haspassed = $bigbluebuttonbn->openingtime < time();
1135
1136
    // Check if the room is closed and the user has already joined this session or played the record.
1137
    if ($haspassed && !$roomavailable && $usercomplete) {
1138
        return null;
1139
    }
1140
1141
    // Check if the user can join this session.
1142
    $actionable = ($roomavailable && $usercanjoin) || $haspassed;
1143
1144
    // Action data.
1145
    $string = get_string('view_room', 'bigbluebuttonbn');
1146
    $url = new \moodle_url('/mod/bigbluebuttonbn/view.php', array('id' => $cm->id));
1147
    if (groups_get_activity_groupmode($cm) == NOGROUPS) {
1148
        // No groups mode.
1149
        $string = get_string('view_conference_action_join', 'bigbluebuttonbn');
1150
        $url = new \moodle_url('/mod/bigbluebuttonbn/bbb_view.php', array('action' => 'join',
1151
            'id' => $cm->id, 'bn' => $bigbluebuttonbn->id, 'timeline' => 1));
1152
    }
1153
1154
    return $factory->create_instance($string, $url, 1, $actionable);
1155
}
1156
1157
/**
1158
 * Register a bigbluebuttonbn event
1159
 *
1160
 * @param object $bigbluebuttonbn
1161
 * @param string $event
1162
 * @param array  $overrides
1163
 * @param string $meta
1164
 *
1165
 * @return bool Success/Failure
1166
 */
1167
function bigbluebuttonbn_log($bigbluebuttonbn, $event, array $overrides = [], $meta = null) {
1168
    global $DB, $USER;
1169
    $log = new stdClass();
1170
    // Default values.
1171
    $log->courseid = $bigbluebuttonbn->course;
1172
    $log->bigbluebuttonbnid = $bigbluebuttonbn->id;
1173
    $log->userid = $USER->id;
1174
    $log->meetingid = $bigbluebuttonbn->meetingid;
1175
    $log->timecreated = time();
1176
    $log->log = $event;
1177
    $log->meta = $meta;
1178
    // Overrides.
1179
    foreach ($overrides as $key => $value) {
1180
        $log->$key = $value;
1181
    }
1182
    if (!$DB->insert_record('bigbluebuttonbn_logs', $log)) {
1183
        return false;
1184
    }
1185
    return true;
1186
}
1187
1188
/**
1189
 * Adds module specific settings to the settings block
1190
 *
1191
 * @param settings_navigation $settingsnav The settings navigation object
1192
 * @param navigation_node $nodenav The node to add module settings to
1193
 */
1194
function bigbluebuttonbn_extend_settings_navigation(settings_navigation $settingsnav, navigation_node $nodenav) {
0 ignored issues
show
Unused Code introduced by
The parameter $settingsnav 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...
1195
    global $PAGE, $CFG;
1196
1197
    $params = $PAGE->url->params();
1198
    if (!empty($params['id'])) {
1199
        $cm = get_coursemodule_from_id('bigbluebuttonbn', $params['id'], 0, false, MUST_EXIST);
1200
    }
1201
1202
    if (isloggedin() && !isguestuser()) {
1203
        $completionvalidate = '#action=completion_validate&bigbluebuttonbn=' . $cm->instance;
0 ignored issues
show
Bug introduced by
The variable $cm does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1204
        $nodenav->add(get_string('completionvalidatestate', 'bigbluebuttonbn'),
1205
            $completionvalidate, navigation_node::TYPE_CONTAINER);
1206
    }
1207
}
1208