moodle/course/view.php
tjhunt d4a03c00ea themes & blocks - MDL-19077 & MDL-19010 blocks are now printed by the theme
The code to print blocks in now in theme layout.php files. (Or in
moodle_core_renderer::handle_legacy_theme)

Code for printing blocks everywhere else has been stripped out.
(Total diffstat 1225 insertions, 2019 deletions)

The way the HTML for a block instance is generated has been cleaned
up a lot. Now, the block_instance generates a block_contents
object which gives a structured representation of the block,
and then $OUTPUT->block builds all the HTML from that.

How theme config.php files specify the layout template and block
regions by page general type has been changed to be even more flexible.

Further refinement for how the theme and block code gets initialised.

Ability for scrits to add 'pretend blocks' to the page. That is,
things that look like blocks, but are not normal block_instances.
(Like the add a new block UI.)

Things that are still broken:
 * some pages in lesson, quiz and resource. I'm working on it.
 * lots of developer debug notices pointing out things that
   need to be updated.
2009-07-09 07:35:03 +00:00

257 lines
10 KiB
PHP

<?php // $Id$
// Display the course home page.
require_once('../config.php');
require_once('lib.php');
require_once($CFG->dirroot.'/mod/forum/lib.php');
$id = optional_param('id', 0, PARAM_INT);
$name = optional_param('name', '', PARAM_RAW);
$edit = optional_param('edit', -1, PARAM_BOOL);
$hide = optional_param('hide', 0, PARAM_INT);
$show = optional_param('show', 0, PARAM_INT);
$idnumber = optional_param('idnumber', '', PARAM_RAW);
$section = optional_param('section', 0, PARAM_INT);
$move = optional_param('move', 0, PARAM_INT);
$marker = optional_param('marker',-1 , PARAM_INT);
$switchrole = optional_param('switchrole',-1, PARAM_INT);
if (empty($id) && empty($name) && empty($idnumber)) {
print_error('unspecifycourseid', 'error');
}
if (!empty($name)) {
if (! ($course = $DB->get_record('course', array('shortname'=>$name)))) {
print_error('invalidcoursenameshort', 'error');
}
} else if (!empty($idnumber)) {
if (! ($course = $DB->get_record('course', array('idnumber'=>$idnumber)))) {
print_error('invalidcourseid', 'error');
}
} else {
if (! ($course = $DB->get_record('course', array('id'=>$id)))) {
print_error('invalidcourseid', 'error');
}
}
preload_course_contexts($course->id);
if (!$context = get_context_instance(CONTEXT_COURSE, $course->id)) {
print_error('nocontext');
}
// Remove any switched roles before checking login
if ($switchrole == 0 && confirm_sesskey()) {
role_switch($switchrole, $context);
}
require_login($course);
// Switchrole - sanity check in cost-order...
$reset_user_allowed_editing = false;
if ($switchrole > 0 && confirm_sesskey() &&
has_capability('moodle/role:switchroles', $context)) {
// is this role assignable in this context?
// inquiring minds want to know...
$aroles = get_switchable_roles($context);
if (is_array($aroles) && isset($aroles[$switchrole])) {
role_switch($switchrole, $context);
// Double check that this role is allowed here
require_login($course->id);
}
// reset course page state - this prevents some weird problems ;-)
$USER->activitycopy = false;
$USER->activitycopycourse = NULL;
unset($USER->activitycopyname);
unset($SESSION->modform);
$USER->editing = 0;
$reset_user_allowed_editing = true;
}
//If course is hosted on an external server, redirect to corresponding
//url with appropriate authentication attached as parameter
if (file_exists($CFG->dirroot .'/course/externservercourse.php')) {
include $CFG->dirroot .'/course/externservercourse.php';
if (function_exists('extern_server_course')) {
if ($extern_url = extern_server_course($course)) {
redirect($extern_url);
}
}
}
require_once($CFG->dirroot.'/calendar/lib.php'); /// This is after login because it needs $USER
add_to_log($course->id, 'course', 'view', "view.php?id=$course->id", "$course->id");
$course->format = clean_param($course->format, PARAM_ALPHA);
if (!file_exists($CFG->dirroot.'/course/format/'.$course->format.'/format.php')) {
$course->format = 'weeks'; // Default format is weeks
}
$PAGE->set_url('course/view.php', array('id' => $course->id));
$PAGE->set_pagetype('course-view-' . $course->format);
$PAGE->set_other_editing_capability('moodle/course:manageactivities');
if ($reset_user_allowed_editing) {
// ugly hack
unset($PAGE->_user_allowed_editing);
}
if (!isset($USER->editing)) {
$USER->editing = 0;
}
if ($PAGE->user_allowed_editing()) {
if (($edit == 1) and confirm_sesskey()) {
$USER->editing = 1;
} else if (($edit == 0) and confirm_sesskey()) {
$USER->editing = 0;
if(!empty($USER->activitycopy) && $USER->activitycopycourse == $course->id) {
$USER->activitycopy = false;
$USER->activitycopycourse = NULL;
}
}
if ($hide && confirm_sesskey()) {
set_section_visible($course->id, $hide, '0');
}
if ($show && confirm_sesskey()) {
set_section_visible($course->id, $show, '1');
}
if (!empty($section)) {
if (!empty($move) and confirm_sesskey()) {
if (!move_section($course, $section, $move)) {
notify('An error occurred while moving a section');
}
}
}
} else {
$USER->editing = 0;
}
$SESSION->fromdiscussion = $CFG->wwwroot .'/course/view.php?id='. $course->id;
if ($course->id == SITEID) {
// This course is not a real course.
redirect($CFG->wwwroot .'/');
}
// AJAX-capable course format?
$useajax = false;
$ajaxformatfile = $CFG->dirroot.'/course/format/'.$course->format.'/ajax.php';
$bodytags = '';
if (empty($CFG->disablecourseajax) and file_exists($ajaxformatfile)) { // Needs to exist otherwise no AJAX by default
// TODO: stop abusing CFG global here
$CFG->ajaxcapable = false; // May be overridden later by ajaxformatfile
$CFG->ajaxtestedbrowsers = array(); // May be overridden later by ajaxformatfile
require_once($ajaxformatfile);
if (!empty($USER->editing) && $CFG->ajaxcapable && has_capability('moodle/course:manageactivities', $context)) {
// Course-based switches
if (ajaxenabled($CFG->ajaxtestedbrowsers)) { // Browser, user and site-based switches
$PAGE->requires->yui_lib('dragdrop');
$PAGE->requires->yui_lib('connection');
$PAGE->requires->js('lib/ajax/block_classes.js');
$PAGE->requires->js('lib/ajax/section_classes.js');
// Okay, global variable alert. VERY UGLY. We need to create
// this object here before the <blockname>_print_block()
// function is called, since that function needs to set some
// stuff in the javascriptportal object.
$COURSE->javascriptportal = new jsportal();
$useajax = true;
}
}
}
$CFG->blocksdrag = $useajax; // this will add a new class to the header so we can style differently
$completion = new completion_info($course);
if ($completion->is_enabled() && ajaxenabled()) {
$PAGE->requires->yui_lib('connection');
$PAGE->requires->js('course/completion.js');
$PAGE->requires->data_for_js('completion_strsaved', get_string('saved', 'completion'));
$PAGE->requires->data_for_js('completion_strtitley', get_string('completion-title-manual-y', 'completion'));
$PAGE->requires->data_for_js('completion_strtitlen', get_string('completion-title-manual-n', 'completion'));
$PAGE->requires->data_for_js('completion_stralty', get_string('completion-alt-manual-y', 'completion'));
$PAGE->requires->data_for_js('completion_straltn', get_string('completion-alt-manual-n', 'completion'));
}
// The "Editing On" button will be appearing only in the "main" course screen
// (i.e., no breadcrumbs other than the default one added inside this function)
$buttons = switchroles_form($course->id);
if ($PAGE->user_allowed_editing()) {
$buttons .= update_course_icon($course->id );
}
$title = get_string('course') . ': ' . $course->fullname;
$navigation = build_navigation(array());
print_header($title, $course->fullname, $navigation, '', '', true,
$buttons, user_login_string($course, $USER), false, $bodytags);
if ($completion->is_enabled() && ajaxenabled()) {
// This value tracks whether there has been a dynamic change to the page.
// It is used so that if a user does this - (a) set some tickmarks, (b)
// go to another page, (c) clicks Back button - the page will
// automatically reload. Otherwise it would start with the wrong tick
// values.
print '<form action="."><div><input type="hidden" id="completion_dynamic_change"
name="completion_dynamic_change" value="0" /></div></form>';
}
// Course wrapper start.
echo '<div class="course-content">';
$modinfo =& get_fast_modinfo($COURSE);
get_all_mods($course->id, $mods, $modnames, $modnamesplural, $modnamesused);
foreach($mods as $modid=>$unused) {
if (!isset($modinfo->cms[$modid])) {
rebuild_course_cache($course->id);
$modinfo =& get_fast_modinfo($COURSE);
debugging('Rebuilding course cache', DEBUG_DEVELOPER);
break;
}
}
if (! $sections = get_all_sections($course->id)) { // No sections found
// Double-check to be extra sure
if (! $section = $DB->get_record('course_sections', array('course'=>$course->id, 'section'=>0))) {
$section->course = $course->id; // Create a default section.
$section->section = 0;
$section->visible = 1;
$section->id = $DB->insert_record('course_sections', $section);
}
if (! $sections = get_all_sections($course->id) ) { // Try again
print_error('cannotcreateorfindstructs', 'error');
}
}
// Include the actual course format.
require($CFG->dirroot .'/course/format/'. $course->format .'/format.php');
// Content wrapper end.
echo "</div>\n\n";
// Use AJAX?
if ($useajax && has_capability('moodle/course:manageactivities', $context)) {
// At the bottom because we want to process sections and activities
// after the relevant html has been generated. We're forced to do this
// because of the way in which lib/ajax/ajaxcourse.js is written.
$PAGE->requires->js('lib/ajax/ajaxcourse.js');
$COURSE->javascriptportal->print_javascript($course->id);
}
print_footer();
?>