Completed
Push — v2.3-stable ( 4f067b...85dc14 )
by Jesus
01:59
created

lib.php ➔ bigbluebuttonbn_process_post_save_event()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

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