Completed
Branch master (50b31b)
by Jesus
02:05
created

lib.php ➔ bigbluebuttonbn_process_pre_save_checkboxes()   D

Complexity

Conditions 10
Paths 512

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
nc 512
nop 1
dl 0
loc 29
rs 4.1777
c 0
b 0
f 0

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