Differences Between: [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 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 * Raw event retrieval strategy. 19 * 20 * @package core_calendar 21 * @copyright 2017 Cameron Ball <cameron@cameron1729.xyz> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace core_calendar\local\event\strategies; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 /** 30 * Raw event retrieval strategy. 31 * 32 * This strategy is based on what used to be the calendar API's get_events function. 33 * 34 * @copyright 2017 Cameron Ball <cameron@cameron1729.xyz> 35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 36 */ 37 class raw_event_retrieval_strategy implements raw_event_retrieval_strategy_interface { 38 39 public function get_raw_events( 40 array $usersfilter = null, 41 array $groupsfilter = null, 42 array $coursesfilter = null, 43 array $categoriesfilter = null, 44 array $whereconditions = null, 45 array $whereparams = null, 46 $ordersql = null, 47 $offset = null, 48 $limitnum = null, 49 $ignorehidden = true 50 ) { 51 return $this->get_raw_events_legacy_implementation( 52 !is_null($usersfilter) ? $usersfilter : true, // True means no filter in old implementation. 53 !is_null($groupsfilter) ? $groupsfilter : true, 54 !is_null($coursesfilter) ? $coursesfilter : true, 55 !is_null($categoriesfilter) ? $categoriesfilter : true, 56 $whereconditions, 57 $whereparams, 58 $ordersql, 59 $offset, 60 $limitnum, 61 $ignorehidden 62 ); 63 } 64 65 /** 66 * The legacy implementation with minor tweaks. 67 * 68 * @param array|int|boolean $users array of users, user id or boolean for all/no user events 69 * @param array|int|boolean $groups array of groups, group id or boolean for all/no group events 70 * @param array|int|boolean $courses array of courses, course id or boolean for all/no course events 71 * @param string $whereconditions The conditions in the WHERE clause. 72 * @param array $whereparams The parameters for the WHERE clause. 73 * @param string $ordersql The ORDER BY clause. 74 * @param int $offset Offset. 75 * @param int $limitnum Limit. 76 * @param boolean $ignorehidden whether to select only visible events or all events 77 * @return array $events of selected events or an empty array if there aren't any (or there was an error) 78 */ 79 protected function get_raw_events_legacy_implementation( 80 $users, 81 $groups, 82 $courses, 83 $categories, 84 $whereconditions, 85 $whereparams, 86 $ordersql, 87 $offset, 88 $limitnum, 89 $ignorehidden 90 ) { 91 global $DB; 92 93 $params = array(); 94 // Quick test. 95 if (empty($users) && empty($groups) && empty($courses) && empty($categories)) { 96 return array(); 97 } 98 99 if (is_numeric($users)) { 100 $users = array($users); 101 } 102 if (is_numeric($groups)) { 103 $groups = array($groups); 104 } 105 if (is_numeric($courses)) { 106 $courses = array($courses); 107 } 108 if (is_numeric($categories)) { 109 $categories = array($categories); 110 } 111 112 // Array of filter conditions. To be concatenated by the OR operator. 113 $filters = []; 114 115 // User filter. 116 if (is_array($users) && !empty($users)) { 117 // Events from a number of users. 118 list($insqlusers, $inparamsusers) = $DB->get_in_or_equal($users, SQL_PARAMS_NAMED); 119 $filters[] = "(e.userid $insqlusers AND e.courseid = 0 AND e.groupid = 0 AND e.categoryid = 0)"; 120 $params = array_merge($params, $inparamsusers); 121 } else if ($users === true) { 122 // Events from ALL users. 123 $filters[] = "(e.userid != 0 AND e.courseid = 0 AND e.groupid = 0 AND e.categoryid = 0)"; 124 } 125 // Boolean false (no users at all): We don't need to do anything. 126 127 // Group filter. 128 if (is_array($groups) && !empty($groups)) { 129 // Events from a number of groups. 130 list($insqlgroups, $inparamsgroups) = $DB->get_in_or_equal($groups, SQL_PARAMS_NAMED); 131 $filters[] = "e.groupid $insqlgroups"; 132 $params = array_merge($params, $inparamsgroups); 133 } else if ($groups === true) { 134 // Events from ALL groups. 135 $filters[] = "e.groupid != 0"; 136 } 137 // Boolean false (no groups at all): We don't need to do anything. 138 139 // Course filter. 140 if (is_array($courses) && !empty($courses)) { 141 list($insqlcourses, $inparamscourses) = $DB->get_in_or_equal($courses, SQL_PARAMS_NAMED); 142 $filters[] = "(e.groupid = 0 AND e.courseid $insqlcourses)"; 143 $params = array_merge($params, $inparamscourses); 144 } else if ($courses === true) { 145 // Events from ALL courses. 146 $filters[] = "(e.groupid = 0 AND e.courseid != 0)"; 147 } 148 149 // Category filter. 150 if (is_array($categories) && !empty($categories)) { 151 list($insqlcategories, $inparamscategories) = $DB->get_in_or_equal($categories, SQL_PARAMS_NAMED); 152 $filters[] = "(e.groupid = 0 AND e.courseid = 0 AND e.categoryid $insqlcategories)"; 153 $params = array_merge($params, $inparamscategories); 154 } else if ($categories === true) { 155 // Events from ALL categories. 156 $filters[] = "(e.groupid = 0 AND e.courseid = 0 AND e.categoryid != 0)"; 157 } 158 159 // Security check: if, by now, we have NOTHING in $whereclause, then it means 160 // that NO event-selecting clauses were defined. Thus, we won't be returning ANY 161 // events no matter what. Allowing the code to proceed might return a completely 162 // valid query with only time constraints, thus selecting ALL events in that time frame! 163 if (empty($filters)) { 164 return array(); 165 } 166 167 // Build our clause for the filters. 168 $filterclause = implode(' OR ', $filters); 169 170 // Array of where conditions for our query. To be concatenated by the AND operator. 171 $whereconditions[] = "($filterclause)"; 172 173 // Show visible only. 174 if ($ignorehidden) { 175 $whereconditions[] = "(e.visible = 1)"; 176 } 177 178 // Build the main query's WHERE clause. 179 $whereclause = implode(' AND ', $whereconditions); 180 181 // Build SQL subquery and conditions for filtered events based on priorities. 182 $subquerywhere = ''; 183 $subqueryconditions = []; 184 $subqueryparams = []; 185 $allusercourses = []; 186 187 if (is_array($users) && !empty($users)) { 188 $userrecords = $DB->get_records_sql("SELECT * FROM {user} WHERE id $insqlusers", $inparamsusers); 189 foreach ($userrecords as $userrecord) { 190 // Get the user's courses. Otherwise, get the default courses being shown by the calendar. 191 $usercourses = calendar_get_default_courses(null, 'id, category, groupmode, groupmodeforce', 192 false, $userrecord->id); 193 194 // Set calendar filters. 195 list($usercourses, $usergroups, $user) = calendar_set_filters($usercourses, true, $userrecord); 196 197 $allusercourses = array_merge($allusercourses, $usercourses); 198 199 // Flag to indicate whether the query needs to exclude group overrides. 200 $viewgroupsonly = false; 201 202 if ($user) { 203 // Set filter condition for the user's events. 204 // Even though $user is a single scalar, we still use get_in_or_equal() because we are inside a loop. 205 list($inusers, $inuserparams) = $DB->get_in_or_equal($user, SQL_PARAMS_NAMED); 206 $subqueryconditions[] = "(ev.userid $inusers AND ev.courseid = 0 AND ev.groupid = 0 AND ev.categoryid = 0)"; 207 $subqueryparams = array_merge($subqueryparams, $inuserparams); 208 209 foreach ($usercourses as $courseid) { 210 if (has_capability('moodle/site:accessallgroups', \context_course::instance($courseid), $userrecord)) { 211 $usergroupmembership = groups_get_all_groups($courseid, $user, 0, 'g.id'); 212 if (count($usergroupmembership) == 0) { 213 $viewgroupsonly = true; 214 break; 215 } 216 } 217 } 218 } 219 220 // Set filter condition for the user's group events. 221 if ($usergroups === true || $viewgroupsonly) { 222 // Fetch group events, but not group overrides. 223 $subqueryconditions[] = "(ev.groupid != 0 AND ev.eventtype = 'group')"; 224 } else if (!empty($usergroups)) { 225 // Fetch group events and group overrides. 226 list($inusergroups, $inusergroupparams) = $DB->get_in_or_equal($usergroups, SQL_PARAMS_NAMED); 227 $subqueryconditions[] = "(ev.groupid $inusergroups)"; 228 $subqueryparams = array_merge($subqueryparams, $inusergroupparams); 229 } 230 } 231 } else if ($users === true) { 232 // Events from ALL users. 233 $subqueryconditions[] = "(ev.userid != 0 AND ev.courseid = 0 AND ev.groupid = 0 AND ev.categoryid = 0)"; 234 235 if (is_array($groups)) { 236 // Events from a number of groups. 237 list($insqlgroups, $inparamsgroups) = $DB->get_in_or_equal($groups, SQL_PARAMS_NAMED); 238 $subqueryconditions[] = "ev.groupid $insqlgroups"; 239 $subqueryparams = array_merge($subqueryparams, $inparamsgroups); 240 } else if ($groups === true) { 241 // Events from ALL groups. 242 $subqueryconditions[] = "ev.groupid != 0"; 243 } 244 245 if ($courses === true) { 246 // ALL course events. It's not needed to worry about users' access as $users = true. 247 $subqueryconditions[] = "(ev.groupid = 0 AND ev.courseid != 0 AND ev.categoryid = 0)"; 248 } 249 } 250 251 // Get courses to be used for the subquery. 252 $subquerycourses = []; 253 if (is_array($courses)) { 254 $subquerycourses = $courses; 255 } 256 // Merge with user courses, if necessary. 257 if (!empty($allusercourses)) { 258 $subquerycourses = array_merge($subquerycourses, $allusercourses); 259 // Make sure we remove duplicate values. 260 $subquerycourses = array_unique($subquerycourses); 261 } 262 263 // Set subquery filter condition for the courses. 264 if (!empty($subquerycourses)) { 265 list($incourses, $incoursesparams) = $DB->get_in_or_equal($subquerycourses, SQL_PARAMS_NAMED); 266 $subqueryconditions[] = "(ev.groupid = 0 AND ev.courseid $incourses AND ev.categoryid = 0)"; 267 $subqueryparams = array_merge($subqueryparams, $incoursesparams); 268 } 269 270 // Set subquery filter condition for the categories. 271 if ($categories === true) { 272 $subqueryconditions[] = "(ev.categoryid != 0 AND ev.eventtype = 'category')"; 273 } else if (!empty($categories)) { 274 list($incategories, $incategoriesparams) = $DB->get_in_or_equal($categories, SQL_PARAMS_NAMED); 275 $subqueryconditions[] = "(ev.groupid = 0 AND ev.courseid = 0 AND ev.categoryid $incategories)"; 276 $subqueryparams = array_merge($subqueryparams, $incategoriesparams); 277 } 278 279 // Build the WHERE condition for the sub-query. 280 if (!empty($subqueryconditions)) { 281 $unionstartquery = "SELECT modulename, instance, eventtype, priority 282 FROM {event} ev 283 WHERE "; 284 $subqueryunion = '('.$unionstartquery . implode(" UNION $unionstartquery ", $subqueryconditions).')'; 285 } else { 286 $subqueryunion = '{event}'; 287 } 288 289 // Merge subquery parameters to the parameters of the main query. 290 if (!empty($subqueryparams)) { 291 $params = array_merge($params, $subqueryparams); 292 } 293 294 // Sub-query that fetches the list of unique events that were filtered based on priority. 295 $subquery = "SELECT ev.modulename, 296 ev.instance, 297 ev.eventtype, 298 MIN(ev.priority) as priority 299 FROM $subqueryunion ev 300 GROUP BY ev.modulename, ev.instance, ev.eventtype"; 301 302 // Build the main query. 303 $sql = "SELECT e.* 304 FROM {event} e 305 INNER JOIN ($subquery) fe 306 ON e.modulename = fe.modulename 307 AND e.instance = fe.instance 308 AND e.eventtype = fe.eventtype 309 AND (e.priority = fe.priority OR (e.priority IS NULL AND fe.priority IS NULL)) 310 LEFT JOIN {modules} m 311 ON e.modulename = m.name 312 WHERE (m.visible = 1 OR m.visible IS NULL) AND $whereclause 313 ORDER BY " . ($ordersql ? $ordersql : "e.timestart"); 314 315 if (!empty($whereparams)) { 316 $params = array_merge($params, $whereparams); 317 } 318 319 $events = $DB->get_records_sql($sql, $params, $offset, $limitnum); 320 321 return $events === false ? [] : $events; 322 } 323 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body