MDL-34785 performance improvement with big list of courses
[moodle.git] / blocks / course_overview / locallib.php
CommitLineData
83ea0cc1 1<?php
83ea0cc1
AO
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
37b5e8fe
RT
17/**
18 * Helper functions for course_overview block
19 *
20 * @package block_course_overview
21 * @copyright 2012 Adam Olley <adam.olley@netspot.com.au>
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25/**
26 * Display overview for courses
27 *
28 * @param array $courses courses for which overview needs to be shown
29 * @return array html overview
30 */
83ea0cc1 31function block_course_overview_get_overviews($courses) {
83ea0cc1 32 $htmlarray = array();
37b5e8fe 33 if ($modules = get_plugin_list_with_function('mod', 'print_overview')) {
a9881c17
MG
34 // Split courses list into batches with no more than MAX_MODINFO_CACHE_SIZE courses in one batch.
35 // Otherwise we exceed the cache limit in get_fast_modinfo() and rebuild it too often.
36 if (defined('MAX_MODINFO_CACHE_SIZE') && MAX_MODINFO_CACHE_SIZE > 0 && count($courses) > MAX_MODINFO_CACHE_SIZE) {
37 $batches = array_chunk($courses, MAX_MODINFO_CACHE_SIZE, true);
38 } else {
39 $batches = array($courses);
40 }
41 foreach ($batches as $courses) {
42 foreach ($modules as $fname) {
43 $fname($courses, $htmlarray);
44 }
83ea0cc1
AO
45 }
46 }
47 return $htmlarray;
48}
49
37b5e8fe
RT
50/**
51 * Sets user preference for maximum courses to be displayed in course_overview block
52 *
53 * @param int $number maximum courses which should be visible
54 */
83ea0cc1 55function block_course_overview_update_mynumber($number) {
37b5e8fe 56 set_user_preference('course_overview_number_of_courses', $number);
83ea0cc1
AO
57}
58
37b5e8fe
RT
59/**
60 * Sets user course sorting preference in course_overview block
61 *
62 * @param array $sortorder sort order of course
63 */
83ea0cc1 64function block_course_overview_update_myorder($sortorder) {
37b5e8fe 65 set_user_preference('course_overview_course_order', serialize($sortorder));
83ea0cc1
AO
66}
67
37b5e8fe
RT
68/**
69 * Returns shortname of activities in course
70 *
71 * @param int $courseid id of course for which activity shortname is needed
72 * @return string|bool list of child shortname
73 */
83ea0cc1 74function block_course_overview_get_child_shortnames($courseid) {
37b5e8fe
RT
75 global $DB;
76 $ctxselect = context_helper::get_preload_record_columns_sql('ctx');
77 $sql = "SELECT c.id, c.shortname, $ctxselect
78 FROM {enrol} e
79 JOIN {course} c ON (c.id = e.customint1)
80 JOIN {context} ctx ON (ctx.instanceid = e.customint1)
81 WHERE e.courseid = :courseid AND e.enrol = :method AND ctx.contextlevel = :contextlevel ORDER BY e.sortorder";
82 $params = array('method' => 'meta', 'courseid' => $courseid, 'contextlevel' => CONTEXT_COURSE);
83ea0cc1 83
83ea0cc1
AO
84 if ($results = $DB->get_records_sql($sql, $params)) {
85 $shortnames = array();
37b5e8fe 86 // Preload the context we will need it to format the category name shortly.
83ea0cc1 87 foreach ($results as $res) {
37b5e8fe
RT
88 context_helper::preload_from_record($res);
89 $context = context_course::instance($res->id);
90 $shortnames[] = format_string($res->shortname, true, $context);
83ea0cc1
AO
91 }
92 $total = count($shortnames);
93 $suffix = '';
94 if ($total > 10) {
95 $shortnames = array_slice($shortnames, 0, 10);
96 $diff = $total - count($shortnames);
37b5e8fe
RT
97 if ($diff > 1) {
98 $suffix = get_string('shortnamesufixprural', 'block_course_overview', $diff);
99 } else {
100 $suffix = get_string('shortnamesufixsingular', 'block_course_overview', $diff);
101 }
83ea0cc1 102 }
37b5e8fe
RT
103 $shortnames = get_string('shortnameprefix', 'block_course_overview', implode('; ', $shortnames));
104 $shortnames .= $suffix;
83ea0cc1
AO
105 }
106
107 return isset($shortnames) ? $shortnames : false;
108}
109
37b5e8fe
RT
110/**
111 * Returns maximum number of courses which will be displayed in course_overview block
112 *
113 * @return int maximum number of courses
114 */
115function block_course_overview_get_max_user_courses() {
116 // Get block configuration
117 $config = get_config('block_course_overview');
118 $limit = $config->defaultmaxcourses;
119
120 // If max course is not set then try get user preference
121 if (empty($config->forcedefaultmaxcourses)) {
122 $limit = get_user_preferences('course_overview_number_of_courses', $limit);
123 }
124 return $limit;
125}
126
127/**
128 * Return sorted list of user courses
129 *
130 * @return array list of sorted courses and count of courses.
131 */
83ea0cc1
AO
132function block_course_overview_get_sorted_courses() {
133 global $USER;
134
37b5e8fe 135 $limit = block_course_overview_get_max_user_courses();
83ea0cc1 136
49ed1b0d 137 $courses = enrol_get_my_courses('id, shortname, fullname, modinfo, sectioncache');
83ea0cc1
AO
138 $site = get_site();
139
140 if (array_key_exists($site->id,$courses)) {
141 unset($courses[$site->id]);
142 }
143
144 foreach ($courses as $c) {
145 if (isset($USER->lastcourseaccess[$c->id])) {
146 $courses[$c->id]->lastaccess = $USER->lastcourseaccess[$c->id];
147 } else {
148 $courses[$c->id]->lastaccess = 0;
149 }
150 }
151
37b5e8fe
RT
152 // Get remote courses.
153 $remotecourses = array();
154 if (is_enabled_auth('mnet')) {
155 $remotecourses = get_my_remotecourses();
156 }
157 // Remote courses will have -ve remoteid as key, so it can be differentiated from normal courses
158 foreach ($remotecourses as $id => $val) {
159 $remoteid = $val->remoteid * -1;
160 $val->id = $remoteid;
161 $courses[$remoteid] = $val;
83ea0cc1
AO
162 }
163
37b5e8fe
RT
164 $order = array();
165 if (!is_null($usersortorder = get_user_preferences('course_overview_course_order'))) {
166 $order = unserialize($usersortorder);
83ea0cc1
AO
167 }
168
37b5e8fe
RT
169 $sortedcourses = array();
170 $counter = 0;
171 // Get courses in sort order into list.
172 foreach ($order as $key => $cid) {
173 if (($counter >= $limit) && ($limit != 0)) {
83ea0cc1
AO
174 break;
175 }
37b5e8fe
RT
176
177 // Make sure user is still enroled.
178 if (isset($courses[$cid])) {
179 $sortedcourses[$cid] = $courses[$cid];
180 $counter++;
83ea0cc1
AO
181 }
182 }
37b5e8fe 183 // Append unsorted courses if limit allows
83ea0cc1 184 foreach ($courses as $c) {
37b5e8fe 185 if (($limit != 0) && ($counter >= $limit)) {
83ea0cc1
AO
186 break;
187 }
37b5e8fe
RT
188 if (!in_array($c->id, $order)) {
189 $sortedcourses[$c->id] = $c;
190 $counter++;
83ea0cc1
AO
191 }
192 }
193
37b5e8fe
RT
194 // From list extract site courses for overview
195 $sitecourses = array();
196 foreach ($sortedcourses as $key => $course) {
197 if ($course->id > 0) {
198 $sitecourses[$key] = $course;
199 }
200 }
201 return array($sortedcourses, $sitecourses, count($courses));
83ea0cc1 202}