Differences Between: [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]
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 moodle_url; 28 use renderable; 29 use renderer_base; 30 use stdClass; 31 use templatable; 32 use forumreport_summary; 33 34 defined('MOODLE_INTERNAL') || die(); 35 36 /** 37 * Forum summary report filters renderable. 38 * 39 * @copyright 2019 Michael Hawkins <michaelh@moodle.com> 40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 41 */ 42 class filters implements renderable, templatable { 43 44 /** 45 * Course modules the report relates to. 46 * Array of stdClass objects 47 * 48 * @var array $cms 49 */ 50 protected $cms; 51 52 /** 53 * Course ID where the report is being generated. 54 * 55 * @var int $courseid 56 */ 57 protected $courseid; 58 59 /** 60 * Moodle URL used as the form action on the generate button. 61 * 62 * @var moodle_url $actionurl 63 */ 64 protected $actionurl; 65 66 /** 67 * Details of groups available for filtering. 68 * Stored in the format groupid => groupname. 69 * 70 * @var array $groupsavailable 71 */ 72 protected $groupsavailable = []; 73 74 /** 75 * IDs of groups selected for filtering. 76 * 77 * @var array $groupsselected 78 */ 79 protected $groupsselected = []; 80 81 /** 82 * IDs of discussions required for export links. 83 * If a subset of groups available are selected, this will include the discussion IDs 84 * within that group in the forum. 85 * If all groups are selected, or no groups mode is enabled, this will be empty as 86 * no discussion filtering is required in the export. 87 * 88 * @var array $discussionids 89 */ 90 protected $discussionids = []; 91 92 /** 93 * HTML for dates filter. 94 * 95 * @var array $datesdata 96 */ 97 protected $datesdata = []; 98 99 /** 100 * Text to display on the dates filter button. 101 * 102 * @var string $datesbuttontext 103 */ 104 protected $datesbuttontext; 105 106 /** 107 * Builds renderable filter data. 108 * 109 * @param stdClass $course The course object. 110 * @param array $cms Array of course module objects. 111 * @param moodle_url $actionurl The form action URL. 112 * @param array $filterdata (optional) Associative array of data that has been set on available filters, if any, 113 * in the format filtertype => [values] 114 */ 115 public function __construct(stdClass $course, array $cms, moodle_url $actionurl, array $filterdata = []) { 116 $this->cms = $cms; 117 $this->courseid = $course->id; 118 $this->actionurl = $actionurl; 119 120 // Prepare groups filter data. 121 $groupsdata = $filterdata['groups'] ?? []; 122 $this->prepare_groups_data($groupsdata); 123 124 // Prepare dates filter data. 125 $datefromdata = $filterdata['datefrom'] ?? []; 126 $datetodata = $filterdata['dateto'] ?? []; 127 $this->prepare_dates_data($datefromdata, $datetodata); 128 } 129 130 /** 131 * Prepares groups data and sets relevant property values. 132 * 133 * @param array $groupsdata Groups selected for filtering. 134 * @return void. 135 */ 136 protected function prepare_groups_data(array $groupsdata): void { 137 global $DB, $USER; 138 139 $groupsavailable = []; 140 $allowedgroupsobj = []; 141 142 $usergroups = groups_get_all_groups($this->courseid, $USER->id); 143 $coursegroups = groups_get_all_groups($this->courseid); 144 $forumids = []; 145 $allgroups = false; 146 $hasgroups = false; 147 148 // Check if any forum gives the user access to all groups and no groups. 149 foreach ($this->cms as $cm) { 150 $forumids[] = $cm->instance; 151 152 // Only need to check for all groups access if not confirmed by a previous check. 153 if (!$allgroups) { 154 $groupmode = groups_get_activity_groupmode($cm); 155 156 // If no groups mode enabled on the forum, nothing to prepare. 157 if (!in_array($groupmode, [VISIBLEGROUPS, SEPARATEGROUPS])) { 158 continue; 159 } 160 161 $hasgroups = true; 162 163 // Fetch for the current cm's forum. 164 $context = \context_module::instance($cm->id); 165 $aag = has_capability('moodle/site:accessallgroups', $context); 166 167 if ($groupmode == VISIBLEGROUPS || $aag) { 168 $allgroups = true; 169 } 170 } 171 } 172 173 // If no groups mode enabled, nothing to prepare. 174 if (!$hasgroups) { 175 return; 176 } 177 178 // Any groups, and no groups. 179 if ($allgroups) { 180 $nogroups = new stdClass(); 181 $nogroups->id = -1; 182 $nogroups->name = get_string('groupsnone'); 183 184 $allowedgroupsobj = $coursegroups + [$nogroups]; 185 } else { 186 $allowedgroupsobj = $usergroups; 187 } 188 189 foreach ($allowedgroupsobj as $group) { 190 $groupsavailable[$group->id] = $group->name; 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