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
/**
18
 * Forum summary report filters renderable.
19
 *
20
 * @package    forumreport_summary
21
 * @copyright  2019 Michael Hawkins <michaelh@moodle.com>
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace forumreport_summary\output;
26
 
27
use context_course;
28
use moodle_url;
29
use renderable;
30
use renderer_base;
31
use stdClass;
32
use templatable;
33
use forumreport_summary;
34
 
35
/**
36
 * Forum summary report filters renderable.
37
 *
38
 * @copyright  2019 Michael Hawkins <michaelh@moodle.com>
39
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40
 */
41
class filters implements renderable, templatable {
42
 
43
    /**
44
     * Course modules the report relates to.
45
     * Array of stdClass objects
46
     *
47
     * @var array $cms
48
     */
49
    protected $cms;
50
 
51
    /**
52
     * Course ID where the report is being generated.
53
     *
54
     * @var int $courseid
55
     */
56
    protected $courseid;
57
 
58
    /**
59
     * Moodle URL used as the form action on the generate button.
60
     *
61
     * @var moodle_url $actionurl
62
     */
63
    protected $actionurl;
64
 
65
    /**
66
     * Details of groups available for filtering.
67
     * Stored in the format groupid => groupname.
68
     *
69
     * @var array $groupsavailable
70
     */
71
    protected $groupsavailable = [];
72
 
73
    /**
74
     * IDs of groups selected for filtering.
75
     *
76
     * @var array $groupsselected
77
     */
78
    protected $groupsselected = [];
79
 
80
    /**
81
     * IDs of discussions required for export links.
82
     * If a subset of groups available are selected, this will include the discussion IDs
83
     * within that group in the forum.
84
     * If all groups are selected, or no groups mode is enabled, this will be empty as
85
     * no discussion filtering is required in the export.
86
     *
87
     * @var array $discussionids
88
     */
89
    protected $discussionids = [];
90
 
91
    /**
92
     * HTML for dates filter.
93
     *
94
     * @var array $datesdata
95
     */
96
    protected $datesdata = [];
97
 
98
    /**
99
     * Text to display on the dates filter button.
100
     *
101
     * @var string $datesbuttontext
102
     */
103
    protected $datesbuttontext;
104
 
105
    /**
106
     * Builds renderable filter data.
107
     *
108
     * @param stdClass $course The course object.
109
     * @param array $cms Array of course module objects.
110
     * @param moodle_url $actionurl The form action URL.
111
     * @param array $filterdata (optional) Associative array of data that has been set on available filters, if any,
112
     *                                     in the format filtertype => [values]
113
     */
114
    public function __construct(stdClass $course, array $cms, moodle_url $actionurl, array $filterdata = []) {
115
        $this->cms = $cms;
116
        $this->courseid = $course->id;
117
        $this->actionurl = $actionurl;
118
 
119
        // Prepare groups filter data.
120
        $groupsdata = $filterdata['groups'] ?? [];
121
        $this->prepare_groups_data($groupsdata);
122
 
123
        // Prepare dates filter data.
124
        $datefromdata = $filterdata['datefrom'] ?? [];
125
        $datetodata = $filterdata['dateto'] ?? [];
126
        $this->prepare_dates_data($datefromdata, $datetodata);
127
    }
128
 
129
    /**
130
     * Prepares groups data and sets relevant property values.
131
     *
132
     * @param array $groupsdata Groups selected for filtering.
133
     * @return void.
134
     */
135
    protected function prepare_groups_data(array $groupsdata): void {
136
        global $DB, $USER;
137
 
138
        $groupsavailable = [];
139
        $allowedgroupsobj = [];
140
 
141
        $usergroups = groups_get_all_groups($this->courseid, $USER->id);
142
        $coursegroups = groups_get_all_groups($this->courseid);
143
        $forumids = [];
144
        $allgroups = false;
145
        $hasgroups = false;
146
 
147
        // Check if any forum gives the user access to all groups and no groups.
148
        foreach ($this->cms as $cm) {
149
            $forumids[] = $cm->instance;
150
 
151
            // Only need to check for all groups access if not confirmed by a previous check.
152
            if (!$allgroups) {
153
                $groupmode = groups_get_activity_groupmode($cm);
154
 
155
                // If no groups mode enabled on the forum, nothing to prepare.
156
                if (!in_array($groupmode, [VISIBLEGROUPS, SEPARATEGROUPS])) {
157
                    continue;
158
                }
159
 
160
                $hasgroups = true;
161
 
162
                // Fetch for the current cm's forum.
163
                $context = \context_module::instance($cm->id);
164
                $aag = has_capability('moodle/site:accessallgroups', $context);
165
 
166
                if ($groupmode == VISIBLEGROUPS || $aag) {
167
                    $allgroups = true;
168
                }
169
            }
170
        }
171
 
172
        // If no groups mode enabled, nothing to prepare.
173
        if (!$hasgroups) {
174
            return;
175
        }
176
 
177
        // Any groups, and no groups.
178
        if ($allgroups) {
179
            $nogroups = new stdClass();
180
            $nogroups->id = -1;
181
            $nogroups->name = get_string('groupsnone');
182
 
183
            $allowedgroupsobj = $coursegroups + [$nogroups];
184
        } else {
185
            $allowedgroupsobj = $usergroups;
186
        }
187
 
188
        $contextcourse = context_course::instance($this->courseid);
189
        foreach ($allowedgroupsobj as $group) {
190
            $groupsavailable[$group->id] = format_string($group->name, true, ['context' => $contextcourse]);
191
        }
192
 
193
        // Set valid groups selected.
194
        $groupsselected = array_intersect($groupsdata, array_keys($groupsavailable));
195
 
196
        // Overwrite groups properties.
197
        $this->groupsavailable = $groupsavailable;
198
        $this->groupsselected = $groupsselected;
199
 
200
        $groupsselectedcount = count($groupsselected);
201
        if ($groupsselectedcount > 0 && $groupsselectedcount < count($groupsavailable)) {
202
            list($forumidin, $forumidparams) = $DB->get_in_or_equal($forumids, SQL_PARAMS_NAMED);
203
            list($groupidin, $groupidparams) = $DB->get_in_or_equal($groupsselected, SQL_PARAMS_NAMED);
204
 
205
            $discussionswhere = "course = :courseid AND forum {$forumidin} AND groupid {$groupidin}";
206
            $discussionsparams = ['courseid' => $this->courseid];
207
            $discussionsparams += $forumidparams + $groupidparams;
208
 
209
            $discussionids = $DB->get_fieldset_select('forum_discussions', 'DISTINCT id', $discussionswhere, $discussionsparams);
210
 
211
            foreach ($discussionids as $discussionid) {
212
                $this->discussionids[] = ['discid' => $discussionid];
213
            }
214
        }
215
    }
216
 
217
    /**
218
     * Prepares from date, to date and button text.
219
     * Empty data will default to a disabled filter with today's date.
220
     *
221
     * @param array $datefromdata From date selected for filtering, and whether the filter is enabled.
222
     * @param array $datetodata To date selected for filtering, and whether the filter is enabled.
223
     * @return void.
224
     */
225
    private function prepare_dates_data(array $datefromdata, array $datetodata): void {
226
        $timezone = \core_date::get_user_timezone_object();
227
        $calendartype = \core_calendar\type_factory::get_calendar_instance();
228
        $timestamptoday = time();
229
        $datetoday  = $calendartype->timestamp_to_date_array($timestamptoday, $timezone);
230
 
231
        // Prepare date/enabled data.
232
        if (empty($datefromdata['enabled'])) {
233
            $fromdate = $datetoday;
234
            $fromtimestamp = $timestamptoday;
235
            $fromenabled = false;
236
        } else {
237
            $fromdate = $calendartype->timestamp_to_date_array($datefromdata['timestamp'], $timezone);
238
            $fromtimestamp = $datefromdata['timestamp'];
239
            $fromenabled = true;
240
        }
241
 
242
        if (empty($datetodata['enabled'])) {
243
            $todate = $datetoday;
244
            $totimestamp = $timestamptoday;
245
            $toenabled = false;
246
        } else {
247
            $todate = $calendartype->timestamp_to_date_array($datetodata['timestamp'], $timezone);
248
            $totimestamp = $datetodata['timestamp'];
249
            $toenabled = true;
250
        }
251
 
252
        $this->datesdata = [
253
            'from' => [
254
                'day'       => $fromdate['mday'],
255
                'month'     => $fromdate['mon'],
256
                'year'      => $fromdate['year'],
257
                'timestamp' => $fromtimestamp,
258
                'enabled'   => $fromenabled,
259
            ],
260
            'to' => [
261
                'day'       => $todate['mday'],
262
                'month'     => $todate['mon'],
263
                'year'      => $todate['year'],
264
                'timestamp' => $totimestamp,
265
                'enabled'   => $toenabled,
266
            ],
267
        ];
268
 
269
        // Prepare button string data.
270
        $displayformat = get_string('strftimedatemonthabbr', 'langconfig');
271
        $fromdatestring = $calendartype->timestamp_to_date_string($fromtimestamp, $displayformat, $timezone, true, true);
272
        $todatestring = $calendartype->timestamp_to_date_string($totimestamp, $displayformat, $timezone, true, true);
273
 
274
        if ($fromenabled && $toenabled) {
275
            $datestrings = [
276
                'datefrom' => $fromdatestring,
277
                'dateto'   => $todatestring,
278
            ];
279
            $this->datesbuttontext = get_string('filter:datesfromto', 'forumreport_summary', $datestrings);
280
        } else if ($fromenabled) {
281
            $this->datesbuttontext = get_string('filter:datesfrom', 'forumreport_summary', $fromdatestring);
282
        } else if ($toenabled) {
283
            $this->datesbuttontext = get_string('filter:datesto', 'forumreport_summary', $todatestring);
284
        } else {
285
            $this->datesbuttontext = get_string('filter:datesname', 'forumreport_summary');
286
        }
287
    }
288
 
289
    /**
290
     * Export data for use as the context of a mustache template.
291
     *
292
     * @param renderer_base $renderer The renderer to be used to display report filters.
293
     * @return array Data in a format compatible with a mustache template.
294
     */
295
    public function export_for_template(renderer_base $renderer): stdClass {
296
        $output = new stdClass();
297
 
298
        // Set formaction URL.
299
        $output->actionurl = $this->actionurl->out(false);
300
 
301
        // Set groups filter data.
302
        if (!empty($this->groupsavailable)) {
303
            $output->hasgroups = true;
304
 
305
            $groupscount = count($this->groupsselected);
306
 
307
            if (count($this->groupsavailable) <= $groupscount) {
308
                $output->filtergroupsname = get_string('filter:groupscountall', 'forumreport_summary');
309
            } else if (!empty($this->groupsselected)) {
310
                $output->filtergroupsname = get_string('filter:groupscountnumber', 'forumreport_summary', $groupscount);
311
            } else {
312
                $output->filtergroupsname = get_string('filter:groupsname', 'forumreport_summary');
313
            }
314
 
315
            // Set groups filter.
316
            $groupsdata = [];
317
 
318
            foreach ($this->groupsavailable as $groupid => $groupname) {
319
                $groupsdata[] = [
320
                    'groupid' => $groupid,
321
                    'groupname' => $groupname,
322
                    'checked' => in_array($groupid, $this->groupsselected),
323
                ];
324
            }
325
 
326
            $output->filtergroups = $groupsdata;
327
        } else {
328
            $output->hasgroups = false;
329
        }
330
 
331
        // Set discussion IDs for use by export links (always included, as it will be empty if not required).
332
        $output->discussionids = $this->discussionids;
333
 
334
        // Set date button and generate dates popover mform.
335
        $datesformdata = [];
336
 
337
        if ($this->datesdata['from']['enabled']) {
338
            $datesformdata['filterdatefrompopover'] = $this->datesdata['from'];
339
        }
340
 
341
        if ($this->datesdata['to']['enabled']) {
342
            $datesformdata['filterdatetopopover'] = $this->datesdata['to'];
343
        }
344
 
345
        $output->filterdatesname = $this->datesbuttontext;
346
        $datesform = new forumreport_summary\form\dates_filter_form();
347
        $datesform->set_data($datesformdata);
348
        $output->filterdatesform = $datesform->render();
349
 
350
         // Set dates filter data within filters form.
351
        $disableddate = [
352
            'day' => '',
353
            'month' => '',
354
            'year' => '',
355
            'enabled' => '0',
356
        ];
357
        $datefromdata = ['type' => 'from'] + ($this->datesdata['from']['enabled'] ? $this->datesdata['from'] : $disableddate);
358
        $datetodata = ['type' => 'to'] + ($this->datesdata['to']['enabled'] ? $this->datesdata['to'] : $disableddate);
359
        $output->filterdatesdata = [$datefromdata, $datetodata];
360
 
361
        return $output;
362
    }
363
}