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 - https://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 <https://www.gnu.org/licenses/>.
16
 
17
namespace tool_courserating\reportbuilder\local\entities;
18
 
19
use core_reportbuilder\local\entities\base;
20
use core_reportbuilder\local\helpers\database;
21
use lang_string;
22
use core_reportbuilder\local\report\column;
23
use stdClass;
24
use core_reportbuilder\local\helpers\format;
25
use core_reportbuilder\local\report\filter;
26
use core_reportbuilder\local\filters\number;
27
use core_reportbuilder\local\filters\text;
28
use core_reportbuilder\local\filters\boolean_select;
29
use core_reportbuilder\local\filters\date;
30
use tool_courserating\helper;
31
use tool_courserating\permission;
32
 
33
/**
34
 * Reportbuilder entity representing table tool_courserating_rating.
35
 *
36
 * @package     tool_courserating
37
 * @copyright   2022 Marina Glancy
38
 * @license     https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39
 */
40
class rating extends base {
41
    /**
42
     * Database tables that this entity uses and their default aliases
43
     *
44
     * @return array
45
     */
46
    protected function get_default_table_aliases(): array {
47
        return ['tool_courserating_rating' => 'tool_courserating_rating'];
48
    }
49
 
50
    /**
51
     * Database tables that this entity uses
52
     *
53
     * @return string[]
54
     */
55
    protected function get_default_tables(): array {
56
        return array_keys($this->get_default_table_aliases());
57
    }
58
 
59
    /**
60
     * The default title for this entity
61
     *
62
     * @return lang_string
63
     */
64
    protected function get_default_entity_title(): lang_string {
65
        return new lang_string('entity_rating', 'tool_courserating');
66
    }
67
 
68
    /**
69
     * Initialise the entity
70
     *
71
     * @return base
72
     */
73
    public function initialise(): base {
74
        $columns = $this->get_all_columns();
75
        foreach ($columns as $column) {
76
            $this->add_column($column);
77
        }
78
 
79
        // All the filters defined by the entity can also be used as conditions.
80
        $filters = $this->get_all_filters();
81
        foreach ($filters as $filter) {
82
            $this
83
                ->add_filter($filter)
84
                ->add_condition($filter);
85
        }
86
 
87
        return $this;
88
    }
89
 
90
    /**
91
     * Returns list of all available columns
92
     *
93
     * @return column[]
94
     */
95
    protected function get_all_columns(): array {
96
        global $DB;
97
        $tablealias = $this->get_table_alias('tool_courserating_rating');
98
        $columns = [];
99
 
100
        // Rating column.
101
        $columns[] = (new column(
102
            'rating',
103
            new lang_string('rating_rating', 'tool_courserating'),
104
            $this->get_entity_name()
105
        ))
106
            ->add_joins($this->get_joins())
107
            ->set_type(column::TYPE_INTEGER)
108
            ->add_fields("{$tablealias}.rating, {$tablealias}.id")
109
            ->set_is_sortable(true)
110
            ->set_callback(static function($rating, $row) {
111
                // TODO MDL-76199 not currently possible to set custom callbacks for AVG() that should display float.
112
                if (empty($row->id)) {
113
                    // This is aggregation - display as float, it works for AVG but not for MIN/MAX/SUM unfortunately.
114
                    return helper::format_avgrating($row->rating);
115
                } else {
116
                    // This is a non-aggregated value - display as integer.
117
                    return $rating ?? '';
118
                }
119
            });
120
 
121
        // Rating column.
122
        $columns[] = (new column(
123
            'stars',
124
            new lang_string('ratingasstars', 'tool_courserating'),
125
            $this->get_entity_name()
126
        ))
127
            ->add_joins($this->get_joins())
128
            ->set_type(column::TYPE_FLOAT) // TODO MDL-76199 this is actually integer but otherwise AVG aggregation rounds it.
129
            ->add_fields("{$tablealias}.rating")
130
            ->set_disabled_aggregation(['sum']) // Not possible to set different callback to SUM(), so we have to disable it.
131
            ->set_is_sortable(true)
132
            ->add_callback(static function($avgrating, $r) {
133
                return helper::stars((float)$avgrating);
134
            });
135
 
136
        // Review column.
137
        $reviewfield = "{$tablealias}.review";
138
        if ($DB->get_dbfamily() === 'oracle') {
139
            $reviewfield = $DB->sql_order_by_text($reviewfield, 1024);
140
        }
141
        $columns[] = (new column(
142
            'review',
143
            new lang_string('rating_review', 'tool_courserating'),
144
            $this->get_entity_name()
145
        ))
146
            ->add_joins($this->get_joins())
147
            ->set_type(column::TYPE_LONGTEXT)
148
            ->add_field("{$reviewfield}", 'review')
149
            ->add_fields("{$tablealias}.id, {$tablealias}.courseid")
150
            ->set_callback([helper::class, 'format_review']);
151
 
152
        // Hasreview column.
153
        $columns[] = (new column(
154
            'hasreview',
155
            new lang_string('rating_hasreview', 'tool_courserating'),
156
            $this->get_entity_name()
157
        ))
158
            ->add_joins($this->get_joins())
159
            ->set_type(column::TYPE_BOOLEAN)
160
            ->add_fields("{$tablealias}.hasreview")
161
            ->set_is_sortable(true)
162
            ->add_callback(static function($value, stdClass $row): ?string {
163
                return is_null($value) ? null : format::boolean_as_text((int)$value);
164
            });
165
 
166
        // Timecreated column.
167
        $columns[] = (new column(
168
            'timecreated',
169
            new lang_string('rating_timecreated', 'tool_courserating'),
170
            $this->get_entity_name()
171
        ))
172
            ->add_joins($this->get_joins())
173
            ->set_type(column::TYPE_TIMESTAMP)
174
            ->add_fields("{$tablealias}.timecreated")
175
            ->set_is_sortable(true)
176
            ->add_callback([helper::class, 'format_date']);
177
 
178
        // Timemodified column.
179
        $columns[] = (new column(
180
            'timemodified',
181
            new lang_string('rating_timemodified', 'tool_courserating'),
182
            $this->get_entity_name()
183
        ))
184
            ->add_joins($this->get_joins())
185
            ->set_type(column::TYPE_TIMESTAMP)
186
            ->add_fields("{$tablealias}.timemodified")
187
            ->set_is_sortable(true)
188
            ->add_callback([helper::class, 'format_date']);
189
 
190
        // Number of flags column.
191
        $a = database::generate_alias();
192
        $column = (new column(
193
            'flags',
194
            new lang_string('rating_nofflags', 'tool_courserating'),
195
            $this->get_entity_name()
196
        ))
197
            ->add_joins($this->get_joins())
198
            ->set_type(column::TYPE_INTEGER)
199
            ->add_field("(SELECT count(1) FROM {tool_courserating_flag} {$a} WHERE {$a}.ratingid = {$tablealias}.id)", 'flags')
200
            ->set_is_sortable(true);
201
        if (in_array($DB->get_dbfamily(), ['mssql', 'oracle'])) {
202
            $column->set_disabled_aggregation(['avg', 'groupconcat', 'count', 'countdistinct',
203
                'groupconcatdistinct', 'max', 'min', 'sum', ]);
204
            $column->set_groupby_sql("{$tablealias}.id");
205
        }
206
        $columns[] = $column;
207
 
208
        // Actions column.
209
        $columns[] = (new column(
210
            'actions',
211
            new lang_string('rating_actions', 'tool_courserating'),
212
            $this->get_entity_name()
213
        ))
214
            ->add_joins($this->get_joins())
215
            ->set_type(column::TYPE_TEXT)
216
            ->add_fields("{$tablealias}.id, {$tablealias}.courseid")
217
            ->set_disabled_aggregation_all()
218
            ->set_callback([helper::class, 'format_actions']);
219
 
220
        return $columns;
221
    }
222
 
223
    /**
224
     * Return list of all available filters
225
     *
226
     * @return filter[]
227
     */
228
    protected function get_all_filters(): array {
229
        $tablealias = $this->get_table_alias('tool_courserating_rating');
230
        $filters = [];
231
 
232
        // Rating filter.
233
        $filters[] = (new filter(
234
            number::class,
235
            'rating',
236
            new lang_string('rating_rating', 'tool_courserating'),
237
            $this->get_entity_name(),
238
            "{$tablealias}.rating"
239
        ))
240
            ->add_joins($this->get_joins());
241
 
242
        // Review filter.
243
        $filters[] = (new filter(
244
            text::class,
245
            'review',
246
            new lang_string('rating_review', 'tool_courserating'),
247
            $this->get_entity_name(),
248
            "{$tablealias}.review"
249
        ))
250
            ->add_joins($this->get_joins());
251
 
252
        // Hasreview filter.
253
        $filters[] = (new filter(
254
            boolean_select::class,
255
            'hasreview',
256
            new lang_string('rating_hasreview', 'tool_courserating'),
257
            $this->get_entity_name(),
258
            "{$tablealias}.hasreview"
259
        ))
260
            ->add_joins($this->get_joins());
261
 
262
        // Timecreated filter.
263
        $filters[] = (new filter(
264
            date::class,
265
            'timecreated',
266
            new lang_string('rating_timecreated', 'tool_courserating'),
267
            $this->get_entity_name(),
268
            "{$tablealias}.timecreated"
269
        ))
270
            ->add_joins($this->get_joins());
271
 
272
        // Timemodified filter.
273
        $filters[] = (new filter(
274
            date::class,
275
            'timemodified',
276
            new lang_string('rating_timemodified', 'tool_courserating'),
277
            $this->get_entity_name(),
278
            "{$tablealias}.timemodified"
279
        ))
280
            ->add_joins($this->get_joins());
281
 
282
        // Number of flags filter.
283
        $a = database::generate_alias();
284
        $filters[] = (new filter(
285
            number::class,
286
            'flags',
287
            new lang_string('rating_nofflags', 'tool_courserating'),
288
            $this->get_entity_name(),
289
            "(SELECT count(1) FROM {tool_courserating_flag} {$a} WHERE {$a}.ratingid = {$tablealias}.id)"
290
        ))
291
            ->add_joins($this->get_joins());
292
 
293
        return $filters;
294
    }
295
}