Completed
Push — v2.3-stable ( 5a00b3...7854bc )
by Jesus
03:58 queued 01:50
created

lib.php ➔ bigbluebuttonbn_process_pre_save_checkboxes()   F

Complexity

Conditions 11
Paths 1024

Size

Total Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
nc 1024
nop 1
dl 0
loc 32
rs 3.15
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
// JWT is included in Moodle 3.7 core, but a local package is still needed for backward compatibility.
32
if (!class_exists('\Firebase\JWT\JWT')) {
33
    if (file_exists($CFG->libdir.'/php-jwt/src/JWT.php')) {
34
        require_once($CFG->libdir.'/php-jwt/src/JWT.php');
35
    } else {
36
        require_once($CFG->dirroot.'/mod/bigbluebuttonbn/vendor/firebase/php-jwt/src/JWT.php');
37
    }
38
}
39
40
if (!isset($CFG->bigbluebuttonbn)) {
41
    $CFG->bigbluebuttonbn = array();
42
}
43
44
if (file_exists(dirname(__FILE__).'/config.php')) {
45
    require_once(dirname(__FILE__).'/config.php');
46
}
47
48
/*
49
 * DURATIONCOMPENSATION: Feature removed by configuration
50
 */
51
$CFG->bigbluebuttonbn['scheduled_duration_enabled'] = 0;
52
/*
53
 * Remove this block when restored
54
 */
55
56
/** @var BIGBLUEBUTTONBN_DEFAULT_SERVER_URL string of default bigbluebutton server url */
57
const BIGBLUEBUTTONBN_DEFAULT_SERVER_URL = 'http://test-install.blindsidenetworks.com/bigbluebutton/';
58
/** @var BIGBLUEBUTTONBN_DEFAULT_SHARED_SECRET string of default bigbluebutton server shared secret */
59
const BIGBLUEBUTTONBN_DEFAULT_SHARED_SECRET = '8cd8ef52e8e101574e400365b55e11a6';
60
/** @var BIGBLUEBUTTONBN_LOG_EVENT_ADD string of event add for bigbluebuttonbn_logs */
61
const BIGBLUEBUTTONBN_LOG_EVENT_ADD = 'Add';
62
/** @var BIGBLUEBUTTONBN_LOG_EVENT_EDIT string of event edit for bigbluebuttonbn_logs */
63
const BIGBLUEBUTTONBN_LOG_EVENT_EDIT = 'Edit';
64
/** @var BIGBLUEBUTTONBN_LOG_EVENT_CREATE string of event create for bigbluebuttonbn_logs */
65
const BIGBLUEBUTTONBN_LOG_EVENT_CREATE = 'Create';
66
/** @var BIGBLUEBUTTONBN_LOG_EVENT_JOIN string of event join for bigbluebuttonbn_logs */
67
const BIGBLUEBUTTONBN_LOG_EVENT_JOIN = 'Join';
68
/** @var BIGBLUEBUTTONBN_LOG_EVENT_PLAYED string of event record played for bigbluebuttonbn_logs */
69
const BIGBLUEBUTTONBN_LOG_EVENT_PLAYED = 'Played';
70
/** @var BIGBLUEBUTTONBN_LOG_EVENT_LOGOUT string of event logout for bigbluebuttonbn_logs */
71
const BIGBLUEBUTTONBN_LOG_EVENT_LOGOUT = 'Logout';
72
/** @var BIGBLUEBUTTONBN_LOG_EVENT_IMPORT string of event import for bigbluebuttonbn_logs */
73
const BIGBLUEBUTTONBN_LOG_EVENT_IMPORT = 'Import';
74
/** @var BIGBLUEBUTTONBN_LOG_EVENT_DELETE string of event delete for bigbluebuttonbn_logs */
75
const BIGBLUEBUTTONBN_LOG_EVENT_DELETE = 'Delete';
76
/** @var BIGBLUEBUTTON_LOG_EVENT_CALLBACK string defines the bigbluebuttonbn callback event */
77
const BIGBLUEBUTTON_LOG_EVENT_CALLBACK = 'Callback';
78
/**
79
 * Indicates API features that the bigbluebuttonbn supports.
80
 *
81
 * @uses FEATURE_IDNUMBER
82
 * @uses FEATURE_GROUPS
83
 * @uses FEATURE_GROUPINGS
84
 * @uses FEATURE_GROUPMEMBERSONLY
85
 * @uses FEATURE_MOD_INTRO
86
 * @uses FEATURE_BACKUP_MOODLE2
87
 * @uses FEATURE_COMPLETION_TRACKS_VIEWS
88
 * @uses FEATURE_COMPLETION_HAS_RULES
89
 * @uses FEATURE_GRADE_HAS_GRADE
90
 * @uses FEATURE_GRADE_OUTCOMES
91
 * @uses FEATURE_SHOW_DESCRIPTION
92
 * @param string $feature
93
 * @return mixed True if yes (some features may use other values)
94
 */
95
function bigbluebuttonbn_supports($feature) {
96
    if (!$feature) {
97
        return null;
98
    }
99
    $features = array(
100
        (string) FEATURE_IDNUMBER => true,
101
        (string) FEATURE_GROUPS => true,
102
        (string) FEATURE_GROUPINGS => true,
103
        (string) FEATURE_GROUPMEMBERSONLY => true,
104
        (string) FEATURE_MOD_INTRO => true,
105
        (string) FEATURE_BACKUP_MOODLE2 => true,
106
        (string) FEATURE_COMPLETION_TRACKS_VIEWS => true,
107
        (string) FEATURE_GRADE_HAS_GRADE => false,
108
        (string) FEATURE_GRADE_OUTCOMES => false,
109
        (string) FEATURE_SHOW_DESCRIPTION => true,
110
    );
111
    if (isset($features[(string) $feature])) {
112
        return $features[$feature];
113
    }
114
    return null;
115
}
116
117
/**
118
 * Given an object containing all the necessary data,
119
 * (defined by the form in mod_form.php) this function
120
 * will create a new instance and return the id number
121
 * of the new instance.
122
 *
123
 * @param object $bigbluebuttonbn  An object from the form in mod_form.php
124
 * @return int The id of the newly inserted bigbluebuttonbn record
125
 */
126 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...
127
    global $DB;
128
    // Excecute preprocess.
129
    bigbluebuttonbn_process_pre_save($bigbluebuttonbn);
130
    // Pre-set initial values.
131
    $bigbluebuttonbn->presentation = bigbluebuttonbn_get_media_file($bigbluebuttonbn);
132
    // Insert a record.
133
    $bigbluebuttonbn->id = $DB->insert_record('bigbluebuttonbn', $bigbluebuttonbn);
134
    // Encode meetingid.
135
    $bigbluebuttonbn->meetingid = bigbluebuttonbn_unique_meetingid_seed();
136
    // Set the meetingid column in the bigbluebuttonbn table.
137
    $DB->set_field('bigbluebuttonbn', 'meetingid', $bigbluebuttonbn->meetingid, array('id' => $bigbluebuttonbn->id));
138
    // Log insert action.
139
    bigbluebuttonbn_log($bigbluebuttonbn, BIGBLUEBUTTONBN_LOG_EVENT_ADD);
140
    // Complete the process.
141
    bigbluebuttonbn_process_post_save($bigbluebuttonbn);
142
    return $bigbluebuttonbn->id;
143
}
144
145
/**
146
 * Given an object containing all the necessary data,
147
 * (defined by the form in mod_form.php) this function
148
 * will update an existing instance with new data.
149
 *
150
 * @param object $bigbluebuttonbn  An object from the form in mod_form.php
151
 * @return bool Success/Fail
152
 */
153 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...
154
    global $DB;
155
    // Excecute preprocess.
156
    bigbluebuttonbn_process_pre_save($bigbluebuttonbn);
157
    // Pre-set initial values.
158
    $bigbluebuttonbn->id = $bigbluebuttonbn->instance;
159
    $bigbluebuttonbn->presentation = bigbluebuttonbn_get_media_file($bigbluebuttonbn);
160
    // Update a record.
161
    $DB->update_record('bigbluebuttonbn', $bigbluebuttonbn);
162
    // Get the meetingid column in the bigbluebuttonbn table.
163
    $bigbluebuttonbn->meetingid = (string)$DB->get_field('bigbluebuttonbn', 'meetingid', array('id' => $bigbluebuttonbn->id));
164
    // Log update action.
165
    bigbluebuttonbn_log($bigbluebuttonbn, BIGBLUEBUTTONBN_LOG_EVENT_EDIT);
166
    // Complete the process.
167
    bigbluebuttonbn_process_post_save($bigbluebuttonbn);
168
    return true;
169
}
170
171
/**
172
 * Given an ID of an instance of this module,
173
 * this function will permanently delete the instance
174
 * and any data that depends on it.
175
 *
176
 * @param int $id Id of the module instance
177
 *
178
 * @return bool Success/Failure
179
 */
180
function bigbluebuttonbn_delete_instance($id) {
181
    global $DB;
182
183
    if (!$bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $id))) {
184
        return false;
185
    }
186
187
    // TODO: End the meeting if it is running.
188
189
    $result = true;
190
191
    // Delete any dependent records here.
192
    if (!$DB->delete_records('bigbluebuttonbn', array('id' => $bigbluebuttonbn->id))) {
193
        $result = false;
194
    }
195
196
    if (!$DB->delete_records('event', array('modulename' => 'bigbluebuttonbn', 'instance' => $bigbluebuttonbn->id))) {
197
        $result = false;
198
    }
199
200
    // Log action performed.
201
    bigbluebuttonbn_delete_instance_log($bigbluebuttonbn);
202
203
    return $result;
204
}
205
206
/**
207
 * Given an ID of an instance of this module,
208
 * this function will permanently delete the data that depends on it.
209
 *
210
 * @param object $bigbluebuttonbn Id of the module instance
211
 *
212
 * @return bool Success/Failure
213
 */
214
function bigbluebuttonbn_delete_instance_log($bigbluebuttonbn) {
215
    global $DB;
216
    $sql  = "SELECT * FROM {bigbluebuttonbn_logs} ";
217
    $sql .= "WHERE bigbluebuttonbnid = ? AND log = ? AND ". $DB->sql_compare_text('meta') . " = ?";
218
    $logs = $DB->get_records_sql($sql, array($bigbluebuttonbn->id, BIGBLUEBUTTONBN_LOG_EVENT_CREATE, "{\"record\":true}"));
219
    $meta = "{\"has_recordings\":" . empty($logs) ? "true" : "false" . "}";
220
    bigbluebuttonbn_log($bigbluebuttonbn, BIGBLUEBUTTONBN_LOG_EVENT_DELETE, [], $meta);
221
}
222
223
/**
224
 * Return a small object with summary information about what a
225
 * user has done with a given particular instance of this module
226
 * Used for user activity reports.
227
 *
228
 * @param object $course
229
 * @param object $user
230
 * @param object $mod
231
 * @param object $bigbluebuttonbn
232
 *
233
 * @return bool
234
 */
235
function bigbluebuttonbn_user_outline($course, $user, $mod, $bigbluebuttonbn) {
236
    if ($completed = bigbluebuttonbn_user_complete($course, $user, $mod, $bigbluebuttonbn)) {
237
        return fullname($user).' '.get_string('view_message_has_joined', 'bigbluebuttonbn').' '.
238
            get_string('view_message_session_for', 'bigbluebuttonbn').' '.(string) $completed.' '.
239
            get_string('view_message_times', 'bigbluebuttonbn');
240
    }
241
    return '';
242
}
243
244
/**
245
 * Print a detailed representation of what a user has done with
246
 * a given particular instance of this module, for user activity reports.
247
 *
248
 * @param object|int $courseorid
249
 * @param object|int $userorid
250
 * @param object $mod
251
 * @param object $bigbluebuttonbn
252
 *
253
 * @return bool
254
 */
255
function bigbluebuttonbn_user_complete($courseorid, $userorid, $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...
256
    global $DB;
257
    if (is_object($courseorid)) {
258
        $course = $courseorid;
259
    } else {
260
        $course = (object)array('id' => $courseorid);
261
    }
262
    if (is_object($userorid)) {
263
        $user = $userorid;
264
    } else {
265
        $user = (object)array('id' => $userorid);
266
    }
267
    $sql = "SELECT COUNT(*) FROM {bigbluebuttonbn_logs} ";
268
    $sql .= "WHERE courseid = ? AND bigbluebuttonbnid = ? AND userid = ? AND (log = ? OR log = ?)";
269
    $result = $DB->count_records_sql($sql, array($course->id, $bigbluebuttonbn->id, $user->id,
270
                                              BIGBLUEBUTTONBN_LOG_EVENT_JOIN, BIGBLUEBUTTONBN_LOG_EVENT_PLAYED));
271
    return $result;
272
}
273
274
/**
275
 * Returns all other caps used in module.
276
 *
277
 * @return string[]
278
 */
279
function bigbluebuttonbn_get_extra_capabilities() {
280
    return array('moodle/site:accessallgroups');
281
}
282
283
/**
284
 * Define items to be reset by course/reset.php
285
 *
286
 * @return array
287
 */
288
function bigbluebuttonbn_reset_course_items() {
289
    $items = array("events" => 0, "tags" => 0, "logs" => 0);
290
    // Include recordings only if enabled.
291
    if ((boolean)\mod_bigbluebuttonbn\locallib\config::recordings_enabled()) {
292
        $items["recordings"] = 0;
293
    }
294
    return $items;
295
}
296
297
/**
298
 * Called by course/reset.php
299
 *
300
 * @param object $mform
301
 * @return void
302
 */
303
function bigbluebuttonbn_reset_course_form_definition(&$mform) {
304
    $items = bigbluebuttonbn_reset_course_items();
305
    $mform->addElement('header', 'bigbluebuttonbnheader', get_string('modulenameplural', 'bigbluebuttonbn'));
306
    foreach ($items as $item => $default) {
307
        $mform->addElement('advcheckbox', "reset_bigbluebuttonbn_{$item}"
308
            , get_string("reset{$item}", 'bigbluebuttonbn')
309
        );
310
        if ($item == 'logs' || $item == 'recordings') {
311
            $mform->addHelpButton("reset_bigbluebuttonbn_{$item}", "reset{$item}", 'bigbluebuttonbn');
312
        }
313
    }
314
}
315
316
/**
317
 * Course reset form defaults.
318
 *
319
 * @param object $course
320
 * @return array
321
 */
322
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...
323
    $formdefaults = array();
324
    $items = bigbluebuttonbn_reset_course_items();
325
    // All unchecked by default.
326
    foreach ($items as $item => $default) {
327
        $formdefaults["reset_bigbluebuttonbn_{$item}"] = $default;
328
    }
329
    return $formdefaults;
330
}
331
332
/**
333
 * This function is used by the reset_course_userdata function in moodlelib.
334
 *
335
 * @param array $data the data submitted from the reset course.
336
 * @return array status array
337
 */
338
function bigbluebuttonbn_reset_userdata($data) {
339
    $items = bigbluebuttonbn_reset_course_items();
340
    $status = array();
341
    // Any changes to the list of dates that needs to be rolled should be same during course restore and course reset.
342
    // See MDL-9367.
343
    if (array_key_exists('recordings', $items) && !empty($data->reset_bigbluebuttonbn_recordings)) {
344
        // Remove all the recordings from a BBB server that are linked to the room/activities in this course.
345
        bigbluebuttonbn_reset_recordings($data->courseid);
346
        unset($items['recordings']);
347
        $status[] = bigbluebuttonbn_reset_getstatus('recordings');
348
    }
349
    if (!empty($data->reset_bigbluebuttonbn_tags)) {
350
        // Remove all the tags linked to the room/activities in this course.
351
        bigbluebuttonbn_reset_tags($data->courseid);
352
        unset($items['tags']);
353
        $status[] = bigbluebuttonbn_reset_getstatus('tags');
354
    }
355
    foreach ($items as $item => $default) {
356
        // Remove instances or elements linked to this course, others than recordings or tags.
357
        if (!empty($data->{"reset_bigbluebuttonbn_{$item}"})) {
358
            call_user_func("bigbluebuttonbn_reset_{$item}", $data->courseid);
359
            $status[] = bigbluebuttonbn_reset_getstatus($item);
360
        }
361
    }
362
    return $status;
363
}
364
365
/**
366
 * Returns status used on every defined reset action.
367
 *
368
 * @param string $item
369
 * @return array status array
370
 */
371
function bigbluebuttonbn_reset_getstatus($item) {
372
    return array('component' => get_string('modulenameplural', 'bigbluebuttonbn')
373
        , 'item' => get_string("removed{$item}", 'bigbluebuttonbn')
374
        , 'error' => false);
375
}
376
377
/**
378
 * Used by the reset_course_userdata for deleting events linked to bigbluebuttonbn instances in the course.
379
 *
380
 * @param string $courseid
381
 * @return array status array
382
 */
383
function bigbluebuttonbn_reset_events($courseid) {
384
    global $DB;
385
    // Remove all the events.
386
    return $DB->delete_records('event', array('modulename' => 'bigbluebuttonbn', 'courseid' => $courseid));
387
}
388
389
/**
390
 * Used by the reset_course_userdata for deleting tags linked to bigbluebuttonbn instances in the course.
391
 *
392
 * @param array $courseid
393
 * @return array status array
394
 */
395
function bigbluebuttonbn_reset_tags($courseid) {
396
    global $DB;
397
    // Remove all the tags linked to the room/activities in this course.
398
    if ($bigbluebuttonbns = $DB->get_records('bigbluebuttonbn', array('course' => $courseid))) {
399
        foreach ($bigbluebuttonbns as $bigbluebuttonbn) {
400
            if (!$cm = get_coursemodule_from_instance('bigbluebuttonbn', $bigbluebuttonbn->id, $courseid)) {
401
                continue;
402
            }
403
            $context = context_module::instance($cm->id);
404
            core_tag_tag::delete_instances('mod_bigbluebuttonbn', null, $context->id);
405
        }
406
    }
407
}
408
409
/**
410
 * Used by the reset_course_userdata for deleting bigbluebuttonbn_logs linked to bigbluebuttonbn instances in the course.
411
 *
412
 * @param string $courseid
413
 * @return array status array
414
 */
415
function bigbluebuttonbn_reset_logs($courseid) {
416
    global $DB;
417
    // Remove all the logs.
418
    return $DB->delete_records('bigbluebuttonbn_logs', array('courseid' => $courseid));
419
}
420
421
/**
422
 * Used by the reset_course_userdata for deleting recordings in a BBB server linked to bigbluebuttonbn instances in the course.
423
 *
424
 * @param string $courseid
425
 * @return array status array
426
 */
427
function bigbluebuttonbn_reset_recordings($courseid) {
428
    require_once(__DIR__.'/locallib.php');
429
    // Criteria for search [courseid | bigbluebuttonbn=null | subset=false | includedeleted=true].
430
    $recordings = bigbluebuttonbn_get_recordings($courseid, null, false, true);
431
    // Remove all the recordings.
432
    bigbluebuttonbn_delete_recordings(implode(",", array_keys($recordings)));
433
}
434
435
/**
436
 * List of view style log actions.
437
 *
438
 * @return string[]
439
 */
440
function bigbluebuttonbn_get_view_actions() {
441
    return array('view', 'view all');
442
}
443
444
/**
445
 * List of update style log actions.
446
 *
447
 * @return string[]
448
 */
449
function bigbluebuttonbn_get_post_actions() {
450
    return array('update', 'add', 'delete');
451
}
452
453
/**
454
 * Print an overview of all bigbluebuttonbn instances for the courses.
455
 *
456
 * @param array $courses
457
 * @param array $htmlarray Passed by reference
458
 *
459
 * @return void
460
 */
461
function bigbluebuttonbn_print_overview($courses, &$htmlarray) {
462
    if (empty($courses) || !is_array($courses)) {
463
        return array();
464
    }
465
    $bns = get_all_instances_in_courses('bigbluebuttonbn', $courses);
466
    foreach ($bns as $bn) {
467
        $now = time();
468
        if ($bn->openingtime and (!$bn->closingtime or $bn->closingtime > $now)) {
469
            // A bigbluebuttonbn is scheduled.
470
            if (empty($htmlarray[$bn->course]['bigbluebuttonbn'])) {
471
                $htmlarray[$bn->course]['bigbluebuttonbn'] = '';
472
            }
473
            $htmlarray[$bn->course]['bigbluebuttonbn'] .= bigbluebuttonbn_print_overview_element($bn, $now);
474
        }
475
    }
476
}
477
478
/**
479
 * Print an overview of a bigbluebuttonbn instance.
480
 *
481
 * @param array $bigbluebuttonbn
482
 * @param int $now
483
 *
484
 * @return string
485
 */
486
function bigbluebuttonbn_print_overview_element($bigbluebuttonbn, $now) {
487
    global $CFG;
488
    $start = 'started_at';
489
    if ($bigbluebuttonbn->openingtime > $now) {
490
        $start = 'starts_at';
491
    }
492
    $classes = '';
493
    if ($bigbluebuttonbn->visible) {
494
        $classes = 'class="dimmed" ';
495
    }
496
    $str  = '<div class="bigbluebuttonbn overview">'."\n";
497
    $str .= '  <div class="name">'.get_string('modulename', 'bigbluebuttonbn').':&nbsp;'."\n";
498
    $str .= '    <a '.$classes.'href="'.$CFG->wwwroot.'/mod/bigbluebuttonbn/view.php?id='.$bigbluebuttonbn->coursemodule.
499
      '">'.$bigbluebuttonbn->name.'</a>'."\n";
500
    $str .= '  </div>'."\n";
501
    $str .= '  <div class="info">'.get_string($start, 'bigbluebuttonbn').': '.userdate($bigbluebuttonbn->openingtime).
502
        '</div>'."\n";
503
    $str .= '  <div class="info">'.get_string('ends_at', 'bigbluebuttonbn').': '.userdate($bigbluebuttonbn->closingtime)
504
      .'</div>'."\n";
505
    $str .= '</div>'."\n";
506
    return $str;
507
}
508
509
/**
510
 * Given a course_module object, this function returns any
511
 * "extra" information that may be needed when printing
512
 * this activity in a course listing.
513
 * See get_array_of_activities() in course/lib.php.
514
 *
515
 * @param object $coursemodule
516
 *
517
 * @return null|cached_cm_info
518
 */
519
function bigbluebuttonbn_get_coursemodule_info($coursemodule) {
520
    global $DB;
521
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $coursemodule->instance),
522
        'id, name, intro, introformat');
523
    if (!$bigbluebuttonbn) {
524
        return null;
525
    }
526
    $info = new cached_cm_info();
527
    $info->name = $bigbluebuttonbn->name;
528
    if ($coursemodule->showdescription) {
529
        // Convert intro to html. Do not filter cached version, filters run at display time.
530
        $info->content = format_module_intro('bigbluebuttonbn', $bigbluebuttonbn, $coursemodule->id, false);
531
    }
532
    return $info;
533
}
534
535
/**
536
 * Runs any processes that must run before a bigbluebuttonbn insert/update.
537
 *
538
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
539
 *
540
 * @return void
541
 **/
542
function bigbluebuttonbn_process_pre_save(&$bigbluebuttonbn) {
543
    bigbluebuttonbn_process_pre_save_instance($bigbluebuttonbn);
544
    bigbluebuttonbn_process_pre_save_checkboxes($bigbluebuttonbn);
545
    bigbluebuttonbn_process_pre_save_common($bigbluebuttonbn);
546
    $bigbluebuttonbn->participants = htmlspecialchars_decode($bigbluebuttonbn->participants);
547
}
548
549
/**
550
 * Runs process for defining the instance (insert/update).
551
 *
552
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
553
 *
554
 * @return void
555
 **/
556
function bigbluebuttonbn_process_pre_save_instance(&$bigbluebuttonbn) {
557
    require_once(__DIR__.'/locallib.php');
558
    $bigbluebuttonbn->timemodified = time();
559
    if ((integer)$bigbluebuttonbn->instance == 0) {
560
        $bigbluebuttonbn->meetingid = 0;
561
        $bigbluebuttonbn->timecreated = time();
562
        $bigbluebuttonbn->timemodified = 0;
563
        // As it is a new activity, assign passwords.
564
        $bigbluebuttonbn->moderatorpass = bigbluebuttonbn_random_password(12);
565
        $bigbluebuttonbn->viewerpass = bigbluebuttonbn_random_password(12, $bigbluebuttonbn->moderatorpass);
566
    }
567
}
568
569
/**
570
 * Runs process for assigning default value to checkboxes.
571
 *
572
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
573
 *
574
 * @return void
575
 **/
576
function bigbluebuttonbn_process_pre_save_checkboxes(&$bigbluebuttonbn) {
577
    if (!isset($bigbluebuttonbn->wait)) {
578
        $bigbluebuttonbn->wait = 0;
579
    }
580
    if (!isset($bigbluebuttonbn->record)) {
581
        $bigbluebuttonbn->record = 0;
582
    }
583
    if (!isset($bigbluebuttonbn->recordallfromstart)) {
584
        $bigbluebuttonbn->recordallfromstart = 0;
585
    }
586
    if (!isset($bigbluebuttonbn->recordhidebutton)) {
587
        $bigbluebuttonbn->recordhidebutton = 0;
588
    }
589
    if (!isset($bigbluebuttonbn->recordings_html)) {
590
        $bigbluebuttonbn->recordings_html = 0;
591
    }
592
    if (!isset($bigbluebuttonbn->recordings_deleted)) {
593
        $bigbluebuttonbn->recordings_deleted = 0;
594
    }
595
    if (!isset($bigbluebuttonbn->recordings_imported)) {
596
        $bigbluebuttonbn->recordings_imported = 0;
597
    }
598
    if (!isset($bigbluebuttonbn->recordings_preview)) {
599
        $bigbluebuttonbn->recordings_preview = 0;
600
    }
601
    if (!isset($bigbluebuttonbn->muteonstart)) {
602
        $bigbluebuttonbn->muteonstart = 0;
603
    }
604
    if (!isset($bigbluebuttonbn->recordings_validate_url)) {
605
        $bigbluebuttonbn->recordings_validate_url = 1;
606
    }
607
}
608
609
/**
610
 * Runs process for wipping common settings when 'recordings only'.
611
 *
612
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
613
 *
614
 * @return void
615
 **/
616
function bigbluebuttonbn_process_pre_save_common(&$bigbluebuttonbn) {
617
    // Make sure common settings are removed when 'recordings only'.
618
    if ($bigbluebuttonbn->type == BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY) {
619
        $bigbluebuttonbn->groupmode = 0;
620
        $bigbluebuttonbn->groupingid = 0;
621
    }
622
}
623
624
/**
625
 * Runs any processes that must be run after a bigbluebuttonbn insert/update.
626
 *
627
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
628
 *
629
 * @return void
630
 **/
631
function bigbluebuttonbn_process_post_save(&$bigbluebuttonbn) {
632
    if (isset($bigbluebuttonbn->notification) && $bigbluebuttonbn->notification) {
633
        bigbluebuttonbn_process_post_save_notification($bigbluebuttonbn);
634
    }
635
    bigbluebuttonbn_process_post_save_event($bigbluebuttonbn);
636
    bigbluebuttonbn_process_post_save_completion($bigbluebuttonbn);
637
}
638
639
/**
640
 * Generates a message on insert/update which is sent to all users enrolled.
641
 *
642
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
643
 *
644
 * @return void
645
 **/
646
function bigbluebuttonbn_process_post_save_notification(&$bigbluebuttonbn) {
647
    $action = get_string('mod_form_field_notification_msg_modified', 'bigbluebuttonbn');
648
    if (isset($bigbluebuttonbn->add) && !empty($bigbluebuttonbn->add)) {
649
        $action = get_string('mod_form_field_notification_msg_created', 'bigbluebuttonbn');
650
    }
651
    \mod_bigbluebuttonbn\locallib\notifier::notification_process($bigbluebuttonbn, $action);
652
}
653
654
/**
655
 * Generates an event after a bigbluebuttonbn insert/update.
656
 *
657
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
658
 *
659
 * @return void
660
 **/
661
function bigbluebuttonbn_process_post_save_event(&$bigbluebuttonbn) {
662
    global $CFG, $DB;
663
    require_once($CFG->dirroot.'/calendar/lib.php');
664
    $eventid = $DB->get_field('event', 'id', array('modulename' => 'bigbluebuttonbn',
665
        'instance' => $bigbluebuttonbn->id));
666
    // Delete the event from calendar when/if openingtime is NOT set.
667
    if (!isset($bigbluebuttonbn->openingtime) || !$bigbluebuttonbn->openingtime) {
668
        if ($eventid) {
669
            $calendarevent = calendar_event::load($eventid);
670
            $calendarevent->delete();
671
        }
672
        return;
673
    }
674
    // Add evento to the calendar as openingtime is set.
675
    $event = new stdClass();
676
    $event->eventtype = BIGBLUEBUTTON_EVENT_MEETING_START;
677
    $event->type = CALENDAR_EVENT_TYPE_ACTION;
678
    $event->name = get_string('calendarstarts', 'bigbluebuttonbn', $bigbluebuttonbn->name);
679
    $event->description = format_module_intro('bigbluebuttonbn', $bigbluebuttonbn, $bigbluebuttonbn->coursemodule);
680
    $event->courseid = $bigbluebuttonbn->course;
681
    $event->groupid = 0;
682
    $event->userid = 0;
683
    $event->modulename = 'bigbluebuttonbn';
684
    $event->instance = $bigbluebuttonbn->id;
685
    $event->timestart = $bigbluebuttonbn->openingtime;
686
    $event->timeduration = 0;
687
    $event->timesort = $event->timestart;
688
    $event->visible = instance_is_visible('bigbluebuttonbn', $bigbluebuttonbn);
689
    $event->priority = null;
690
    // Update the event in calendar when/if eventid was found.
691
    if ($eventid) {
692
        $event->id = $eventid;
693
        $calendarevent = calendar_event::load($eventid);
694
        $calendarevent->update($event);
695
        return;
696
    }
697
    calendar_event::create($event);
698
}
699
700
/**
701
 * Generates an event after a bigbluebuttonbn activity is completed.
702
 *
703
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
704
 *
705
 * @return void
706
 **/
707
function bigbluebuttonbn_process_post_save_completion($bigbluebuttonbn) {
708
    if (!empty($bigbluebuttonbn->completionexpected)) {
709
        \core_completion\api::update_completion_date_event(
710
            $bigbluebuttonbn->coursemodule,
711
            'bigbluebuttonbn',
712
            $bigbluebuttonbn->id, $bigbluebuttonbn->completionexpected
713
          );
714
    }
715
}
716
717
/**
718
 * Get a full path to the file attached as a preuploaded presentation
719
 * or if there is none, set the presentation field will be set to blank.
720
 *
721
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
722
 *
723
 * @return string
724
 */
725
function bigbluebuttonbn_get_media_file(&$bigbluebuttonbn) {
726
    if (!isset($bigbluebuttonbn->presentation) || $bigbluebuttonbn->presentation == '') {
727
        return '';
728
    }
729
    $context = context_module::instance($bigbluebuttonbn->coursemodule);
730
    // Set the filestorage object.
731
    $fs = get_file_storage();
732
    // Save the file if it exists that is currently in the draft area.
733
    file_save_draft_area_files($bigbluebuttonbn->presentation, $context->id, 'mod_bigbluebuttonbn', 'presentation', 0);
734
    // Get the file if it exists.
735
    $files = $fs->get_area_files($context->id, 'mod_bigbluebuttonbn', 'presentation', 0,
736
        'itemid, filepath, filename', false);
737
    // Check that there is a file to process.
738
    $filesrc = '';
739
    if (count($files) == 1) {
740
        // Get the first (and only) file.
741
        $file = reset($files);
742
        $filesrc = '/'.$file->get_filename();
743
    }
744
    return $filesrc;
745
}
746
747
/**
748
 * Serves the bigbluebuttonbn attachments. Implements needed access control ;-).
749
 *
750
 * @category files
751
 *
752
 * @param stdClass $course        course object
753
 * @param stdClass $cm            course module object
754
 * @param stdClass $context       context object
755
 * @param string   $filearea      file area
756
 * @param array    $args          extra arguments
757
 * @param bool     $forcedownload whether or not force download
758
 * @param array    $options       additional options affecting the file serving
759
 *
760
 * @return false|null false if file not found, does not return if found - justsend the file
761
 */
762
function bigbluebuttonbn_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) {
763
    if (!bigbluebuttonbn_pluginfile_valid($context, $filearea)) {
764
        return false;
765
    }
766
    $file = bigbluebuttonbn_pluginfile_file($course, $cm, $context, $filearea, $args);
767
    if (empty($file)) {
768
        return false;
769
    }
770
    // Finally send the file.
771
    send_stored_file($file, 0, 0, $forcedownload, $options); // download MUST be forced - security!
772
}
773
774
/**
775
 * Helper for validating pluginfile.
776
 * @param stdClass $context       context object
777
 * @param string   $filearea      file area
778
 *
779
 * @return false|null false if file not valid
780
 */
781
function bigbluebuttonbn_pluginfile_valid($context, $filearea) {
782
783
    // Can be in context module or in context_system (if is the presentation by default).
784
    if (!in_array($context->contextlevel, array(CONTEXT_MODULE, CONTEXT_SYSTEM))) {
785
        return false;
786
    }
787
788
    if (!array_key_exists($filearea, bigbluebuttonbn_get_file_areas())) {
789
        return false;
790
    }
791
792
    return true;
793
}
794
795
/**
796
 * Helper for getting pluginfile.
797
 *
798
 * @param stdClass $course        course object
799
 * @param stdClass $cm            course module object
800
 * @param stdClass $context       context object
801
 * @param string   $filearea      file area
802
 * @param array    $args          extra arguments
803
 *
804
 * @return object
805
 */
806
function bigbluebuttonbn_pluginfile_file($course, $cm, $context, $filearea, $args) {
807
    $filename = bigbluebuttonbn_pluginfile_filename($course, $cm, $context, $args);
808
    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...
809
        return false;
810
    }
811
    $fullpath = "/$context->id/mod_bigbluebuttonbn/$filearea/0/".$filename;
812
    $fs = get_file_storage();
813
    $file = $fs->get_file_by_hash(sha1($fullpath));
814
    if (!$file || $file->is_directory()) {
815
        return false;
816
    }
817
    return $file;
818
}
819
820
/**
821
 * Helper for give access to the file configured in setting as default presentation.
822
 *
823
 * @param stdClass $course        course object
824
 * @param stdClass $cm            course module object
825
 * @param stdClass $context       context object
826
 * @param array    $args          extra arguments
827
 *
828
 * @return array
829
 */
830
function bigbluebuttonbn_default_presentation_get_file($course, $cm, $context, $args) {
831
832
    // The difference with the standard bigbluebuttonbn_pluginfile_filename() are.
833
    // - Context is system, so we don't need to check the cmid in this case.
834
    // - The area is "presentationdefault_cache".
835
    if (count($args) > 1) {
836
        $cache = cache::make_from_params(cache_store::MODE_APPLICATION,
837
            'mod_bigbluebuttonbn',
838
            'presentationdefault_cache');
839
840
        $noncekey = sha1($context->id);
841
        $presentationnonce = $cache->get($noncekey);
842
        $noncevalue = $presentationnonce['value'];
843
        $noncecounter = $presentationnonce['counter'];
844
        if ($args['0'] != $noncevalue) {
845
            return;
846
        }
847
848
        // The nonce value is actually used twice because BigBlueButton reads the file two times.
849
        $noncecounter += 1;
850
        $cache->set($noncekey, array('value' => $noncevalue, 'counter' => $noncecounter));
851
        if ($noncecounter == 2) {
852
            $cache->delete($noncekey);
853
        }
854
        return($args['1']);
855
    }
856
    require_course_login($course, true, $cm);
857
    if (!has_capability('mod/bigbluebuttonbn:join', $context)) {
858
        return;
859
    }
860
    return implode('/', $args);
861
}
862
863
/**
864
 * Helper for getting pluginfile name.
865
 *
866
 * @param stdClass $course        course object
867
 * @param stdClass $cm            course module object
868
 * @param stdClass $context       context object
869
 * @param array    $args          extra arguments
870
 *
871
 * @return array
872
 */
873
function bigbluebuttonbn_pluginfile_filename($course, $cm, $context, $args) {
874
    global $DB;
875
876
    if ($context->contextlevel == CONTEXT_SYSTEM) {
877
        // Plugin has a file to use as default in general setting.
878
        return(bigbluebuttonbn_default_presentation_get_file($course, $cm, $context, $args));
879
    }
880
881
    if (count($args) > 1) {
882
        if (!$bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $cm->instance))) {
883
            return;
884
        }
885
        $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', 'presentation_cache');
886
        $noncekey = sha1($bigbluebuttonbn->id);
887
        $presentationnonce = $cache->get($noncekey);
888
        $noncevalue = $presentationnonce['value'];
889
        $noncecounter = $presentationnonce['counter'];
890
        if ($args['0'] != $noncevalue) {
891
            return;
892
        }
893
        // The nonce value is actually used twice because BigBlueButton reads the file two times.
894
        $noncecounter += 1;
895
        $cache->set($noncekey, array('value' => $noncevalue, 'counter' => $noncecounter));
896
        if ($noncecounter == 2) {
897
            $cache->delete($noncekey);
898
        }
899
        return $args['1'];
900
    }
901
    require_course_login($course, true, $cm);
902
    if (!has_capability('mod/bigbluebuttonbn:join', $context)) {
903
        return;
904
    }
905
    return implode('/', $args);
906
}
907
908
/**
909
 * Returns an array of file areas.
910
 *
911
 * @category files
912
 *
913
 * @return array a list of available file areas
914
 */
915
function bigbluebuttonbn_get_file_areas() {
916
    $areas = array();
917
    $areas['presentation'] = get_string('mod_form_block_presentation', 'bigbluebuttonbn');
918
    $areas['presentationdefault'] = get_string('mod_form_block_presentation_default', 'bigbluebuttonbn');
919
    return $areas;
920
}
921
922
/**
923
 * Mark the activity completed (if required) and trigger the course_module_viewed event.
924
 *
925
 * @param  stdClass $bigbluebuttonbn        bigbluebuttonbn object
926
 * @param  stdClass $course     course object
927
 * @param  stdClass $cm         course module object
928
 * @param  stdClass $context    context object
929
 * @since Moodle 3.0
930
 */
931
function bigbluebuttonbn_view($bigbluebuttonbn, $course, $cm, $context) {
932
933
    // Trigger course_module_viewed event.
934
    $params = array(
935
        'context' => $context,
936
        'objectid' => $bigbluebuttonbn->id
937
    );
938
939
    $event = \mod_bigbluebuttonbn\event\activity_viewed::create($params);
940
    $event->add_record_snapshot('course_modules', $cm);
941
    $event->add_record_snapshot('course', $course);
942
    $event->add_record_snapshot('bigbluebuttonbn', $bigbluebuttonbn);
943
    $event->trigger();
944
945
    // Completion.
946
    $completion = new completion_info($course);
947
    $completion->set_module_viewed($cm);
948
}
949
950
/**
951
 * Check if the module has any update that affects the current user since a given time.
952
 *
953
 * @param  cm_info $cm course module data
954
 * @param  int $from the time to check updates from
955
 * @param  array $filter  if we need to check only specific updates
956
 * @return stdClass an object with the different type of areas indicating if they were updated or not
957
 * @since Moodle 3.2
958
 */
959
function bigbluebuttonbn_check_updates_since(cm_info $cm, $from, $filter = array()) {
960
    $updates = course_check_module_updates_since($cm, $from, array('content'), $filter);
961
    return $updates;
962
}
963
964
965
/**
966
 * Get icon mapping for font-awesome.
967
 */
968
function mod_bigbluebuttonbn_get_fontawesome_icon_map() {
969
    return [
970
        'mod_bigbluebuttonbn:icon' => 'icon-bigbluebutton',
971
    ];
972
}
973
974
/**
975
 * This function receives a calendar event and returns the action associated with it, or null if there is none.
976
 *
977
 * This is used by block_myoverview in order to display the event appropriately. If null is returned then the event
978
 * is not displayed on the block.
979
 *
980
 * @param calendar_event $event
981
 * @param \core_calendar\action_factory $factory
982
 * @return \core_calendar\local\event\entities\action_interface|null
983
 */
984
function mod_bigbluebuttonbn_core_calendar_provide_event_action(calendar_event $event,
985
        \core_calendar\action_factory $factory) {
986
    global $CFG, $DB;
987
988
    require_once($CFG->dirroot . '/mod/bigbluebuttonbn/locallib.php');
989
990
    // Get mod info.
991
    $cm = get_fast_modinfo($event->courseid)->instances['bigbluebuttonbn'][$event->instance];
992
993
    // Get bigbluebuttonbn activity.
994
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $event->instance), '*', MUST_EXIST);
995
996
    // Get if the user has joined in live session or viewed the recorded.
997
    $usercomplete = bigbluebuttonbn_user_complete($event->courseid, $event->userid, null, $bigbluebuttonbn);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a object.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
998
    // Get if the room is available.
999
    list($roomavailable) = bigbluebuttonbn_room_is_available($bigbluebuttonbn);
1000
    // Get if the user can join.
1001
    list($usercanjoin) = bigbluebuttonbn_user_can_join_meeting($bigbluebuttonbn);
1002
    // Get if the time has already passed.
1003
    $haspassed = $bigbluebuttonbn->openingtime < time();
1004
1005
    // Check if the room is closed and the user has already joined this session or played the record.
1006
    if ($haspassed && !$roomavailable && $usercomplete) {
1007
        return null;
1008
    }
1009
1010
    // Check if the user can join this session.
1011
    $actionable = ($roomavailable && $usercanjoin) || $haspassed;
1012
1013
    // Action data.
1014
    $string = get_string('view_room', 'bigbluebuttonbn');
1015
    $url = new \moodle_url('/mod/bigbluebuttonbn/view.php', array('id' => $cm->id));
1016
    if (groups_get_activity_groupmode($cm) == NOGROUPS) {
1017
        // No groups mode.
1018
        $string = get_string('view_conference_action_join', 'bigbluebuttonbn');
1019
        $url = new \moodle_url('/mod/bigbluebuttonbn/bbb_view.php', array('action' => 'join',
1020
            'id' => $cm->id, 'bn' => $bigbluebuttonbn->id, 'timeline' => 1));
1021
    }
1022
1023
    return $factory->create_instance($string, $url, 1, $actionable);
1024
}
1025
1026
/**
1027
 * Register a bigbluebuttonbn event
1028
 *
1029
 * @param object $bigbluebuttonbn
1030
 * @param string $event
1031
 * @param array  $overrides
1032
 * @param string $meta
1033
 *
1034
 * @return bool Success/Failure
1035
 */
1036
function bigbluebuttonbn_log($bigbluebuttonbn, $event, array $overrides = [], $meta = null) {
1037
    global $DB, $USER;
1038
    $log = new stdClass();
1039
    // Default values.
1040
    $log->courseid = $bigbluebuttonbn->course;
1041
    $log->bigbluebuttonbnid = $bigbluebuttonbn->id;
1042
    $log->userid = $USER->id;
1043
    $log->meetingid = $bigbluebuttonbn->meetingid;
1044
    $log->timecreated = time();
1045
    $log->log = $event;
1046
    $log->meta = $meta;
1047
    // Overrides.
1048
    foreach ($overrides as $key => $value) {
1049
        $log->$key = $value;
1050
    }
1051
    if (!$DB->insert_record('bigbluebuttonbn_logs', $log)) {
1052
        return false;
1053
    }
1054
    return true;
1055
}
1056