See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body