Passed
Pull Request — 1.11.x (#3739)
by Julito
14:08
created

BBBPlugin::update_course_field_in_all_courses()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 9
c 0
b 0
f 0
nop 2
dl 0
loc 12
rs 9.9666
nc 2
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
/* To show the plugin course icons you need to add these icons:
6
 * main/img/icons/22/plugin_name.png
7
 * main/img/icons/64/plugin_name.png
8
 * main/img/icons/64/plugin_name_na.png
9
*/
10
11
/**
12
 * Class BBBPlugin
13
 * Videoconference plugin with BBB
14
 */
15
class BBBPlugin extends Plugin
16
{
17
    const INTERFACE_FLASH = 0;
18
    const INTERFACE_HTML5 = 1;
19
20
    const LAUNCH_TYPE_DEFAULT = 0;
21
    const LAUNCH_TYPE_SET_BY_TEACHER = 1;
22
    const LAUNCH_TYPE_SET_BY_STUDENT = 2;
23
24
    const ROOM_OPEN = 0;
25
    const ROOM_CLOSE = 1;
26
    const ROOM_CHECK = 2;
27
28
    public $isCoursePlugin = true;
29
30
    // When creating a new course this settings are added to the course
31
    public $course_settings = [
32
        [
33
            'name' => 'big_blue_button_record_and_store',
34
            'type' => 'checkbox',
35
        ],
36
        [
37
            'name' => 'bbb_enable_conference_in_groups',
38
            'type' => 'checkbox',
39
        ],
40
        [
41
            'name' => 'bbb_force_record_generation',
42
            'type' => 'checkbox',
43
        ],
44
        [
45
            'name' => 'big_blue_button_students_start_conference_in_groups',
46
            'type' => 'checkbox',
47
        ],
48
    ];
49
50
    /**
51
     * BBBPlugin constructor.
52
     */
53
    protected function __construct()
54
    {
55
        parent::__construct(
56
            '2.8.2',
57
            'Julio Montoya, Yannick Warnier, Angel Fernando Quiroz Campos, Jose Angel Ruiz',
58
            [
59
                'tool_enable' => 'boolean',
60
                'host' => 'text',
61
                'salt' => 'text',
62
                'enable_global_conference' => 'boolean',
63
                'enable_global_conference_per_user' => 'boolean',
64
                'enable_conference_in_course_groups' => 'boolean',
65
                'enable_global_conference_link' => 'boolean',
66
                'disable_download_conference_link' => 'boolean',
67
                'max_users_limit' => 'text',
68
                'global_conference_allow_roles' => [
69
                    'type' => 'select',
70
                    'options' => [
71
                        PLATFORM_ADMIN => get_lang('Administrator'),
72
                        COURSEMANAGER => get_lang('Teacher'),
73
                        STUDENT => get_lang('Student'),
74
                        STUDENT_BOSS => get_lang('StudentBoss'),
75
                    ],
76
                    'attributes' => ['multiple' => 'multiple'],
77
                ],
78
                'allow_regenerate_recording' => 'boolean',
79
                // Default course settings, must be the same as $course_settings
80
                'big_blue_button_record_and_store' => 'checkbox',
81
                'bbb_enable_conference_in_groups' => 'checkbox',
82
                'bbb_force_record_generation' => 'checkbox',
83
                'disable_course_settings' => 'boolean',
84
                'meeting_duration' => 'text',
85
            ]
86
        );
87
88
        $this->isAdminPlugin = true;
89
    }
90
91
    /**
92
     * @return BBBPlugin|null
93
     */
94
    public static function create()
95
    {
96
        static $result = null;
97
98
        return $result ? $result : $result = new self();
99
    }
100
101
    /**
102
     * @param string $variable
103
     *
104
     * @return bool
105
     */
106
    public function validateCourseSetting($variable)
107
    {
108
        if ($this->get('disable_course_settings') === 'true') {
109
            return false;
110
        }
111
112
        $result = true;
113
        switch ($variable) {
114
            case 'bbb_enable_conference_in_groups':
115
                $result = $this->get('enable_conference_in_course_groups') === 'true';
116
                break;
117
            case 'bbb_force_record_generation':
118
                $result = $this->get('allow_regenerate_recording') === 'true';
119
                break;
120
            case 'big_blue_button_record_and_store':
121
        }
122
123
        return $result;
124
    }
125
126
    /**
127
     *
128
     * @return array
129
     */
130
    public function getCourseSettings()
131
    {
132
        $settings = [];
133
        if ($this->get('disable_course_settings') !== 'true') {
134
            $settings = parent::getCourseSettings();
135
        }
136
137
        return $settings;
138
    }
139
140
    /**
141
     *
142
     * @return \Plugin
143
     */
144
    public function performActionsAfterConfigure()
145
    {
146
        $result = $this->get('disable_course_settings') === 'true';
147
        if ($result) {
148
            $valueConference = $this->get('bbb_enable_conference_in_groups') === 'true' ? 1 : 0;
149
            self::update_course_field_in_all_courses('bbb_enable_conference_in_groups', $valueConference);
150
151
            $valueForceRecordGeneration = $this->get('bbb_force_record_generation') === 'true' ? 1 : 0;
152
            self::update_course_field_in_all_courses('bbb_force_record_generation', $valueForceRecordGeneration);
153
154
            $valueForceRecordStore = $this->get('big_blue_button_record_and_store') === 'true' ? 1 : 0;
155
            self::update_course_field_in_all_courses('big_blue_button_record_and_store', $valueForceRecordStore);
156
        }
157
158
        return $this;
159
    }
160
161
    /**
162
     * Install
163
     */
164
    public function install()
165
    {
166
        $sql = "CREATE TABLE IF NOT EXISTS plugin_bbb_meeting (
167
                id INT unsigned NOT NULL auto_increment PRIMARY KEY,
168
                c_id INT unsigned NOT NULL DEFAULT 0,
169
                group_id INT unsigned NOT NULL DEFAULT 0,
170
                user_id INT unsigned NOT NULL DEFAULT 0,
171
                meeting_name VARCHAR(255) NOT NULL DEFAULT '',
172
                attendee_pw VARCHAR(255) NOT NULL DEFAULT '',
173
                moderator_pw VARCHAR(255) NOT NULL DEFAULT '',
174
                record INT NOT NULL DEFAULT 0,
175
                status INT NOT NULL DEFAULT 0,
176
                created_at VARCHAR(255) NOT NULL,
177
                closed_at VARCHAR(255) NOT NULL,
178
                calendar_id INT DEFAULT 0,
179
                welcome_msg VARCHAR(255) NOT NULL DEFAULT '',
180
                session_id INT unsigned DEFAULT 0,
181
                remote_id CHAR(30),
182
                internal_meeting_id VARCHAR(255) DEFAULT NULL,
183
                visibility TINYINT NOT NULL DEFAULT 1,
184
                voice_bridge INT NOT NULL DEFAULT 1,
185
                access_url INT NOT NULL DEFAULT 1,
186
                video_url TEXT NULL,
187
                has_video_m4v TINYINT NOT NULL DEFAULT 0,
188
                interface INT NOT NULL DEFAULT 0
189
                )";
190
        Database::query($sql);
191
192
        Database::query(
193
            "CREATE TABLE IF NOT EXISTS plugin_bbb_room (
194
                id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
195
                meeting_id int NOT NULL,
196
                participant_id int(11) NOT NULL,
197
                in_at datetime,
198
                out_at datetime,
199
                interface int NOT NULL DEFAULT 0,
200
                close INT NOT NULL DEFAULT 0
201
            );"
202
        );
203
        $fieldLabel = 'plugin_bbb_course_users_limit';
204
        $fieldType = ExtraField::FIELD_TYPE_INTEGER;
205
        $fieldTitle = $this->get_lang('MaxUsersInConferenceRoom');
206
        $fieldDefault = '0';
207
        $extraField = new ExtraField('course');
208
        $fieldId = CourseManager::create_course_extra_field(
209
            $fieldLabel,
210
            $fieldType,
211
            $fieldTitle,
212
            $fieldDefault
213
        );
214
        $extraField->find($fieldId);
215
        $extraField->update(
216
            [
217
                'id' => $fieldId,
218
                'variable' => 'plugin_bbb_course_users_limit',
219
                'changeable' => 1,
220
                'visible_to_self' => 1,
221
                'visible_to_others' => 0,
222
            ]
223
        );
224
        $fieldLabel = 'plugin_bbb_session_users_limit';
225
        $extraField = new ExtraField('session');
226
        $fieldId = SessionManager::create_session_extra_field(
227
            $fieldLabel,
228
            $fieldType,
229
            $fieldTitle,
230
            $fieldDefault
231
        );
232
        $extraField->find($fieldId);
233
        $extraField->update(
234
            [
235
                'id' => $fieldId,
236
                'variable' => 'plugin_bbb_session_users_limit',
237
                'changeable' => 1,
238
                'visible_to_self' => 1,
239
                'visible_to_others' => 0,
240
            ]
241
        );
242
243
        // Copy icons into the main/img/icons folder
244
        $iconName = 'bigbluebutton';
245
        $iconsList = [
246
            '64/'.$iconName.'.png',
247
            '64/'.$iconName.'_na.png',
248
            '32/'.$iconName.'.png',
249
            '32/'.$iconName.'_na.png',
250
            '22/'.$iconName.'.png',
251
            '22/'.$iconName.'_na.png',
252
        ];
253
        $sourceDir = api_get_path(SYS_PLUGIN_PATH).'bbb/resources/img/';
254
        $destinationDir = api_get_path(SYS_CODE_PATH).'img/icons/';
255
        foreach ($iconsList as $icon) {
256
            $src = $sourceDir.$icon;
257
            $dest = $destinationDir.$icon;
258
            copy($src, $dest);
259
        }
260
        // Installing course settings
261
        $this->install_course_fields_in_all_courses(true, 'bigbluebutton.png');
262
    }
263
264
    /**
265
     * Uninstall
266
     */
267
    public function uninstall()
268
    {
269
        $t_settings = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
270
        $t_options = Database::get_main_table(TABLE_MAIN_SETTINGS_OPTIONS);
271
        $t_tool = Database::get_course_table(TABLE_TOOL_LIST);
272
273
        $variables = [
274
            'bbb_salt',
275
            'bbb_host',
276
            'bbb_tool_enable',
277
            'enable_global_conference',
278
            'enable_global_conference_per_user',
279
            'enable_global_conference_link',
280
            'disable_download_conference_link',
281
            'enable_conference_in_course_groups',
282
            'bbb_plugin',
283
            'bbb_plugin_host',
284
            'bbb_plugin_salt',
285
            'max_users_limit',
286
            'global_conference_allow_roles'
287
        ];
288
289
        $urlId = api_get_current_access_url_id();
290
291
        foreach ($variables as $variable) {
292
            $sql = "DELETE FROM $t_settings WHERE variable = '$variable' AND access_url = $urlId";
293
            Database::query($sql);
294
        }
295
296
        $em = Database::getManager();
297
        $sm = $em->getConnection()->getSchemaManager();
298
        if ($sm->tablesExist('plugin_bbb_meeting')) {
299
            Database::query("DELETE FROM plugin_bbb_meeting WHERE access_url = $urlId");
300
        }
301
302
        // Only delete tables if it's uninstalled from main url.
303
        if (1 == $urlId) {
304
            $extraField = new ExtraField('course');
305
            $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable(
306
                'plugin_bbb_course_users_limit'
307
            );
308
            if (!empty($extraFieldInfo)) {
309
                $extraField->delete($extraFieldInfo['id']);
310
            }
311
            $extraField = new ExtraField('session');
312
            $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable(
313
                'plugin_bbb_session_users_limit'
314
            );
315
            if (!empty($extraFieldInfo)) {
316
                $extraField->delete($extraFieldInfo['id']);
317
            }
318
319
            $sql = "DELETE FROM $t_options WHERE variable = 'bbb_plugin'";
320
            Database::query($sql);
321
322
            // hack to get rid of Database::query warning (please add c_id...)
323
            $sql = "DELETE FROM $t_tool WHERE name = 'bbb' AND c_id != 0";
324
            Database::query($sql);
325
326
            if ($sm->tablesExist('plugin_bbb_room')) {
327
                Database::query('DROP TABLE IF EXISTS plugin_bbb_room');
328
            }
329
            if ($sm->tablesExist('plugin_bbb_meeting')) {
330
                Database::query('DROP TABLE IF EXISTS plugin_bbb_meeting');
331
            }
332
333
            // Deleting course settings
334
            $this->uninstall_course_fields_in_all_courses($this->course_settings);
335
336
            // Remove icons from the main/img/icons folder
337
            $iconName = 'bigbluebutton';
338
            $iconsList = [
339
                '64/'.$iconName.'.png',
340
                '64/'.$iconName.'_na.png',
341
                '32/'.$iconName.'.png',
342
                '32/'.$iconName.'_na.png',
343
                '22/'.$iconName.'.png',
344
                '22/'.$iconName.'_na.png',
345
            ];
346
            $destinationDir = api_get_path(SYS_CODE_PATH).'img/icons/';
347
            foreach ($iconsList as $icon) {
348
                $dest = $destinationDir.$icon;
349
                if (is_file($dest)) {
350
                    @unlink($dest);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

350
                    /** @scrutinizer ignore-unhandled */ @unlink($dest);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
351
                }
352
            }
353
        }
354
    }
355
356
    /**
357
     * Update
358
     */
359
    public function update()
360
    {
361
        $sql = "SHOW COLUMNS FROM plugin_bbb_room WHERE Field = 'close'";
362
        $res = Database::query($sql);
363
364
        if (Database::num_rows($res) === 0) {
365
            $sql = "ALTER TABLE plugin_bbb_room ADD close int unsigned NULL";
366
            $res = Database::query($sql);
367
            if (!$res) {
0 ignored issues
show
introduced by
$res is of type Doctrine\DBAL\Driver\Statement, thus it always evaluated to true.
Loading history...
368
                echo Display::return_message($this->get_lang('ErrorUpdateFieldDB'), 'warning');
369
            }
370
371
            Database::update(
372
                'plugin_bbb_room',
373
                ['close' => BBBPlugin::ROOM_CLOSE]
374
            );
375
        }
376
    }
377
378
    /**
379
     * @param string $conferenceUrl
380
     *
381
     * @return array
382
     */
383
    public function getHtmlUrl($conferenceUrl)
384
    {
385
        $data = [
386
            'text' => $this->get_lang('EnterConferenceHTML5'),
387
            'url' => $conferenceUrl.'&interface='.self::INTERFACE_HTML5,
388
            'icon' => 'resources/img/64/videoconference_html5.png',
389
        ];
390
391
        return $data;
392
    }
393
394
    /**
395
     * Set the course setting in all courses
396
     *
397
     * @param bool $variable Course setting to update
398
     * @param bool $value New values of the course setting
399
     */
400
    public function update_course_field_in_all_courses($variable, $value)
401
    {
402
        // Update existing courses to add the new course setting value
403
        $table = Database::get_main_table(TABLE_MAIN_COURSE);
404
        $sql = "SELECT id FROM $table ORDER BY id";
405
        $res = Database::query($sql);
406
        $courseSettingTable = Database::get_course_table(TABLE_COURSE_SETTING);
407
        while ($row = Database::fetch_assoc($res)) {
408
            Database::update(
409
                $courseSettingTable,
410
                ['value' => $value],
411
                ['variable = ? AND c_id = ?' => [$variable, $row['id']]]
412
            );
413
        }
414
    }
415
}
416