Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | 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
declare(strict_types=1);
18
 
19
namespace core_files\reportbuilder\local\entities;
20
 
21
use core_collator;
22
use core_filetypes;
23
use lang_string;
24
use license_manager;
25
use stdClass;
26
use core_reportbuilder\local\entities\base;
27
use core_reportbuilder\local\helpers\format;
28
use core_reportbuilder\local\filters\{boolean_select, date, filesize, select, text};
29
use core_reportbuilder\local\report\{column, filter};
30
 
31
/**
32
 * File entity
33
 *
34
 * @package     core_files
35
 * @copyright   2022 Paul Holden <paulh@moodle.com>
36
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37
 */
38
class file extends base {
39
 
40
    /**
41
     * Database tables that this entity uses
42
     *
43
     * @return string[]
44
     */
45
    protected function get_default_tables(): array {
46
        return [
47
            'files',
1441 ariadna 48
        ];
49
    }
50
 
51
    /**
52
     * Database tables that this entity no longer uses
53
     *
54
     * @return string[]
55
     */
56
    protected function get_deprecated_tables(): array {
57
        return [
1 efrain 58
            'context',
59
        ];
60
    }
61
 
62
    /**
63
     * The default title for this entity
64
     *
65
     * @return lang_string
66
     */
67
    protected function get_default_entity_title(): lang_string {
68
        return new lang_string('file');
69
    }
70
 
71
    /**
72
     * Initialise the entity
73
     *
74
     * @return base
75
     */
76
    public function initialise(): base {
77
        $columns = $this->get_all_columns();
78
        foreach ($columns as $column) {
79
            $this->add_column($column);
80
        }
81
 
82
        // All the filters defined by the entity can also be used as conditions.
83
        $filters = $this->get_all_filters();
84
        foreach ($filters as $filter) {
85
            $this
86
                ->add_filter($filter)
87
                ->add_condition($filter);
88
        }
89
 
90
        return $this;
91
    }
92
 
93
    /**
94
     * Returns list of all available columns
95
     *
96
     * @return column[]
97
     */
98
    protected function get_all_columns(): array {
99
        $filesalias = $this->get_table_alias('files');
100
 
101
        // Name.
102
        $columns[] = (new column(
103
            'name',
104
            new lang_string('filename', 'core_repository'),
105
            $this->get_entity_name()
106
        ))
107
            ->add_joins($this->get_joins())
108
            ->set_type(column::TYPE_TEXT)
109
            ->add_field("{$filesalias}.filename")
110
            ->set_is_sortable(true);
111
 
112
        // Size.
113
        $columns[] = (new column(
114
            'size',
115
            new lang_string('size'),
116
            $this->get_entity_name()
117
        ))
118
            ->add_joins($this->get_joins())
119
            ->set_type(column::TYPE_INTEGER)
120
            ->add_field("{$filesalias}.filesize")
121
            ->add_field("CASE WHEN {$filesalias}.filename = '.' THEN 1 ELSE 0 END", 'directory')
122
            ->set_is_sortable(true)
123
            ->add_callback(static function($filesize, stdClass $fileinfo): string {
124
                // Absent file size and/or directory should not return output.
125
                if ($fileinfo->filesize === null || $fileinfo->directory) {
126
                    return '';
127
                }
128
                return display_size($fileinfo->filesize);
129
            });
130
 
131
        // Path.
132
        $columns[] = (new column(
133
            'path',
134
            new lang_string('path'),
135
            $this->get_entity_name()
136
        ))
137
            ->add_joins($this->get_joins())
138
            ->set_type(column::TYPE_TEXT)
139
            ->add_field("{$filesalias}.filepath")
140
            ->set_is_sortable(true);
141
 
142
        // Type.
143
        $columns[] = (new column(
144
            'type',
145
            new lang_string('type', 'core_repository'),
146
            $this->get_entity_name()
147
        ))
148
            ->add_joins($this->get_joins())
149
            ->set_type(column::TYPE_TEXT)
150
            ->add_field("{$filesalias}.mimetype")
151
            ->add_field("CASE WHEN {$filesalias}.filename = '.' THEN 1 ELSE 0 END", 'directory')
152
            ->set_is_sortable(true)
153
            ->add_callback(static function($mimetype, stdClass $fileinfo): string {
154
                global $CFG;
155
                require_once("{$CFG->libdir}/filelib.php");
156
 
157
                // Absent mime type and/or directory has pre-determined output.
158
                if ($fileinfo->mimetype === null && !$fileinfo->directory) {
159
                    return '';
160
                } else if ($fileinfo->directory) {
161
                    return get_string('directory');
162
                }
163
 
164
                return get_mimetype_description($fileinfo->mimetype);
165
            });
166
 
167
        // Icon.
168
        $columns[] = (new column(
169
            'icon',
170
            new lang_string('icon'),
171
            $this->get_entity_name()
172
        ))
173
            ->add_joins($this->get_joins())
174
            ->set_type(column::TYPE_TEXT)
175
            ->add_field("{$filesalias}.mimetype")
176
            ->add_field("CASE WHEN {$filesalias}.filename = '.' THEN 1 ELSE 0 END", 'directory')
177
            ->set_disabled_aggregation_all()
178
            ->add_callback(static function($mimetype, stdClass $fileinfo): string {
179
                global $CFG, $OUTPUT;
180
                require_once("{$CFG->libdir}/filelib.php");
181
 
182
                if ($fileinfo->mimetype === null && !$fileinfo->directory) {
183
                    return '';
184
                }
185
 
186
                if ($fileinfo->directory) {
187
                    $icon = file_folder_icon();
188
                    $description = get_string('directory');
189
                } else {
190
                    $icon = file_file_icon($fileinfo);
191
                    $description = get_mimetype_description($fileinfo->mimetype);
192
                }
193
 
194
                return $OUTPUT->pix_icon($icon, $description, 'moodle', ['class' => 'iconsize-medium']);
195
            });
196
 
197
        // Author.
198
        $columns[] = (new column(
199
            'author',
200
            new lang_string('author', 'core_repository'),
201
            $this->get_entity_name()
202
        ))
203
            ->add_joins($this->get_joins())
204
            ->set_type(column::TYPE_TEXT)
205
            ->add_field("{$filesalias}.author")
206
            ->set_is_sortable(true);
207
 
208
        // License.
209
        $columns[] = (new column(
210
            'license',
211
            new lang_string('license', 'core_repository'),
212
            $this->get_entity_name()
213
        ))
214
            ->add_joins($this->get_joins())
215
            ->set_type(column::TYPE_TEXT)
216
            ->add_field("{$filesalias}.license")
217
            ->set_is_sortable(true)
218
            ->add_callback(static function(?string $license): string {
219
                global $CFG;
220
                require_once("{$CFG->libdir}/licenselib.php");
221
 
222
                $licenses = license_manager::get_licenses();
223
                if ($license === null || !array_key_exists($license, $licenses)) {
224
                    return '';
225
                }
226
                return $licenses[$license]->fullname;
227
            });
228
 
229
        // Content hash.
230
        $columns[] = (new column(
231
             'contenthash',
232
            new lang_string('contenthash', 'core_files'),
233
            $this->get_entity_name()
234
        ))
235
            ->add_joins($this->get_joins())
236
            ->set_type(column::TYPE_TEXT)
237
            ->add_field("{$filesalias}.contenthash")
238
            ->set_is_sortable(true);
239
 
240
        // Component.
241
        $columns[] = (new column(
242
            'component',
243
            new lang_string('plugin'),
244
            $this->get_entity_name()
245
        ))
246
            ->add_joins($this->get_joins())
247
            ->set_type(column::TYPE_TEXT)
248
            ->add_fields("{$filesalias}.component")
249
            ->set_is_sortable(true);
250
 
251
        // Area.
252
        $columns[] = (new column(
253
            'area',
254
            new lang_string('pluginarea'),
255
            $this->get_entity_name()
256
        ))
257
            ->add_joins($this->get_joins())
258
            ->set_type(column::TYPE_TEXT)
259
            ->add_fields("{$filesalias}.filearea")
260
            ->set_is_sortable(true);
261
 
262
        // Item ID.
263
        $columns[] = (new column(
264
            'itemid',
265
            new lang_string('pluginitemid'),
266
            $this->get_entity_name()
267
        ))
268
            ->add_joins($this->get_joins())
269
            ->add_fields("{$filesalias}.itemid")
1441 ariadna 270
            ->set_is_sortable(true);
1 efrain 271
 
272
        // Time created.
273
        $columns[] = (new column(
274
            'timecreated',
275
            new lang_string('timecreated', 'core_reportbuilder'),
276
            $this->get_entity_name()
277
        ))
278
            ->add_joins($this->get_joins())
279
            ->set_type(column::TYPE_TIMESTAMP)
280
            ->add_field("{$filesalias}.timecreated")
281
            ->add_callback([format::class, 'userdate'])
282
            ->set_is_sortable(true);
283
 
284
        return $columns;
285
    }
286
 
287
    /**
288
     * Return list of all available filters
289
     *
290
     * @return filter[]
291
     */
292
    protected function get_all_filters(): array {
293
        $filesalias = $this->get_table_alias('files');
294
 
295
        // Directory.
296
        $filters[] = (new filter(
297
            boolean_select::class,
298
            'directory',
299
            new lang_string('directory'),
300
            $this->get_entity_name(),
301
            "CASE WHEN {$filesalias}.filename = '.' THEN 1 ELSE 0 END"
302
        ))
303
            ->add_joins($this->get_joins());
304
 
305
        // Draft.
306
        $filters[] = (new filter(
307
            boolean_select::class,
308
            'draft',
309
            new lang_string('areauserdraft', 'core_repository'),
310
            $this->get_entity_name(),
311
            "CASE WHEN {$filesalias}.component = 'user' AND {$filesalias}.filearea = 'draft' THEN 1 ELSE 0 END"
312
        ))
313
            ->add_joins($this->get_joins());
314
 
315
        // Name.
316
        $filters[] = (new filter(
317
            text::class,
318
            'name',
319
            new lang_string('filename', 'core_repository'),
320
            $this->get_entity_name(),
321
            "{$filesalias}.filename"
322
        ))
323
            ->add_joins($this->get_joins());
324
 
325
        // Size.
326
        $filters[] = (new filter(
327
            filesize::class,
328
            'size',
329
            new lang_string('size'),
330
            $this->get_entity_name(),
331
            "{$filesalias}.filesize"
332
        ))
333
            ->add_joins($this->get_joins());
334
 
335
        // Type.
336
        $filters[] = (new filter(
337
            select::class,
338
            'type',
339
            new lang_string('type', 'core_repository'),
340
            $this->get_entity_name(),
341
            "{$filesalias}.mimetype"
342
        ))
343
            ->add_joins($this->get_joins())
344
            ->set_options_callback(static function(): array {
345
                $mimetypenames = array_column(core_filetypes::get_types(), 'type');
346
 
347
                // Convert the names into a map of name => description.
348
                $mimetypes = array_combine($mimetypenames, array_map(static function(string $mimetype): string {
349
                    return get_mimetype_description($mimetype);
350
                }, $mimetypenames));
351
 
352
                core_collator::asort($mimetypes);
353
                return $mimetypes;
354
            });
355
 
1441 ariadna 356
        // Author.
357
        $filters[] = (new filter(
358
            text::class,
359
            'author',
360
            new lang_string('author', 'core_repository'),
361
            $this->get_entity_name(),
362
            "{$filesalias}.author"
363
        ))
364
            ->add_joins($this->get_joins());
365
 
1 efrain 366
        // License (consider null = 'unknown/license not specified' for filtering purposes).
367
        $filters[] = (new filter(
368
            select::class,
369
            'license',
370
            new lang_string('license', 'core_repository'),
371
            $this->get_entity_name(),
372
            "COALESCE({$filesalias}.license, 'unknown')"
373
        ))
374
            ->add_joins($this->get_joins())
375
            ->set_options_callback(static function(): array {
376
                global $CFG;
377
                require_once("{$CFG->libdir}/licenselib.php");
378
 
379
                $licenses = license_manager::get_licenses();
380
 
381
                return array_map(static function(stdClass $license): string {
382
                    return $license->fullname;
383
                }, $licenses);
384
            });
385
 
386
        // Content hash.
387
        $filters[] = (new filter(
388
            text::class,
389
            'contenthash',
390
            new lang_string('contenthash', 'core_files'),
391
            $this->get_entity_name(),
392
            "{$filesalias}.contenthash"
393
        ))
394
            ->add_joins($this->get_joins());
395
 
1441 ariadna 396
        // Component.
397
        $filters[] = (new filter(
398
            text::class,
399
            'component',
400
            new lang_string('plugin'),
401
            $this->get_entity_name(),
402
            "{$filesalias}.component"
403
        ))
404
            ->add_joins($this->get_joins());
405
 
406
        // Area.
407
        $filters[] = (new filter(
408
            text::class,
409
            'area',
410
            new lang_string('pluginarea'),
411
            $this->get_entity_name(),
412
            "{$filesalias}.filearea"
413
        ))
414
            ->add_joins($this->get_joins());
415
 
1 efrain 416
        // Time created.
417
        $filters[] = (new filter(
418
            date::class,
419
            'timecreated',
420
            new lang_string('timecreated', 'core_reportbuilder'),
421
            $this->get_entity_name(),
422
            "{$filesalias}.timecreated"
423
        ))
424
            ->add_joins($this->get_joins())
425
            ->set_limited_operators([
426
                date::DATE_ANY,
427
                date::DATE_RANGE,
428
                date::DATE_LAST,
429
                date::DATE_CURRENT,
430
            ]);
431
 
432
        return $filters;
433
    }
434
}