Completed
Pull Request — master (#134)
by Jesus
01:56
created

lib.php ➔ bigbluebuttonbn_reset_events()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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