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
declare(strict_types=1);
18
 
19
namespace core_badges\reportbuilder\local\entities;
20
 
21
use context_course;
22
use context_helper;
23
use context_system;
24
use html_writer;
25
use lang_string;
26
use moodle_url;
27
use stdClass;
28
use core_reportbuilder\local\entities\base;
29
use core_reportbuilder\local\filters\{date, select, text};
30
use core_reportbuilder\local\helpers\database;
31
use core_reportbuilder\local\report\{column, filter};
32
 
33
defined('MOODLE_INTERNAL') or die;
34
 
35
global $CFG;
36
require_once("{$CFG->libdir}/badgeslib.php");
37
 
38
/**
39
 * Badge entity
40
 *
41
 * @package     core_badges
42
 * @copyright   2022 Paul Holden <paulh@moodle.com>
43
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
44
 */
45
class badge extends base {
46
 
47
    /**
48
     * Database tables that this entity uses
49
     *
50
     * @return string[]
51
     */
52
    protected function get_default_tables(): array {
53
        return [
54
            'badge',
55
            'context',
56
            'tag_instance',
57
            'tag',
58
        ];
59
    }
60
 
61
    /**
62
     * The default title for this entity
63
     *
64
     * @return lang_string
65
     */
66
    protected function get_default_entity_title(): lang_string {
67
        return new lang_string('badgedetails', 'core_badges');
68
    }
69
 
70
    /**
71
     * Initialise the entity
72
     *
73
     * @return base
74
     */
75
    public function initialise(): base {
76
        $columns = $this->get_all_columns();
77
        foreach ($columns as $column) {
78
            $this->add_column($column);
79
        }
80
 
81
        // All the filters defined by the entity can also be used as conditions.
82
        $filters = $this->get_all_filters();
83
        foreach ($filters as $filter) {
84
            $this
85
                ->add_filter($filter)
86
                ->add_condition($filter);
87
        }
88
 
89
        return $this;
90
    }
91
 
92
    /**
93
     * Returns list of all available columns
94
     *
95
     * @return column[]
96
     */
97
    protected function get_all_columns(): array {
98
        global $DB;
99
 
100
        $badgealias = $this->get_table_alias('badge');
101
        $contextalias = $this->get_table_alias('context');
102
 
103
        // Name.
104
        $columns[] = (new column(
105
            'name',
106
            new lang_string('name'),
107
            $this->get_entity_name()
108
        ))
109
            ->add_joins($this->get_joins())
110
            ->set_type(column::TYPE_TEXT)
111
            ->add_field("{$badgealias}.name")
112
            ->set_is_sortable(true);
113
 
114
        // Name with link.
115
        $columns[] = (new column(
116
            'namewithlink',
117
            new lang_string('namewithlink', 'core_badges'),
118
            $this->get_entity_name()
119
        ))
120
            ->add_joins($this->get_joins())
121
            ->set_type(column::TYPE_TEXT)
122
            ->add_fields("{$badgealias}.name, {$badgealias}.id")
123
            ->set_is_sortable(true)
124
            ->add_callback(static function(?string $value, stdClass $row): string {
125
                if (!$row->id) {
126
                    return '';
127
                }
128
 
129
                $url = new moodle_url('/badges/overview.php', ['id' => $row->id]);
130
                return html_writer::link($url, $row->name);
131
            });
132
 
133
        // Description (note, this column contains plaintext so requires no post-processing).
134
        $descriptionfieldsql = "{$badgealias}.description";
135
        if ($DB->get_dbfamily() === 'oracle') {
136
            $descriptionfieldsql = $DB->sql_order_by_text($descriptionfieldsql, 1024);
137
        }
138
        $columns[] = (new column(
139
            'description',
140
            new lang_string('description', 'core_badges'),
141
            $this->get_entity_name()
142
        ))
143
            ->add_joins($this->get_joins())
144
            ->set_type(column::TYPE_LONGTEXT)
145
            ->add_field($descriptionfieldsql, 'description');
146
 
147
        // Criteria.
148
        $columns[] = (new column(
149
            'criteria',
150
            new lang_string('bcriteria', 'core_badges'),
151
            $this->get_entity_name()
152
        ))
153
            ->add_joins($this->get_joins())
154
            ->set_type(column::TYPE_TEXT)
155
            ->add_field("{$badgealias}.id")
156
            ->set_disabled_aggregation_all()
157
            ->add_callback(static function($badgeid): string {
158
                global $PAGE;
159
                if (!$badgeid) {
160
                    return '';
161
                }
162
                $badge = new \core_badges\badge($badgeid);
163
 
164
                $renderer = $PAGE->get_renderer('core_badges');
165
                return $renderer->print_badge_criteria($badge, 'short');
166
            });
167
 
168
        // Image.
169
        $columns[] = (new column(
170
            'image',
171
            new lang_string('badgeimage', 'core_badges'),
172
            $this->get_entity_name()
173
        ))
174
            ->add_joins($this->get_joins())
175
            ->add_join("LEFT JOIN {context} {$contextalias}
176
                    ON {$contextalias}.contextlevel = " . CONTEXT_COURSE . "
177
                   AND {$contextalias}.instanceid = {$badgealias}.courseid")
178
            ->set_type(column::TYPE_INTEGER)
179
            ->add_fields("{$badgealias}.id, {$badgealias}.type, {$badgealias}.courseid")
180
            ->add_field($DB->sql_cast_to_char("{$badgealias}.imagecaption"), 'imagecaption')
181
            ->add_fields(context_helper::get_preload_record_columns_sql($contextalias))
182
            ->set_disabled_aggregation_all()
183
            ->add_callback(static function(?int $badgeid, stdClass $badge): string {
184
                if (!$badgeid) {
185
                    return '';
186
                }
187
                if ($badge->type == BADGE_TYPE_SITE) {
188
                    $context = context_system::instance();
189
                } else {
190
                    context_helper::preload_from_record($badge);
191
                    $context = context_course::instance($badge->courseid);
192
                }
193
 
194
                $badgeimage = moodle_url::make_pluginfile_url($context->id, 'badges', 'badgeimage', $badgeid, '/', 'f2');
195
                return html_writer::img($badgeimage, $badge->imagecaption);
196
            });
197
 
198
        // Language.
199
        $columns[] = (new column(
200
            'language',
201
            new lang_string('language'),
202
            $this->get_entity_name()
203
        ))
204
            ->add_joins($this->get_joins())
205
            ->set_type(column::TYPE_TEXT)
206
            ->add_field("{$badgealias}.language")
207
            ->set_is_sortable(true)
208
            ->add_callback(static function($language): string {
209
                $languages = get_string_manager()->get_list_of_languages();
210
                return $languages[$language] ?? $language ?? '';
211
            });
212
 
213
        // Version.
214
        $columns[] = (new column(
215
            'version',
216
            new lang_string('version', 'core_badges'),
217
            $this->get_entity_name()
218
        ))
219
            ->add_joins($this->get_joins())
220
            ->set_type(column::TYPE_TEXT)
221
            ->add_field("{$badgealias}.version")
222
            ->set_is_sortable(true);
223
 
224
        // Status.
225
        $columns[] = (new column(
226
            'status',
227
            new lang_string('status', 'core_badges'),
228
            $this->get_entity_name()
229
        ))
230
            ->add_joins($this->get_joins())
231
            ->set_type(column::TYPE_TEXT)
232
            ->add_field("{$badgealias}.status")
233
            ->set_is_sortable(true)
234
            ->add_callback(static function($status): string {
235
                if ($status === null) {
236
                    return '';
237
                }
238
 
239
                return get_string("badgestatus_{$status}", 'core_badges');
240
            });
241
 
242
        // Expiry date/period.
243
        $columns[] = (new column(
244
            'expiry',
245
            new lang_string('expirydate', 'core_badges'),
246
            $this->get_entity_name()
247
        ))
248
            ->add_joins($this->get_joins())
249
            ->set_type(column::TYPE_TIMESTAMP)
250
            ->add_fields("{$badgealias}.expiredate, {$badgealias}.expireperiod, {$badgealias}.id")
251
            ->set_is_sortable(true, ["{$badgealias}.expiredate", "{$badgealias}.expireperiod"])
252
            ->set_disabled_aggregation_all()
253
            ->add_callback(static function(?int $expiredate, stdClass $badge): string {
254
                if (!$badge->id) {
255
                    return '';
256
                } else if ($expiredate) {
257
                    return userdate($expiredate);
258
                } else if ($badge->expireperiod) {
259
                    return format_time($badge->expireperiod);
260
                } else {
261
                    return get_string('never', 'core_badges');
262
                }
263
            });
264
 
265
        // Image author details.
266
        foreach (['imageauthorname', 'imageauthoremail', 'imageauthorurl'] as $imageauthorfield) {
267
            $columns[] = (new column(
268
                $imageauthorfield,
269
                new lang_string($imageauthorfield, 'core_badges'),
270
                $this->get_entity_name()
271
            ))
272
                ->add_joins($this->get_joins())
273
                ->set_type(column::TYPE_TEXT)
274
                ->add_field("{$badgealias}.{$imageauthorfield}")
275
                ->set_is_sortable(true);
276
        }
277
 
278
        return $columns;
279
    }
280
 
281
    /**
282
     * Return list of all available filters
283
     *
284
     * @return filter[]
285
     */
286
    protected function get_all_filters(): array {
287
        global $DB;
288
 
289
        $badgealias = $this->get_table_alias('badge');
290
 
291
        // Name.
292
        $filters[] = (new filter(
293
            text::class,
294
            'name',
295
            new lang_string('name'),
296
            $this->get_entity_name(),
297
            "{$badgealias}.name"
298
        ))
299
            ->add_joins($this->get_joins());
300
 
301
        // Version.
302
        $filters[] = (new filter(
303
            text::class,
304
            'version',
305
            new lang_string('version', 'core_badges'),
306
            $this->get_entity_name(),
307
            "{$badgealias}.version"
308
        ))
309
            ->add_joins($this->get_joins());
310
 
311
        // Status.
312
        $filters[] = (new filter(
313
            select::class,
314
            'status',
315
            new lang_string('status', 'core_badges'),
316
            $this->get_entity_name(),
317
            "{$badgealias}.status"
318
        ))
319
            ->add_joins($this->get_joins())
320
            ->set_options([
321
                BADGE_STATUS_INACTIVE => new lang_string('badgestatus_0', 'core_badges'),
322
                BADGE_STATUS_ACTIVE => new lang_string('badgestatus_1', 'core_badges'),
323
                BADGE_STATUS_INACTIVE_LOCKED => new lang_string('badgestatus_2', 'core_badges'),
324
                BADGE_STATUS_ACTIVE_LOCKED => new lang_string('badgestatus_3', 'core_badges'),
325
                BADGE_STATUS_ARCHIVED => new lang_string('badgestatus_4', 'core_badges'),
326
            ]);
327
 
328
        // Expiry date/period.
329
        [$parammaxint, $paramtime] = database::generate_param_names(2);
330
        $filters[] = (new filter(
331
            date::class,
332
            'expiry',
333
            new lang_string('expirydate', 'core_badges'),
334
            $this->get_entity_name(),
335
            "CASE WHEN {$badgealias}.expiredate IS NULL AND {$badgealias}.expireperiod IS NULL
336
                  THEN " . $DB->sql_cast_char2int(":{$parammaxint}") . "
337
                  ELSE COALESCE({$badgealias}.expiredate, {$badgealias}.expireperiod + :{$paramtime})
338
             END",
339
            [$parammaxint => 2147483647, $paramtime => time()]
340
        ))
341
            ->add_joins($this->get_joins())
342
            ->set_limited_operators([
343
                date::DATE_ANY,
344
                date::DATE_RANGE,
345
                date::DATE_LAST,
346
                date::DATE_CURRENT,
347
                date::DATE_NEXT,
348
                date::DATE_PAST,
349
                date::DATE_FUTURE,
350
            ]);
351
 
352
        // Type.
353
        $filters[] = (new filter(
354
            select::class,
355
            'type',
356
            new lang_string('type', 'core_badges'),
357
            $this->get_entity_name(),
358
            "{$badgealias}.type"
359
        ))
360
            ->add_joins($this->get_joins())
361
            ->set_options([
362
                BADGE_TYPE_SITE => new lang_string('site'),
363
                BADGE_TYPE_COURSE => new lang_string('course'),
364
            ]);
365
 
366
        return $filters;
367
    }
368
 
369
    /**
370
     * Return joins necessary for retrieving tags
371
     *
372
     * @return string[]
373
     */
374
    public function get_tag_joins(): array {
375
        return $this->get_tag_joins_for_entity('core_badges', 'badge', $this->get_table_alias('badge') . '.id');
376
    }
377
}