Commit | Line | Data |
---|---|---|
aa6c1ced | 1 | <?php |
f9903ed0 | 2 | |
3 | // Display the course home page. | |
4 | ||
08cebf19 | 5 | require_once('../config.php'); |
6 | require_once('lib.php'); | |
516c5eca | 7 | require_once($CFG->libdir.'/completionlib.php'); |
f9903ed0 | 8 | |
2335781f | 9 | $id = optional_param('id', 0, PARAM_INT); |
8908432f | 10 | $name = optional_param('name', '', PARAM_TEXT); |
0cdae0dc | 11 | $edit = optional_param('edit', -1, PARAM_BOOL); |
12 | $hide = optional_param('hide', 0, PARAM_INT); | |
13 | $show = optional_param('show', 0, PARAM_INT); | |
14 | $idnumber = optional_param('idnumber', '', PARAM_RAW); | |
5249ba74 | 15 | $sectionid = optional_param('sectionid', 0, PARAM_INT); |
0cdae0dc | 16 | $section = optional_param('section', 0, PARAM_INT); |
17 | $move = optional_param('move', 0, PARAM_INT); | |
f4f0bc84 | 18 | $marker = optional_param('marker',-1 , PARAM_INT); |
aae028d9 | 19 | $switchrole = optional_param('switchrole',-1, PARAM_INT); // Deprecated, use course/switchrole.php instead. |
52fc56a7 | 20 | $return = optional_param('return', 0, PARAM_LOCALURL); |
3a52e764 | 21 | |
599a52fe | 22 | $params = array(); |
2335781f | 23 | if (!empty($name)) { |
599a52fe | 24 | $params = array('shortname' => $name); |
816acb46 | 25 | } else if (!empty($idnumber)) { |
599a52fe DP |
26 | $params = array('idnumber' => $idnumber); |
27 | } else if (!empty($id)) { | |
28 | $params = array('id' => $id); | |
29 | }else { | |
30 | print_error('unspecifycourseid', 'error'); | |
f9903ed0 | 31 | } |
32 | ||
599a52fe DP |
33 | $course = $DB->get_record('course', $params, '*', MUST_EXIST); |
34 | ||
45774bdd | 35 | $urlparams = array('id' => $course->id); |
5249ba74 | 36 | |
2c7a72df | 37 | // Sectionid should get priority over section number |
5249ba74 AA |
38 | if ($sectionid) { |
39 | $section = $DB->get_field('course_sections', 'section', array('id' => $sectionid, 'course' => $course->id), MUST_EXIST); | |
40 | } | |
45774bdd DP |
41 | if ($section) { |
42 | $urlparams['section'] = $section; | |
43 | } | |
44 | ||
45 | $PAGE->set_url('/course/view.php', $urlparams); // Defined here to avoid notices on errors etc | |
088e3363 | 46 | |
fbb4c959 SH |
47 | // Prevent caching of this page to stop confusion when changing page after making AJAX changes |
48 | $PAGE->set_cacheable(false); | |
49 | ||
8f7d3d12 | 50 | context_helper::preload_course($course->id); |
599a52fe | 51 | $context = context_course::instance($course->id, MUST_EXIST); |
3a52e764 | 52 | |
d7d4b0e5 | 53 | // Remove any switched roles before checking login |
54 | if ($switchrole == 0 && confirm_sesskey()) { | |
ac4c51be | 55 | role_switch($switchrole, $context); |
56 | } | |
57 | ||
a6af674a | 58 | require_login($course); |
388f8911 | 59 | |
d7d4b0e5 | 60 | // Switchrole - sanity check in cost-order... |
46bd37bf | 61 | $reset_user_allowed_editing = false; |
d7d4b0e5 | 62 | if ($switchrole > 0 && confirm_sesskey() && |
63 | has_capability('moodle/role:switchroles', $context)) { | |
64 | // is this role assignable in this context? | |
65 | // inquiring minds want to know... | |
82701e24 | 66 | $aroles = get_switchable_roles($context); |
d7d4b0e5 | 67 | if (is_array($aroles) && isset($aroles[$switchrole])) { |
68 | role_switch($switchrole, $context); | |
69 | // Double check that this role is allowed here | |
cdbea7ee | 70 | require_login($course); |
d7d4b0e5 | 71 | } |
46bd37bf | 72 | // reset course page state - this prevents some weird problems ;-) |
73 | $USER->activitycopy = false; | |
74 | $USER->activitycopycourse = NULL; | |
75 | unset($USER->activitycopyname); | |
76 | unset($SESSION->modform); | |
77 | $USER->editing = 0; | |
78 | $reset_user_allowed_editing = true; | |
3a52e764 | 79 | } |
80 | ||
542a0435 | 81 | //If course is hosted on an external server, redirect to corresponding |
aa6c1ced | 82 | //url with appropriate authentication attached as parameter |
892c0825 | 83 | if (file_exists($CFG->dirroot .'/course/externservercourse.php')) { |
84 | include $CFG->dirroot .'/course/externservercourse.php'; | |
4d2401d5 | 85 | if (function_exists('extern_server_course')) { |
542a0435 | 86 | if ($extern_url = extern_server_course($course)) { |
87 | redirect($extern_url); | |
88 | } | |
89 | } | |
90 | } | |
91 | ||
3a52e764 | 92 | |
08cebf19 | 93 | require_once($CFG->dirroot.'/calendar/lib.php'); /// This is after login because it needs $USER |
af62781b | 94 | |
6fa877e2 RL |
95 | // Must set layout before gettting section info. See MDL-47555. |
96 | $PAGE->set_pagelayout('course'); | |
97 | ||
9e586967 | 98 | if ($section and $section > 0) { |
c069dacf | 99 | |
100 | // Get section details and check it exists. | |
101 | $modinfo = get_fast_modinfo($course); | |
102 | $coursesections = $modinfo->get_section_info($section, MUST_EXIST); | |
103 | ||
104 | // Check user is allowed to see it. | |
134e28b7 | 105 | if (!$coursesections->uservisible) { |
8e61e0f9 GT |
106 | // Check if coursesection has conditions affecting availability and if |
107 | // so, output availability info. | |
108 | if ($coursesections->visible && $coursesections->availableinfo) { | |
109 | $sectionname = get_section_name($course, $coursesections); | |
110 | $message = get_string('notavailablecourse', '', $sectionname); | |
111 | redirect(course_get_url($course), $message, null, \core\output\notification::NOTIFY_ERROR); | |
112 | } else { | |
113 | // Note: We actually already know they don't have this capability | |
114 | // or uservisible would have been true; this is just to get the | |
115 | // correct error message shown. | |
116 | require_capability('moodle/course:viewhiddensections', $context); | |
117 | } | |
c069dacf | 118 | } |
34b84d45 | 119 | } |
f9903ed0 | 120 | |
8afb1cc8 MG |
121 | // Fix course format if it is no longer installed |
122 | $course->format = course_get_format($course)->get_format(); | |
0f3fe4b6 | 123 | |
66b10689 | 124 | $PAGE->set_pagetype('course-view-' . $course->format); |
3947b8ce | 125 | $PAGE->set_other_editing_capability('moodle/course:update'); |
cfcfb9f3 | 126 | $PAGE->set_other_editing_capability('moodle/course:manageactivities'); |
1fda836c MG |
127 | $PAGE->set_other_editing_capability('moodle/course:activityvisibility'); |
128 | if (course_format_uses_sections($course->format)) { | |
129 | $PAGE->set_other_editing_capability('moodle/course:sectionvisibility'); | |
130 | $PAGE->set_other_editing_capability('moodle/course:movesections'); | |
131 | } | |
b7b2d0f3 | 132 | |
8afb1cc8 MG |
133 | // Preload course format renderer before output starts. |
134 | // This is a little hacky but necessary since | |
135 | // format.php is not included until after output starts | |
136 | if (file_exists($CFG->dirroot.'/course/format/'.$course->format.'/renderer.php')) { | |
137 | require_once($CFG->dirroot.'/course/format/'.$course->format.'/renderer.php'); | |
138 | if (class_exists('format_'.$course->format.'_renderer')) { | |
139 | // call get_renderer only if renderer is defined in format plugin | |
140 | // otherwise an exception would be thrown | |
141 | $PAGE->get_renderer('format_'. $course->format); | |
142 | } | |
143 | } | |
144 | ||
46bd37bf | 145 | if ($reset_user_allowed_editing) { |
146 | // ugly hack | |
147 | unset($PAGE->_user_allowed_editing); | |
148 | } | |
daa27ce4 | 149 | |
0f3fe4b6 | 150 | if (!isset($USER->editing)) { |
d2b23346 | 151 | $USER->editing = 0; |
0f3fe4b6 | 152 | } |
a3f24f7c | 153 | if ($PAGE->user_allowed_editing()) { |
0cdae0dc | 154 | if (($edit == 1) and confirm_sesskey()) { |
d2b23346 | 155 | $USER->editing = 1; |
ad96cc52 AKA |
156 | // Redirect to site root if Editing is toggled on frontpage |
157 | if ($course->id == SITEID) { | |
158 | redirect($CFG->wwwroot .'/?redirect=0'); | |
52fc56a7 JF |
159 | } else if (!empty($return)) { |
160 | redirect($CFG->wwwroot . $return); | |
ad96cc52 | 161 | } else { |
3970a471 | 162 | $url = new moodle_url($PAGE->url, array('notifyeditingon' => 1)); |
6c0ae99b | 163 | redirect($url); |
ad96cc52 | 164 | } |
0cdae0dc | 165 | } else if (($edit == 0) and confirm_sesskey()) { |
d2b23346 | 166 | $USER->editing = 0; |
a3f24f7c | 167 | if(!empty($USER->activitycopy) && $USER->activitycopycourse == $course->id) { |
168 | $USER->activitycopy = false; | |
169 | $USER->activitycopycourse = NULL; | |
9c9f7d77 | 170 | } |
ad96cc52 AKA |
171 | // Redirect to site root if Editing is toggled on frontpage |
172 | if ($course->id == SITEID) { | |
173 | redirect($CFG->wwwroot .'/?redirect=0'); | |
52fc56a7 JF |
174 | } else if (!empty($return)) { |
175 | redirect($CFG->wwwroot . $return); | |
ad96cc52 AKA |
176 | } else { |
177 | redirect($PAGE->url); | |
178 | } | |
f9903ed0 | 179 | } |
8223d271 | 180 | |
643b1de8 | 181 | if (has_capability('moodle/course:sectionvisibility', $context)) { |
af189935 PS |
182 | if ($hide && confirm_sesskey()) { |
183 | set_section_visible($course->id, $hide, '0'); | |
e3c171e1 | 184 | redirect($PAGE->url); |
af189935 | 185 | } |
7d99d695 | 186 | |
af189935 PS |
187 | if ($show && confirm_sesskey()) { |
188 | set_section_visible($course->id, $show, '1'); | |
e3c171e1 | 189 | redirect($PAGE->url); |
af189935 | 190 | } |
643b1de8 | 191 | } |
12905134 | 192 | |
3947b8ce MG |
193 | if (!empty($section) && !empty($move) && |
194 | has_capability('moodle/course:movesections', $context) && confirm_sesskey()) { | |
195 | $destsection = $section + $move; | |
196 | if (move_section_to($course, $section, $destsection)) { | |
197 | if ($course->id == SITEID) { | |
198 | redirect($CFG->wwwroot . '/?redirect=0'); | |
199 | } else { | |
200 | redirect(course_get_url($course)); | |
56e34ee4 | 201 | } |
3947b8ce MG |
202 | } else { |
203 | echo $OUTPUT->notification('An error occurred while moving a section'); | |
12905134 | 204 | } |
205 | } | |
48d72fa7 | 206 | } else { |
d2b23346 | 207 | $USER->editing = 0; |
7d99d695 | 208 | } |
209 | ||
45774bdd | 210 | $SESSION->fromdiscussion = $PAGE->url->out(false); |
4c701e6f | 211 | |
f45cc76f | 212 | |
213 | if ($course->id == SITEID) { | |
214 | // This course is not a real course. | |
892c0825 | 215 | redirect($CFG->wwwroot .'/'); |
83f3c62d | 216 | } |
0a127169 | 217 | |
cf615522 | 218 | $completion = new completion_info($course); |
af64bc61 | 219 | if ($completion->is_enabled()) { |
76c0123b PS |
220 | $PAGE->requires->string_for_js('completion-alt-manual-y', 'completion'); |
221 | $PAGE->requires->string_for_js('completion-alt-manual-n', 'completion'); | |
222 | ||
223 | $PAGE->requires->js_init_call('M.core_completion.init'); | |
cf615522 | 224 | } |
225 | ||
8a7934f7 PS |
226 | // We are currently keeping the button here from 1.x to help new teachers figure out |
227 | // what to do, even though the link also appears in the course admin block. It also | |
2b3d1ac7 | 228 | // means you can back out of a situation where you removed the admin block. :) |
5d3e9d9f | 229 | if ($PAGE->user_allowed_editing()) { |
d628215d | 230 | $buttons = $OUTPUT->edit_button($PAGE->url); |
2b3d1ac7 | 231 | $PAGE->set_button($buttons); |
5d3e9d9f | 232 | } |
233 | ||
761c5fc2 JF |
234 | // If viewing a section, make the title more specific |
235 | if ($section and $section > 0 and course_format_uses_sections($course->format)) { | |
236 | $sectionname = get_string('sectionname', "format_$course->format"); | |
237 | $sectiontitle = get_section_name($course, $section); | |
238 | $PAGE->set_title(get_string('coursesectiontitle', 'moodle', array('course' => $course->fullname, 'sectiontitle' => $sectiontitle, 'sectionname' => $sectionname))); | |
239 | } else { | |
240 | $PAGE->set_title(get_string('coursetitle', 'moodle', array('course' => $course->fullname))); | |
241 | } | |
242 | ||
0a122046 | 243 | $PAGE->set_heading($course->fullname); |
0a122046 | 244 | echo $OUTPUT->header(); |
f45cc76f | 245 | |
af368c10 BH |
246 | if ($USER->editing == 1 && !empty($CFG->enableasyncbackup)) { |
247 | ||
248 | // MDL-65321 The backup libraries are quite heavy, only require the bare minimum. | |
249 | require_once($CFG->dirroot . '/backup/util/helper/async_helper.class.php'); | |
250 | ||
251 | if (async_helper::is_async_pending($id, 'course', 'backup')) { | |
252 | echo $OUTPUT->notification(get_string('pendingasyncedit', 'backup'), 'warning'); | |
253 | } | |
254 | } | |
2cd901a4 | 255 | |
af64bc61 | 256 | if ($completion->is_enabled()) { |
9a5a0694 | 257 | // This value tracks whether there has been a dynamic change to the page. |
258 | // It is used so that if a user does this - (a) set some tickmarks, (b) | |
259 | // go to another page, (c) clicks Back button - the page will | |
260 | // automatically reload. Otherwise it would start with the wrong tick | |
261 | // values. | |
47e75d04 SH |
262 | echo html_writer::start_tag('form', array('action'=>'.', 'method'=>'get')); |
263 | echo html_writer::start_tag('div'); | |
264 | echo html_writer::empty_tag('input', array('type'=>'hidden', 'id'=>'completion_dynamic_change', 'name'=>'completion_dynamic_change', 'value'=>'0')); | |
265 | echo html_writer::end_tag('div'); | |
266 | echo html_writer::end_tag('form'); | |
4e781c7b | 267 | } |
268 | ||
f45cc76f | 269 | // Course wrapper start. |
47e75d04 | 270 | echo html_writer::start_tag('div', array('class'=>'course-content')); |
f45cc76f | 271 | |
d57aa283 | 272 | // make sure that section 0 exists (this function will create one if it is missing) |
4ede27b2 | 273 | course_create_sections_if_missing($course, 0); |
d57aa283 MG |
274 | |
275 | // get information about course modules and existing module types | |
276 | // format.php in course formats may rely on presence of these variables | |
277 | $modinfo = get_fast_modinfo($course); | |
278 | $modnames = get_module_types_names(); | |
279 | $modnamesplural = get_module_types_names(true); | |
280 | $modnamesused = $modinfo->get_used_module_names(); | |
281 | $mods = $modinfo->get_cms(); | |
282 | $sections = $modinfo->get_section_info_all(); | |
7468bf01 | 283 | |
45774bdd DP |
284 | // CAUTION, hacky fundamental variable defintion to follow! |
285 | // Note that because of the way course fromats are constructed though | |
286 | // inclusion we pass parameters around this way.. | |
287 | $displaysection = $section; | |
288 | ||
f45cc76f | 289 | // Include the actual course format. |
290 | require($CFG->dirroot .'/course/format/'. $course->format .'/format.php'); | |
291 | // Content wrapper end. | |
47e75d04 SH |
292 | |
293 | echo html_writer::end_tag('div'); | |
f45cc76f | 294 | |
68a72358 | 295 | // Trigger course viewed event. |
a5f42139 SH |
296 | // We don't trust $context here. Course format inclusion above executes in the global space. We can't assume |
297 | // anything after that point. | |
22588835 | 298 | course_view(context_course::instance($course->id), $section); |
68a72358 | 299 | |
01e0e704 | 300 | // Include course AJAX |
697ff999 | 301 | include_course_ajax($course, $modnamesused); |
f45cc76f | 302 | |
d60c1124 | 303 | echo $OUTPUT->footer(); |