Completed
Pull Request — master (#134)
by Jesus
02:04
created

lib.php ➔ bigbluebuttonbn_reset_course_items()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 8
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
    $strremove = get_string('remove', 'bigbluebuttonbn');
303
    foreach ($items as $item => $default) {
304
        $mform->addElement('advcheckbox', "reset_bigbluebuttonbn_{$item}"
305
            , $strremove . ' ' . get_string($item, 'bigbluebuttonbn')
306
        );
307
        $helpstring = get_string('reset' . $item . '_help', 'bigbluebuttonbn');
308
        if ($helpstring != "[[reset{$item}_help]]") {
309
            $mform->addHelpButton("reset_bigbluebuttonbn_{$item}", "reset{$item}", 'bigbluebuttonbn');
310
        }
311
    }
312
}
313
314
/**
315
 * Course reset form defaults.
316
 *
317
 * @param object $course
318
 * @return array
319
 */
320
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...
321
    $formdefaults = array();
322
    $items = bigbluebuttonbn_reset_course_items();
323
    // All unchecked by default.
324
    foreach ($items as $item => $default) {
325
        $formdefaults["reset_bigbluebuttonbn_{$item}"] = $default;
326
    }
327
    return $formdefaults;
328
}
329
330
/**
331
 * This function is used by the reset_course_userdata function in moodlelib.
332
 *
333
 * @param array $data the data submitted from the reset course.
334
 * @return array status array
335
 */
336
function bigbluebuttonbn_reset_userdata($data) {
337
    $items = bigbluebuttonbn_reset_course_items();
338
    $status = array();
339
    // Any changes to the list of dates that needs to be rolled should be same during course restore and course reset.
340
    // See MDL-9367.
341
    if (array_key_exists('recordings', $items) && !empty($data->reset_bigbluebuttonbn_recordings)) {
342
        // Remove all the recordings from a BBB server that are linked to the room/activities in this course.
343
        bigbluebuttonbn_reset_recordings($data->courseid);
344
        unset($items['recordings']);
345
        $status[] = bigbluebuttonbn_reset_getstatus('recordings');
346
    }
347
    if (!empty($data->reset_bigbluebuttonbn_tags)) {
348
        // Remove all the tags linked to the room/activities in this course.
349
        bigbluebuttonbn_reset_tags($data->courseid);
350
        unset($items['tags']);
351
        $status[] = bigbluebuttonbn_reset_getstatus('tags');
352
    }
353
    foreach ($items as $item => $default) {
354
        // Remove instances or elements linked to this course, others than recordings or tags.
355
        if (!empty($data->{"reset_bigbluebuttonbn_{$item}"})) {
356
            call_user_func("bigbluebuttonbn_reset_{$item}", $data->courseid);
357
            $status[] = bigbluebuttonbn_reset_getstatus($item);
358
        }
359
    }
360
    return $status;
361
}
362
363
/**
364
 * Returns status used on every defined reset action.
365
 *
366
 * @param string $item
367
 * @return array status array
368
 */
369
function bigbluebuttonbn_reset_getstatus($item) {
370
    return array('component' => get_string('modulenameplural', 'bigbluebuttonbn')
371
        , 'item' => get_string('removed', 'bigbluebuttonbn') . ' ' . get_string($item, 'bigbluebuttonbn')
372
        , 'error' => false);
373
}
374
375
/**
376
 * Used by the reset_course_userdata for deleting events linked to bigbluebuttonbn instances in the course.
377
 *
378
 * @param string $courseid
379
 * @return array status array
380
 */
381
function bigbluebuttonbn_reset_events($courseid) {
382
    global $DB;
383
    // Remove all the events.
384
    return $DB->delete_records('event', array('modulename' => 'bigbluebuttonbn', 'courseid' => $courseid));
385
}
386
387
/**
388
 * Used by the reset_course_userdata for deleting tags linked to bigbluebuttonbn instances in the course.
389
 *
390
 * @param array $courseid
391
 * @return array status array
392
 */
393
function bigbluebuttonbn_reset_tags($courseid) {
394
    global $DB;
395
    // Remove all the tags linked to the room/activities in this course.
396
    if ($bigbluebuttonbns = $DB->get_records('bigbluebuttonbn', array('course' => $courseid))) {
397
        foreach ($bigbluebuttonbns as $bigbluebuttonbn) {
398
            if (!$cm = get_coursemodule_from_instance('bigbluebuttonbn', $bigbluebuttonbn->id, $courseid)) {
399
                continue;
400
            }
401
            $context = context_module::instance($cm->id);
402
            core_tag_tag::delete_instances('mod_bigbluebuttonbn', null, $context->id);
403
        }
404
    }
405
}
406
407
/**
408
 * Used by the reset_course_userdata for deleting bigbluebuttonbn_logs linked to bigbluebuttonbn instances in the course.
409
 *
410
 * @param string $courseid
411
 * @return array status array
412
 */
413
function bigbluebuttonbn_reset_logs($courseid) {
414
    global $DB;
415
    // Remove all the logs.
416
    return $DB->delete_records('bigbluebuttonbn_logs', array('courseid' => $courseid));
417
}
418
419
/**
420
 * Used by the reset_course_userdata for deleting recordings in a BBB server linked to bigbluebuttonbn instances in the course.
421
 *
422
 * @param string $courseid
423
 * @return array status array
424
 */
425
function bigbluebuttonbn_reset_recordings($courseid) {
426
    require_once(__DIR__.'/locallib.php');
427
    // Criteria for search [courseid | bigbluebuttonbn=null | subset=false | includedeleted=true].
428
    $recordings = bigbluebuttonbn_get_recordings($courseid, null, false, true);
429
    // Remove all the recordings.
430
    bigbluebuttonbn_delete_recordings(implode(",", array_keys($recordings)));
431
}
432
433
/**
434
 * List of view style log actions.
435
 *
436
 * @return string[]
437
 */
438
function bigbluebuttonbn_get_view_actions() {
439
    return array('view', 'view all');
440
}
441
442
/**
443
 * List of update style log actions.
444
 *
445
 * @return string[]
446
 */
447
function bigbluebuttonbn_get_post_actions() {
448
    return array('update', 'add', 'delete');
449
}
450
451
/**
452
 * Print an overview of all bigbluebuttonbn instances for the courses.
453
 *
454
 * @param array $courses
455
 * @param array $htmlarray Passed by reference
456
 *
457
 * @return void
458
 */
459
function bigbluebuttonbn_print_overview($courses, &$htmlarray) {
460
    if (empty($courses) || !is_array($courses)) {
461
        return array();
462
    }
463
    $bns = get_all_instances_in_courses('bigbluebuttonbn', $courses);
464
    foreach ($bns as $bn) {
465
        $now = time();
466
        if ($bn->openingtime and (!$bn->closingtime or $bn->closingtime > $now)) {
467
            // A bigbluebuttonbn is scheduled.
468
            if (empty($htmlarray[$bn->course]['bigbluebuttonbn'])) {
469
                $htmlarray[$bn->course]['bigbluebuttonbn'] = '';
470
            }
471
            $htmlarray[$bn->course]['bigbluebuttonbn'] = bigbluebuttonbn_print_overview_element($bn, $now);
472
        }
473
    }
474
}
475
476
/**
477
 * Print an overview of a bigbluebuttonbn instance.
478
 *
479
 * @param array $bigbluebuttonbn
480
 * @param int $now
481
 *
482
 * @return string
483
 */
484
function bigbluebuttonbn_print_overview_element($bigbluebuttonbn, $now) {
485
    global $CFG;
486
    $start = 'started_at';
487
    if ($bigbluebuttonbn->openingtime > $now) {
488
        $start = 'starts_at';
489
    }
490
    $classes = '';
491
    if ($bigbluebuttonbn->visible) {
492
        $classes = 'class="dimmed" ';
493
    }
494
    $str  = '<div class="bigbluebuttonbn overview">'."\n";
495
    $str .= '  <div class="name">'.get_string('modulename', 'bigbluebuttonbn').':&nbsp;'."\n";
496
    $str .= '    <a '.$classes.'href="'.$CFG->wwwroot.'/mod/bigbluebuttonbn/view.php?id='.$bigbluebuttonbn->coursemodule.
497
      '">'.$bigbluebuttonbn->name.'</a>'."\n";
498
    $str .= '  </div>'."\n";
499
    $str .= '  <div class="info">'.get_string($start, 'bigbluebuttonbn').': '.userdate($bigbluebuttonbn->openingtime).
500
        '</div>'."\n";
501
    $str .= '  <div class="info">'.get_string('ends_at', 'bigbluebuttonbn').': '.userdate($bigbluebuttonbn->closingtime)
502
      .'</div>'."\n";
503
    $str .= '</div>'."\n";
504
    return $str;
505
}
506
507
/**
508
 * Given a course_module object, this function returns any
509
 * "extra" information that may be needed when printing
510
 * this activity in a course listing.
511
 * See get_array_of_activities() in course/lib.php.
512
 *
513
 * @param object $coursemodule
514
 *
515
 * @return null|cached_cm_info
516
 */
517
function bigbluebuttonbn_get_coursemodule_info($coursemodule) {
518
    global $DB;
519
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $coursemodule->instance),
520
        'id, name, intro, introformat');
521
    if (!$bigbluebuttonbn) {
522
        return null;
523
    }
524
    $info = new cached_cm_info();
525
    $info->name = $bigbluebuttonbn->name;
526
    if ($coursemodule->showdescription) {
527
        // Convert intro to html. Do not filter cached version, filters run at display time.
528
        $info->content = format_module_intro('bigbluebuttonbn', $bigbluebuttonbn, $coursemodule->id, false);
529
    }
530
    return $info;
531
}
532
533
/**
534
 * Runs any processes that must run before a bigbluebuttonbn insert/update.
535
 *
536
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
537
 *
538
 * @return void
539
 **/
540
function bigbluebuttonbn_process_pre_save(&$bigbluebuttonbn) {
541
    bigbluebuttonbn_process_pre_save_instance($bigbluebuttonbn);
542
    bigbluebuttonbn_process_pre_save_checkboxes($bigbluebuttonbn);
543
    bigbluebuttonbn_process_pre_save_common($bigbluebuttonbn);
544
    $bigbluebuttonbn->participants = htmlspecialchars_decode($bigbluebuttonbn->participants);
545
}
546
547
/**
548
 * Runs process for defining the instance (insert/update).
549
 *
550
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
551
 *
552
 * @return void
553
 **/
554
function bigbluebuttonbn_process_pre_save_instance(&$bigbluebuttonbn) {
555
    $bigbluebuttonbn->timemodified = time();
556
    if ((integer)$bigbluebuttonbn->instance == 0) {
557
        $bigbluebuttonbn->meetingid = 0;
558
        $bigbluebuttonbn->timecreated = time();
559
        $bigbluebuttonbn->timemodified = 0;
560
        // As it is a new activity, assign passwords.
561
        $bigbluebuttonbn->moderatorpass = bigbluebuttonbn_random_password(12);
562
        $bigbluebuttonbn->viewerpass = bigbluebuttonbn_random_password(12, $bigbluebuttonbn->moderatorpass);
563
    }
564
}
565
566
/**
567
 * Runs process for assigning default value to checkboxes.
568
 *
569
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
570
 *
571
 * @return void
572
 **/
573
function bigbluebuttonbn_process_pre_save_checkboxes(&$bigbluebuttonbn) {
574
    if (!isset($bigbluebuttonbn->wait)) {
575
        $bigbluebuttonbn->wait = 0;
576
    }
577
    if (!isset($bigbluebuttonbn->record)) {
578
        $bigbluebuttonbn->record = 0;
579
    }
580
    if (!isset($bigbluebuttonbn->recordallfromstart)) {
581
        $bigbluebuttonbn->recordallfromstart = 0;
582
    }
583
    if (!isset($bigbluebuttonbn->recordhidebutton)) {
584
        $bigbluebuttonbn->recordhidebutton = 0;
585
    }
586
    if (!isset($bigbluebuttonbn->recordings_html)) {
587
        $bigbluebuttonbn->recordings_html = 0;
588
    }
589
    if (!isset($bigbluebuttonbn->recordings_deleted)) {
590
        $bigbluebuttonbn->recordings_deleted = 0;
591
    }
592
    if (!isset($bigbluebuttonbn->recordings_imported)) {
593
        $bigbluebuttonbn->recordings_imported = 0;
594
    }
595
    if (!isset($bigbluebuttonbn->recordings_preview)) {
596
        $bigbluebuttonbn->recordings_preview = 0;
597
    }
598
    if (!isset($bigbluebuttonbn->muteonstart)) {
599
        $bigbluebuttonbn->muteonstart = 0;
600
    }
601
}
602
603
/**
604
 * Runs process for wipping common settings when 'recordings only'.
605
 *
606
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
607
 *
608
 * @return void
609
 **/
610
function bigbluebuttonbn_process_pre_save_common(&$bigbluebuttonbn) {
611
    // Make sure common settings are removed when 'recordings only'.
612
    if ($bigbluebuttonbn->type == BIGBLUEBUTTONBN_TYPE_RECORDING_ONLY) {
613
        $bigbluebuttonbn->groupmode = 0;
614
        $bigbluebuttonbn->groupingid = 0;
615
    }
616
}
617
618
/**
619
 * Runs any processes that must be run after a bigbluebuttonbn insert/update.
620
 *
621
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
622
 *
623
 * @return void
624
 **/
625
function bigbluebuttonbn_process_post_save(&$bigbluebuttonbn) {
626
    if (isset($bigbluebuttonbn->notification) && $bigbluebuttonbn->notification) {
627
        bigbluebuttonbn_process_post_save_notification($bigbluebuttonbn);
628
    }
629
    bigbluebuttonbn_process_post_save_event($bigbluebuttonbn);
630
    bigbluebuttonbn_process_post_save_completion($bigbluebuttonbn);
631
}
632
633
/**
634
 * Generates a message on insert/update which is sent to all users enrolled.
635
 *
636
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
637
 *
638
 * @return void
639
 **/
640
function bigbluebuttonbn_process_post_save_notification(&$bigbluebuttonbn) {
641
    $action = get_string('mod_form_field_notification_msg_modified', 'bigbluebuttonbn');
642
    if (isset($bigbluebuttonbn->add) && !empty($bigbluebuttonbn->add)) {
643
        $action = get_string('mod_form_field_notification_msg_created', 'bigbluebuttonbn');
644
    }
645
    $context = context_course::instance($bigbluebuttonbn->course);
646
    \mod_bigbluebuttonbn\locallib\notifier::notification_process($context, $bigbluebuttonbn, $action);
647
}
648
649
/**
650
 * Generates an event after a bigbluebuttonbn insert/update.
651
 *
652
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
653
 *
654
 * @return void
655
 **/
656
function bigbluebuttonbn_process_post_save_event(&$bigbluebuttonbn) {
657
    global $DB;
658
    $eventid = $DB->get_field('event', 'id', array('modulename' => 'bigbluebuttonbn',
659
        'instance' => $bigbluebuttonbn->id));
660
    // Delete the event from calendar when/if openingtime is NOT set.
661
    if (!isset($bigbluebuttonbn->openingtime) || !$bigbluebuttonbn->openingtime) {
662
        if ($eventid) {
663
            $calendarevent = calendar_event::load($eventid);
664
            $calendarevent->delete();
665
        }
666
        return;
667
    }
668
    // Add evento to the calendar as openingtime is set.
669
    $event = new stdClass();
670
    $event->eventtype = BIGBLUEBUTTON_EVENT_MEETING_START;
671
    $event->type = CALENDAR_EVENT_TYPE_ACTION;
672
    $event->name = get_string('calendarstarts', 'bigbluebuttonbn', $bigbluebuttonbn->name);
673
    $event->description = format_module_intro('bigbluebuttonbn', $bigbluebuttonbn, $bigbluebuttonbn->coursemodule);
674
    $event->courseid = $bigbluebuttonbn->course;
675
    $event->groupid = 0;
676
    $event->userid = 0;
677
    $event->modulename = 'bigbluebuttonbn';
678
    $event->instance = $bigbluebuttonbn->id;
679
    $event->timestart = $bigbluebuttonbn->openingtime;
680
    $event->timeduration = 0;
681
    $event->timesort = $event->timestart;
682
    $event->visible = instance_is_visible('bigbluebuttonbn', $bigbluebuttonbn);
683
    $event->priority = null;
684
    // Update the event in calendar when/if eventid was found.
685
    if ($eventid) {
686
        $event->id = $eventid;
687
        $calendarevent = calendar_event::load($eventid);
688
        $calendarevent->update($event);
689
        return;
690
    }
691
    calendar_event::create($event);
692
}
693
694
/**
695
 * Generates an event after a bigbluebuttonbn activity is completed.
696
 *
697
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
698
 *
699
 * @return void
700
 **/
701
function bigbluebuttonbn_process_post_save_completion($bigbluebuttonbn) {
702
    if (!empty($bigbluebuttonbn->completionexpected)) {
703
        \core_completion\api::update_completion_date_event(
704
            $bigbluebuttonbn->coursemodule,
705
            'bigbluebuttonbn',
706
            $bigbluebuttonbn->id, $bigbluebuttonbn->completionexpected
707
          );
708
    }
709
}
710
/**
711
 * Get a full path to the file attached as a preuploaded presentation
712
 * or if there is none, set the presentation field will be set to blank.
713
 *
714
 * @param object $bigbluebuttonbn BigBlueButtonBN form data
715
 *
716
 * @return string
717
 */
718
function bigbluebuttonbn_get_media_file(&$bigbluebuttonbn) {
719
    if (!isset($bigbluebuttonbn->presentation) || $bigbluebuttonbn->presentation == '') {
720
        return '';
721
    }
722
    $context = context_module::instance($bigbluebuttonbn->coursemodule);
723
    // Set the filestorage object.
724
    $fs = get_file_storage();
725
    // Save the file if it exists that is currently in the draft area.
726
    file_save_draft_area_files($bigbluebuttonbn->presentation, $context->id, 'mod_bigbluebuttonbn', 'presentation', 0);
727
    // Get the file if it exists.
728
    $files = $fs->get_area_files($context->id, 'mod_bigbluebuttonbn', 'presentation', 0,
729
        'itemid, filepath, filename', false);
730
    // Check that there is a file to process.
731
    $filesrc = '';
732
    if (count($files) == 1) {
733
        // Get the first (and only) file.
734
        $file = reset($files);
735
        $filesrc = '/'.$file->get_filename();
736
    }
737
    return $filesrc;
738
}
739
740
/**
741
 * Serves the bigbluebuttonbn attachments. Implements needed access control ;-).
742
 *
743
 * @category files
744
 *
745
 * @param stdClass $course        course object
746
 * @param stdClass $cm            course module object
747
 * @param stdClass $context       context object
748
 * @param string   $filearea      file area
749
 * @param array    $args          extra arguments
750
 * @param bool     $forcedownload whether or not force download
751
 * @param array    $options       additional options affecting the file serving
752
 *
753
 * @return false|null false if file not found, does not return if found - justsend the file
754
 */
755
function bigbluebuttonbn_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) {
756
    if (!bigbluebuttonbn_pluginfile_valid($context, $filearea)) {
757
        return false;
758
    }
759
    $file = bigbluebuttonbn_pluginfile_file($course, $cm, $context, $filearea, $args);
760
    if (empty($file)) {
761
        return false;
762
    }
763
    // Finally send the file.
764
    send_stored_file($file, 0, 0, $forcedownload, $options); // download MUST be forced - security!
765
}
766
767
/**
768
 * Helper for validating pluginfile.
769
 * @param stdClass $context       context object
770
 * @param string   $filearea      file area
771
 *
772
 * @return false|null false if file not valid
773
 */
774
function bigbluebuttonbn_pluginfile_valid($context, $filearea) {
775
776
    // Can be in context module or in context_system (if is the presentation by default).
777
    if (!in_array($context->contextlevel, array(CONTEXT_MODULE, CONTEXT_SYSTEM))) {
778
        return false;
779
    }
780
781
    if (!array_key_exists($filearea, bigbluebuttonbn_get_file_areas())) {
782
        return false;
783
    }
784
785
    return true;
786
}
787
788
/**
789
 * Helper for getting pluginfile.
790
 *
791
 * @param stdClass $course        course object
792
 * @param stdClass $cm            course module object
793
 * @param stdClass $context       context object
794
 * @param string   $filearea      file area
795
 * @param array    $args          extra arguments
796
 *
797
 * @return object
798
 */
799
function bigbluebuttonbn_pluginfile_file($course, $cm, $context, $filearea, $args) {
800
    $filename = bigbluebuttonbn_pluginfile_filename($course, $cm, $context, $args);
801
    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...
802
        return false;
803
    }
804
    $fullpath = "/$context->id/mod_bigbluebuttonbn/$filearea/0/".$filename;
805
    $fs = get_file_storage();
806
    $file = $fs->get_file_by_hash(sha1($fullpath));
807
    if (!$file || $file->is_directory()) {
808
        return false;
809
    }
810
    return $file;
811
}
812
813
/**
814
 * Helper for give access to the file configured in setting as default presentation.
815
 *
816
 * @param stdClass $course        course object
817
 * @param stdClass $cm            course module object
818
 * @param stdClass $context       context object
819
 * @param array    $args          extra arguments
820
 *
821
 * @return array
822
 */
823
function bigbluebuttonbn_default_presentation_get_file($course, $cm, $context, $args) {
824
825
    // The difference with the standard bigbluebuttonbn_pluginfile_filename() are.
826
    // - Context is system, so we don't need to check the cmid in this case.
827
    // - The area is "presentationdefault_cache".
828
    if (count($args) > 1) {
829
        $cache = cache::make_from_params(cache_store::MODE_APPLICATION,
830
            'mod_bigbluebuttonbn',
831
            'presentationdefault_cache');
832
833
        $noncekey = sha1($context->id);
834
        $presentationnonce = $cache->get($noncekey);
835
        $noncevalue = $presentationnonce['value'];
836
        $noncecounter = $presentationnonce['counter'];
837
        if ($args['0'] != $noncevalue) {
838
            return;
839
        }
840
841
        // The nonce value is actually used twice because BigBlueButton reads the file two times.
842
        $noncecounter += 1;
843
        $cache->set($noncekey, array('value' => $noncevalue, 'counter' => $noncecounter));
844
        if ($noncecounter == 2) {
845
            $cache->delete($noncekey);
846
        }
847
        return($args['1']);
848
    }
849
    require_course_login($course, true, $cm);
850
    if (!has_capability('mod/bigbluebuttonbn:join', $context)) {
851
        return;
852
    }
853
    return implode('/', $args);
854
}
855
856
/**
857
 * Helper for getting pluginfile name.
858
 *
859
 * @param stdClass $course        course object
860
 * @param stdClass $cm            course module object
861
 * @param stdClass $context       context object
862
 * @param array    $args          extra arguments
863
 *
864
 * @return array
865
 */
866
function bigbluebuttonbn_pluginfile_filename($course, $cm, $context, $args) {
867
    global $DB;
868
869
    if ($context->contextlevel == CONTEXT_SYSTEM) {
870
        // Plugin has a file to use as default in general setting.
871
        return(bigbluebuttonbn_default_presentation_get_file($course, $cm, $context, $args));
872
    }
873
874
    if (count($args) > 1) {
875
        if (!$bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $cm->instance))) {
876
            return;
877
        }
878
        $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', 'presentation_cache');
879
        $noncekey = sha1($bigbluebuttonbn->id);
880
        $presentationnonce = $cache->get($noncekey);
881
        $noncevalue = $presentationnonce['value'];
882
        $noncecounter = $presentationnonce['counter'];
883
        if ($args['0'] != $noncevalue) {
884
            return;
885
        }
886
        // The nonce value is actually used twice because BigBlueButton reads the file two times.
887
        $noncecounter += 1;
888
        $cache->set($noncekey, array('value' => $noncevalue, 'counter' => $noncecounter));
889
        if ($noncecounter == 2) {
890
            $cache->delete($noncekey);
891
        }
892
        return $args['1'];
893
    }
894
    require_course_login($course, true, $cm);
895
    if (!has_capability('mod/bigbluebuttonbn:join', $context)) {
896
        return;
897
    }
898
    return implode('/', $args);
899
}
900
901
/**
902
 * Returns an array of file areas.
903
 *
904
 * @category files
905
 *
906
 * @return array a list of available file areas
907
 */
908
function bigbluebuttonbn_get_file_areas() {
909
    $areas = array();
910
    $areas['presentation'] = get_string('mod_form_block_presentation', 'bigbluebuttonbn');
911
    $areas['presentationdefault'] = get_string('mod_form_block_presentation_default', 'bigbluebuttonbn');
912
    return $areas;
913
}
914
915
/**
916
 * Mark the activity completed (if required) and trigger the course_module_viewed event.
917
 *
918
 * @param  stdClass $bigbluebuttonbn        bigbluebuttonbn object
919
 * @param  stdClass $course     course object
920
 * @param  stdClass $cm         course module object
921
 * @param  stdClass $context    context object
922
 * @since Moodle 3.0
923
 */
924
function bigbluebuttonbn_view($bigbluebuttonbn, $course, $cm, $context) {
925
926
    // Trigger course_module_viewed event.
927
    $params = array(
928
        'context' => $context,
929
        'objectid' => $bigbluebuttonbn->id
930
    );
931
932
    $event = \mod_bigbluebuttonbn\event\bigbluebuttonbn_activity_viewed::create($params);
933
    $event->add_record_snapshot('course_modules', $cm);
934
    $event->add_record_snapshot('course', $course);
935
    $event->add_record_snapshot('bigbluebuttonbn', $bigbluebuttonbn);
936
    $event->trigger();
937
938
    // Completion.
939
    $completion = new completion_info($course);
940
    $completion->set_module_viewed($cm);
941
}
942
943
/**
944
 * Check if the module has any update that affects the current user since a given time.
945
 *
946
 * @param  cm_info $cm course module data
947
 * @param  int $from the time to check updates from
948
 * @param  array $filter  if we need to check only specific updates
949
 * @return stdClass an object with the different type of areas indicating if they were updated or not
950
 * @since Moodle 3.2
951
 */
952
function bigbluebuttonbn_check_updates_since(cm_info $cm, $from, $filter = array()) {
953
    $updates = course_check_module_updates_since($cm, $from, array('content'), $filter);
954
    return $updates;
955
}
956
957
958
/**
959
 * Get icon mapping for font-awesome.
960
 */
961
function mod_bigbluebuttonbn_get_fontawesome_icon_map() {
962
    return [
963
        'mod_bigbluebuttonbn:icon' => 'icon-bigbluebutton',
964
    ];
965
}
966
967
/**
968
 * This function receives a calendar event and returns the action associated with it, or null if there is none.
969
 *
970
 * This is used by block_myoverview in order to display the event appropriately. If null is returned then the event
971
 * is not displayed on the block.
972
 *
973
 * @param calendar_event $event
974
 * @param \core_calendar\action_factory $factory
975
 * @return \core_calendar\local\event\entities\action_interface|null
976
 */
977
function mod_bigbluebuttonbn_core_calendar_provide_event_action(calendar_event $event,
978
        \core_calendar\action_factory $factory) {
979
    global $CFG, $DB;
980
981
    require_once($CFG->dirroot . '/mod/bigbluebuttonbn/locallib.php');
982
983
    $cm = get_fast_modinfo($event->courseid)->instances['bigbluebuttonbn'][$event->instance];
984
985
    // Check that the bigbluebuttonbn activity is open.
986
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $event->instance), '*', MUST_EXIST);
987
    $actionable = bigbluebuttonbn_get_availability_status($bigbluebuttonbn);
988
989
    $string = get_string('view_room', 'bigbluebuttonbn');
990
    $url = new \moodle_url('/mod/bigbluebuttonbn/view.php', array('id' => $cm->id));
991
    if (groups_get_activity_groupmode($cm) == NOGROUPS) {
992
        // No groups mode.
993
        $string = get_string('view_conference_action_join', 'bigbluebuttonbn');
994
        $url = new \moodle_url('/mod/bigbluebuttonbn/bbb_view.php', array('action' => 'join',
995
            'id' => $cm->id, 'bn' => $bigbluebuttonbn->id, 'timeline' => 1));
996
    }
997
998
    return $factory->create_instance($string, $url, 1, $actionable);
999
}
1000
1001
/**
1002
 * Register a bigbluebuttonbn event
1003
 *
1004
 * @param object $bigbluebuttonbn
1005
 * @param string $event
1006
 * @param array  $overrides
1007
 * @param string $meta
1008
 *
1009
 * @return bool Success/Failure
1010
 */
1011
function bigbluebuttonbn_log($bigbluebuttonbn, $event, array $overrides = [], $meta = null) {
1012
    global $DB, $USER;
1013
    $log = new stdClass();
1014
    // Default values.
1015
    $log->courseid = $bigbluebuttonbn->course;
1016
    $log->bigbluebuttonbnid = $bigbluebuttonbn->id;
1017
    $log->userid = $USER->id;
1018
    $log->meetingid = $bigbluebuttonbn->meetingid;
1019
    $log->timecreated = time();
1020
    $log->log = $event;
1021
    $log->meta = $meta;
1022
    // Overrides.
1023
    foreach ($overrides as $key => $value) {
1024
        $log->$key = $value;
1025
    }
1026
    if ($DB->insert_record('bigbluebuttonbn_logs', $log)) {
1027
        return true;
1028
    }
1029
    return false;
1030
}
1031