Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
namespace mod_bigbluebuttonbn\local\bigbluebutton\recordings;
18
 
19
use mod_bigbluebuttonbn\instance;
20
use mod_bigbluebuttonbn\local\config;
21
use mod_bigbluebuttonbn\local\helpers\roles;
22
use mod_bigbluebuttonbn\local\proxy\bigbluebutton_proxy;
23
use mod_bigbluebuttonbn\output\recording_description_editable;
24
use mod_bigbluebuttonbn\output\recording_name_editable;
25
use mod_bigbluebuttonbn\output\recording_row_actionbar;
26
use mod_bigbluebuttonbn\output\recording_row_playback;
27
use mod_bigbluebuttonbn\output\recording_row_preview;
28
use mod_bigbluebuttonbn\recording;
29
use stdClass;
30
 
31
/**
32
 * The recordings_data.
33
 *
34
 * @package   mod_bigbluebuttonbn
35
 * @copyright 2021 onwards, Blindside Networks Inc
36
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37
 * @author    Laurent David  (laurent.david [at] call-learning [dt] fr)
38
 * @author    Jesus Federico  (jesus [at] blindsidenetworks [dt] com)
39
 */
40
class recording_data {
41
 
42
    /**
43
     * Get the full recording table
44
     *
45
     * @param array $recordings
46
     * @param array $tools
47
     * @param instance|null $instance
48
     * @param int $courseid
49
     * @return array
50
     */
51
    public static function get_recording_table(array $recordings, array $tools, instance $instance = null,
52
        int $courseid = 0): array {
53
        $typeprofiles = bigbluebutton_proxy::get_instance_type_profiles();
54
        $typeprofile = empty($instance) ? $typeprofiles[0] : $typeprofiles[$instance->get_type()];
55
        $lang = get_string('locale', 'core_langconfig');
56
        $locale = substr($lang, 0, strpos($lang, '.'));
57
        $tabledata = [
58
            'activity' => empty($instance) ? '' : bigbluebutton_proxy::view_get_activity_status($instance),
59
            'ping_interval' => (int) config::get('waitformoderator_ping_interval') * 1000,
60
            'locale' => substr($locale, 0, strpos($locale, '_')),
61
            'profile_features' => $typeprofile['features'],
62
            'columns' => [],
63
            'data' => '',
64
        ];
65
        $hascapabilityincourse = empty($instance) && roles::has_capability_in_course($courseid,
66
                'mod/bigbluebuttonbn:managerecordings');
67
 
68
        $data = [];
69
 
70
        // Build table content.
71
        foreach ($recordings as $recording) {
72
            $rowtools = $tools;
73
            // Protected recordings may be enabled or disabled from UI through configuration.
74
            if (!(boolean) config::get('recording_protect_editable')) {
75
                $rowtools = array_diff($rowtools, ['protect', 'unprotect']);
76
            }
77
            // Protected recordings is not a standard feature, remove actions when protected flag is not present.
78
            if (in_array('protect', $rowtools) && $recording->get('protected') === null) {
79
                $rowtools = array_diff($rowtools, ['protect', 'unprotect']);
80
            }
81
            $rowdata = self::row($instance, $recording, $rowtools);
82
            if (!empty($rowdata)) {
83
                $data[] = $rowdata;
84
            }
85
        }
86
 
87
        $columns = [
88
            [
89
                'key' => 'playback',
90
                'label' => get_string('view_recording_playback', 'bigbluebuttonbn'),
91
                'width' => '125px',
92
                'type' => 'html',
93
                'allowHTML' => true,
94
            ],
95
            [
96
                'key' => 'recording',
97
                'label' => get_string('view_recording_name', 'bigbluebuttonbn'),
98
                'width' => '125px',
99
                'type' => 'html',
100
                'allowHTML' => true,
101
            ],
102
            [
103
                'key' => 'description',
104
                'label' => get_string('view_recording_description', 'bigbluebuttonbn'),
105
                'sortable' => true,
106
                'width' => '250px',
107
                'type' => 'html',
108
                'allowHTML' => true,
109
            ],
110
        ];
111
 
112
        // Initialize table headers.
113
        $ispreviewenabled = !empty($instance) && self::preview_enabled($instance);
114
        $ispreviewenabled = $ispreviewenabled || $hascapabilityincourse;
115
        if ($ispreviewenabled) {
116
            $columns[] = [
117
                'key' => 'preview',
118
                'label' => get_string('view_recording_preview', 'bigbluebuttonbn'),
119
                'width' => '250px',
120
                'type' => 'html',
121
                'allowHTML' => true,
122
            ];
123
        }
124
 
125
        $columns[] = [
126
            'key' => 'date',
127
            'label' => get_string('view_recording_date', 'bigbluebuttonbn'),
128
            'sortable' => true,
129
            'width' => '225px',
130
            'type' => 'html',
131
            'formatter' => 'customDate',
132
        ];
133
        $columns[] = [
134
            'key' => 'duration',
135
            'label' => get_string('view_recording_duration', 'bigbluebuttonbn'),
136
            'width' => '50px',
137
            'allowHTML' => false,
138
            'sortable' => true,
139
        ];
140
        // Either instance is empty and we must show the toolbar (with restricted content) or we check
141
        // specific rights related to the instance.
142
        $canmanagerecordings = !empty($instance) && $instance->can_manage_recordings();
143
        $canmanagerecordings = $canmanagerecordings || $hascapabilityincourse;
144
        if ($canmanagerecordings) {
145
            $columns[] = [
146
                'key' => 'actionbar',
147
                'label' => get_string('view_recording_actionbar', 'bigbluebuttonbn'),
148
                'width' => '120px',
149
                'type' => 'html',
150
                'allowHTML' => true,
151
            ];
152
        }
153
 
154
        $tabledata['columns'] = $columns;
155
        $tabledata['data'] = json_encode($data);
156
 
157
        return $tabledata;
158
    }
159
 
160
    /**
161
     * Helper function builds a row for the data used by the recording table.
162
     *
163
     * TODO: replace this with templates whenever possible so we just
164
     * return the data via the API.
165
     *
166
     * @param instance|null $instance $instance
167
     * @param recording $rec a recording row
168
     * @param array|null $tools
169
     * @param int|null $courseid
170
     * @return stdClass|null
171
     */
172
    public static function row(?instance $instance, recording $rec, ?array $tools = null, ?int $courseid = 0): ?stdClass {
173
        global $PAGE;
174
 
175
        $hascapabilityincourse = empty($instance) && roles::has_capability_in_course($courseid,
176
                'mod/bigbluebuttonbn:managerecordings');
177
        $renderer = $PAGE->get_renderer('mod_bigbluebuttonbn');
178
        foreach ($tools as $key => $tool) {
179
            if ((!empty($instance) && !$instance->can_perform_on_recordings($tool))
180
                || (empty($instance) && !$hascapabilityincourse)) {
181
                unset($tools[$key]);
182
            }
183
        }
184
        if (!self::include_recording_table_row($instance, $rec)) {
185
            return null;
186
        }
187
        $rowdata = new stdClass();
188
 
189
        // Set recording_playback.
190
        $recordingplayback = new recording_row_playback($rec, $instance);
191
        $rowdata->playback = $renderer->render($recordingplayback);
192
 
193
        if (empty($instance)) {
194
            // Set activity name.
195
            $rowdata->recording = $rec->get('name');
196
 
197
            // Set activity description.
198
            $rowdata->description = $rec->get('description');
199
        } else {
200
            // Set activity name.
201
            $recordingname = new recording_name_editable($rec, $instance);
202
            $rowdata->recording = $renderer->render_inplace_editable($recordingname);
203
            // Set activity description.
204
            $recordingdescription = new recording_description_editable($rec, $instance);
205
            $rowdata->description = $renderer->render_inplace_editable($recordingdescription);
206
        }
207
 
208
        if ((!empty($instance) && self::preview_enabled($instance)) || $hascapabilityincourse) {
209
            // Set recording_preview.
210
            $rowdata->preview = '';
211
            if ($rec->get('playbacks')) {
212
                $rowpreview = new recording_row_preview($rec);
213
                $rowdata->preview = $renderer->render($rowpreview);
214
            }
215
        }
216
        // Set date.
217
        $starttime = $rec->get('starttime');
218
        $rowdata->date = !is_null($starttime) ? floatval($starttime) : 0;
219
        // Set duration.
220
        $rowdata->duration = self::row_duration($rec);
221
        // Set actionbar, if user is allowed to manage recordings.
222
        if ((!empty($instance) && $instance->can_manage_recordings()) || $hascapabilityincourse) {
223
            $actionbar = new recording_row_actionbar($rec, $tools);
224
            $rowdata->actionbar = $renderer->render($actionbar);
225
        }
226
        return $rowdata;
227
    }
228
 
229
    /**
230
     * Helper function evaluates if recording preview should be included.
231
     *
232
     * @param instance $instance
233
     * @return bool
234
     */
235
    public static function preview_enabled(instance $instance): bool {
236
        return $instance->get_instance_var('recordings_preview') == '1';
237
    }
238
 
239
    /**
240
     * Helper function converts recording duration used in row for the data used by the recording table.
241
     *
242
     * @param recording $recording
243
     * @return int
244
     */
245
    protected static function row_duration(recording $recording): int {
246
        $playbacks = $recording->get('playbacks');
247
        if (empty($playbacks)) {
248
            return 0;
249
        }
250
        foreach ($playbacks as $playback) {
251
            // Ignore restricted playbacks.
252
            if (array_key_exists('restricted', $playback) && strtolower($playback['restricted']) == 'true') {
253
                continue;
254
            }
255
 
256
            // Take the length form the fist playback with an actual value.
257
            if (!empty($playback['length'])) {
258
                return intval($playback['length']);
259
            }
260
        }
261
        return 0;
262
    }
263
 
264
    /**
265
     * Helper function to handle yet unknown recording types
266
     *
267
     * @param string $playbacktype : for now presentation, video, statistics, capture, notes, podcast
268
     * @return string the matching language string or a capitalised version of the provided string
269
     */
270
    public static function type_text(string $playbacktype): string {
271
        // Check first if string exists, and if it does not, just default to the capitalised version of the string.
272
        $text = ucwords($playbacktype);
273
        $typestringid = 'view_recording_format_' . $playbacktype;
274
        if (get_string_manager()->string_exists($typestringid, 'bigbluebuttonbn')) {
275
            $text = get_string($typestringid, 'bigbluebuttonbn');
276
        }
277
        return $text;
278
    }
279
 
280
    /**
281
     * Helper function evaluates if recording row should be included in the table.
282
     *
283
     * @param instance|null $instance
284
     * @param recording $rec a bigbluebuttonbn_recordings row
285
     * @return bool
286
     */
287
    protected static function include_recording_table_row(?instance $instance, recording $rec): bool {
288
        if (empty($instance)) {
289
            return roles::has_capability_in_course($rec->get('courseid'), 'mod/bigbluebuttonbn:managerecordings');
290
        }
291
        // Exclude unpublished recordings, only if user has no rights to manage them.
292
        if (!$rec->get('published') && !$instance->can_manage_recordings()) {
293
            return false;
294
        }
295
        // Imported recordings are always shown as long as they are published.
296
        if ($rec->get('imported')) {
297
            return true;
298
        }
299
        // When show imported recordings only is enabled, exclude all other recordings.
300
        if ($instance->get_recordings_imported() && !$rec->get('imported')) {
301
            return false;
302
        }
303
        // Administrators and moderators are always allowed.
304
        if ($instance->is_admin() || $instance->is_moderator()) {
305
            return true;
306
        }
307
        // When groups are enabled, exclude those to which the user doesn't have access to.
308
        if ($instance->uses_groups() && !$instance->can_manage_recordings()) {
309
            if (groups_get_activity_groupmode($instance->get_cm()) == VISIBLEGROUPS) {
310
                // In case we are in visible group mode, we show all recordings.
311
                return true;
312
            }
313
            // Else we check if the Recording group is the same as the instance. Instance group
314
            // being the group chosen for this instance.
315
            return intval($rec->get('groupid')) === $instance->get_group_id();
316
        }
317
        return true;
318
    }
319
}