From 1804b7c1bc99667198d865b56a5af3158d532de5 Mon Sep 17 00:00:00 2001 From: Dan Poltawski Date: Fri, 27 Apr 2012 13:11:35 +0800 Subject: [PATCH] MDL-32508 course/formats: Respect single page course display mode Topics and weeks have been converted to use a shared renderer to output their content. Note, I started with good intentions but this renderer has mixed paradgims due to fast and cheap winning out on the trinity. AMOS BEGIN MOV [currenttopic,access],[currentsection,format_topics] MOV [currentweek,access],[currentsection,format_weeks] AMOS END --- course/format/renderer.php | 514 ++++++++++++++++++ course/format/topics/format.php | 280 +--------- .../format/topics/lang/en/format_topics.php | 1 + course/format/topics/renderer.php | 105 ++++ course/format/topics/version.php | 6 +- course/format/weeks/format.php | 306 ++--------- course/format/weeks/lang/en/format_weeks.php | 1 + course/format/weeks/renderer.php | 61 +++ course/format/weeks/version.php | 6 +- lang/en/access.php | 2 - theme/base/style/course.css | 5 + 11 files changed, 756 insertions(+), 531 deletions(-) create mode 100644 course/format/renderer.php create mode 100644 course/format/topics/renderer.php create mode 100644 course/format/weeks/renderer.php diff --git a/course/format/renderer.php b/course/format/renderer.php new file mode 100644 index 00000000000..dcace50e3bc --- /dev/null +++ b/course/format/renderer.php @@ -0,0 +1,514 @@ +. + +/** + * Base renderer for outputting course formats. + * + * @package core + * @copyright 2012 Dan Poltawski + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.3 + */ + +defined('MOODLE_INTERNAL') || die(); + + +/** + * This renderer is used by section based formats + * + * @package core + * @copyright 2012 Dan Poltawski + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.3 + */ +abstract class format_renderer_base extends plugin_renderer_base { + + /** + * Generate the starting container html for a list of sections + * @return string HTML to output. + */ + abstract public function start_section_list(); + + /** + * Generate the closing container html for a list of sections + * @return string HTML to output. + */ + abstract public function end_section_list(); + + /** + * Generate the title for this section page + * @return string the page title + */ + abstract public function page_title(); + + /** + * Generate the display of the header part of a section before + * course modules are included + * + * @param stdClass $section The course_section entry from DB + * @param stdClass $course The course entry from DB + * @param bool $onsectionpage true if being printed on a section page + * @return string HTML to output. + */ + public function section_header($section, $course, $onsectionpage) { + global $PAGE; + + $o = ''; + $currenttext = ''; + $sectionstyle = ''; + $rightcontent = $this->output->spacer(); + $leftcontent = $this->output->spacer(); + $linktitle = false; + + if ($section->section != 0 ) { + // Only in the non-general sections. + if (!$section->visible) { + $sectionstyle = ' hidden'; + } else if ($course->marker == $section->section) { + $sectionstyle = ' current'; + $currenttext = get_accesshide(get_string('currentsection', 'format_'.$course->format)); + } + $leftcontent = $currenttext.$section->section; + $controls = $this->section_edit_controls($course, $section, $onsectionpage); + if (!empty($controls)) { + $rightcontent = implode('
', $controls); + } + $linktitle = ($course->coursedisplay == COURSE_DISPLAY_MULTIPAGE); + } + + $o.= html_writer::start_tag('li', array('id' => 'section-'.$section->section, + 'class' => 'section main clearfix'.$sectionstyle)); + $o.= html_writer::tag('div', $leftcontent, array('class' => 'left side')); + $o.= html_writer::tag('div', $rightcontent, array('class' => 'right side')); + $o.= html_writer::start_tag('div', array('class' => 'content')); + + if (!$onsectionpage) { + $title = get_section_name($course, $section); + if ($linktitle) { + $title = html_writer::link(course_get_url($course, $section->section), $title); + } + $o.= $this->output->heading($title, 3, 'sectionname'); + } + + $o.= html_writer::start_tag('div', array('class' => 'summary')); + + $context = context_course::instance($section->course); + $summarytext = file_rewrite_pluginfile_urls($section->summary, 'pluginfile.php', + $context->id, 'course', 'section', $section->id); + $summaryformatoptions = new stdClass(); + $summaryformatoptions->noclean = true; + $summaryformatoptions->overflowdiv = true; + + $o.= format_text($summarytext, $section->summaryformat, $summaryformatoptions); + + if ($PAGE->user_is_editing() && has_capability('moodle/course:update', $context)) { + $url = new moodle_url('/course/editsection.php', array('id'=>$section->id)); + + if ($onsectionpage) { + $url->param('sectionreturn', 1); + } + + $o.= html_writer::link($url, + html_writer::empty_tag('img', array('src' => $this->output->pix_url('t/edit'), 'class' => 'iconsmall edit')), + array('title' => get_string('editsummary'))); + } + $o.= html_writer::end_tag('div'); + + return $o; + } + + /** + * Generate the display of the footer part of a section + * + * @return string HTML to output. + */ + public function section_footer() { + $o = html_writer::end_tag('div'); + $o.= html_writer::end_tag('li'); + + return $o; + } + + /** + * Generate the edit controls of a section + * + * @param stdClass $course The course entry from DB + * @param stdClass $section The course_section entry from DB + * @param bool $onsectionpage true if being printed on a section page + * @return array of links with edit controls + */ + public function section_edit_controls($course, $section, $onsectionpage = false) { + global $PAGE; + + if (!$PAGE->user_is_editing()) { + return array(); + } + + if (!has_capability('moodle/course:update', context_course::instance($course->id))) { + return array(); + } + + if ($onsectionpage) { + $baseurl = course_get_url($course, $section->section); + } else { + $baseurl = course_get_url($course); + } + $baseurl->param('sesskey', sesskey()); + + $controls = array(); + + $url = clone($baseurl); + if ($section->visible) { // Show the hide/show eye. + $strhidefromothers = get_string('hidefromothers', 'format_'.$course->format); + $url->param('hide', $section->section); + $controls[] = html_writer::link($url, + html_writer::empty_tag('img', array('src' => $this->output->pix_url('i/hide'), + 'class' => 'icon hide', 'alt' => $strhidefromothers)), + array('title' => $strhidefromothers, 'class' => 'editing_showhide')); + } else { + $strshowfromothers = get_string('showfromothers', 'format_'.$course->format); + $url->param('show', $section->section); + $controls[] = html_writer::link($url, + html_writer::empty_tag('img', array('src' => $this->output->pix_url('i/show'), + 'class' => 'icon hide', 'alt' => $strshowfromothers)), + array('title' => $strshowfromothers, 'class' => 'editing_showhide')); + } + + if (!$onsectionpage) { + $url = clone($baseurl); + if ($section->section > 1) { // Add a arrow to move section up. + $url->param('section', $section->section); + $url->param('move', -1); + $strmoveup = get_string('moveup'); + + $controls[] = html_writer::link($url, + html_writer::empty_tag('img', array('src' => $this->output->pix_url('t/up'), + 'class' => 'icon up', 'alt' => $strmoveup)), + array('title' => $strmoveup, 'class' => 'moveup')); + } + + $url = clone($baseurl); + if ($section->section < $course->numsections) { // Add a arrow to move section down. + $url->param('section', $section->section); + $url->param('move', 1); + $strmovedown = get_string('movedown'); + + $controls[] = html_writer::link($url, + html_writer::empty_tag('img', array('src' => $this->output->pix_url('t/down'), + 'class' => 'icon down', 'alt' => $strmovedown)), + array('title' => $strmovedown, 'class' => 'movedown')); + } + } + + return $controls; + } + + /** + * Generate a summary of a section for display on the 'coruse index page' + * + * @param stdClass $section The course_section entry from DB + * @param stdClass $course The course entry from DB + * @return string HTML to output. + */ + public function section_summary($section, $course) { + + $o = ''; + $o.= html_writer::start_tag('li', array('id' => 'section-'.$section->section)); + + $title = get_section_name($course, $section); + $o.= html_writer::start_tag('div', array('class' => 'section-summary')); + $o.= html_writer::start_tag('a', array('href' => course_get_url($course, $section->section))); + $o.= $this->output->heading($title, 3, 'header section-title'); + $o.= html_writer::end_tag('a'); + + $o.= html_writer::start_tag('div', array('class' => 'summarytext')); + $o.= format_text($section->summary, $section->summaryformat); + $o.= html_writer::end_tag('div'); + $o.= html_writer::end_tag('div'); + $o.= html_writer::end_tag('li'); + + return $o; + } + + /** + * Show if something is on on the course clipboard (moving around) + * + * @param stdClass $course The course entry from DB + * @param int $sectionno The section number in the coruse which is being dsiplayed + * @return string HTML to output. + */ + public function course_activity_clipboard($course, $sectionno = 0) { + global $USER; + + $o = ''; + // If currently moving a file then show the current clipboard. + if (ismoving($course->id)) { + $url = new moodle_url('/course/mod.php', + array('sesskey' => sesskey(), + 'cancelcopy' => true, + 'sr' => $sectionno, + ) + ); + + $strcancel= get_string('cancel'); + + $o.= html_writer::start_tag('li', array('class' => 'clipboard')); + $o.= strip_tags(get_string('activityclipboard', '', $USER->activitycopyname)); + $o.= ' ('.html_writer::link($url, get_string('cancel')).')'; + $o.= html_writer::end_tag('li'); + } + + return $o; + } + + /** + * Generate next/previous section links for naviation + * + * @param stdClass $course The course entry from DB + * @param array $sections The course_sections entries from the DB + * @param int $sectionno The section number in the coruse which is being dsiplayed + * @return string HTML to output. + */ + public function get_nav_links($course, $sections, $sectionno) { + // FIXME: This is really evil and should by using the navigation API. + $canviewhidden = has_capability('moodle/course:viewhiddensections', context_course::instance($course->id)) + or !$course->hiddensections; + + $links = array('previous' => '', 'next' => ''); + $back = $sectionno - 1; + while ($back > 0 and empty($links['previous'])) { + if ($canviewhidden || $sections[$back]->visible) { + $links['previous'] = html_writer::link(course_get_url($course, $back), + $this->output->larrow().$this->output->spacer().get_section_name($course, $sections[$back])); + } + $back--; + } + + $forward = $sectionno + 1; + while ($forward <= $course->numsections and empty($links['next'])) { + if ($canviewhidden || $sections[$forward]->visible) { + $links['next'] = html_writer::link(course_get_url($course, $forward), + get_section_name($course, $sections[$forward]).$this->output->spacer().$this->output->rarrow()); + } + $forward++; + } + + $o = ''; + $o.= html_writer::start_tag('div', array('class' => 'section-navigation yui3-g')); + $o.= html_writer::tag('div', $links['previous'], array('class' => 'yui3-u')); + $o.= html_writer::tag('div', $links['next'], array('class' => 'right yui3-u')); + $o.= html_writer::end_tag('div'); + + return $o; + } + + /** + * Generate the header html of a stealth section + * + * @param int $sectionno The section number in the coruse which is being dsiplayed + * @return string HTML to output. + */ + public function stealth_section_header($sectionno) { + $o = ''; + $o.= html_writer::start_tag('li', array('id' => 'section-'.$sectionno, 'class' => 'section main clearfix orphaned hidden')); + $o.= html_writer::tag('div', '', array('class' => 'left side')); + $o.= html_writer::tag('div', '', array('class' => 'right side')); + $o.= html_writer::start_tag('div', array('class' => 'content')); + $o.= $this->output->heading(get_string('orphanedactivities'), 3, 'sectionname'); + return $o; + } + + /** + * Generate footer html of a stealth section + * + * @return string HTML to output. + */ + public function stealth_section_footer() { + $o = html_writer::end_tag('div'); + $o.= html_writer::end_tag('li'); + return $o; + } + + /** + * Generate the html for a hidden section + * + * @param int $sectionno The section number in the coruse which is being dsiplayed + * @return string HTML to output. + */ + public function section_hidden($sectionno) { + $o = ''; + $o.= html_writer::start_tag('li', array('id' => 'section-'.$sectionno, 'class' => 'section main clearfix hidden')); + $o.= html_writer::tag('div', '', array('class' => 'left side')); + $o.= html_writer::tag('div', '', array('class' => 'right side')); + $o.= html_writer::start_tag('div', array('class' => 'content')); + $o.= get_string('notavailable'); + $o.= html_writer::end_tag('div'); + $o.= html_writer::end_tag('li'); + return $o; + } + + /** + * Output the html for a single section page . + * + * @param stdClass $course The course entry from DB + * @param array $sections The course_sections entries from the DB + * @param array $mods used for print_section() + * @param array $modnames used for print_section() + * @param array $modnamesused used for print_section() + * @param int $displaysection The section number in the course which is being displayed + */ + public function print_single_section_page($course, $sections, $mods, $modnames, $modnamesused, $displaysection) { + global $PAGE; + + // Section next/previous links. + $sectionnavlinks = $this->get_nav_links($course, $sections, $displaysection); + echo $sectionnavlinks; + + // Can we view the section in question? + $context = context_course::instance($course->id); + $canviewhidden = has_capability('moodle/course:viewhiddensections', $context); + + if (!$sections[$displaysection]->visible && !$canviewhidden) { + if (!$course->hiddensections) { + echo $this->start_section_list(); + echo $this->section_hidden($displaysection); + echo $this->end_section_list(); + echo $sectionnavlinks; + } + // Can't view this section. + return; + } + + // Title with completion help icon. + $completioninfo = new completion_info($course); + echo $completioninfo->display_help_icon(); + $title = get_section_name($course, $sections[$displaysection]); + echo $this->output->heading($title, 2, 'headingblock header outline'); + + // Copy activity clipboard.. + echo $this->course_activity_clipboard($course, $displaysection); + + // Now the list of sections.. + echo $this->start_section_list(); + + // General section if non-empty. + $thissection = $sections[0]; + if ($thissection->summary or $thissection->sequence or $PAGE->user_is_editing()) { + echo $this->section_header($thissection, $course, true); + print_section($course, $thissection, $mods, $modnamesused, true); + if ($PAGE->user_is_editing()) { + print_section_add_menus($course, 0, $modnames); + } + echo $this->section_footer(); + } + + // The requested section page. + $thissection = $sections[$displaysection]; + echo $this->section_header($thissection, $course, true); + print_section($course, $thissection, $mods, $modnamesused, true); + if ($PAGE->user_is_editing()) { + print_section_add_menus($course, $displaysection, $modnames); + } + echo $this->section_footer(); + echo $sectionnavlinks; + echo $this->end_section_list(); + } + + /** + * Output the html for a multiple section page + * + * @param stdClass $course The course entry from DB + * @param array $sections The course_sections entries from the DB + * @param array $mods used for print_section() + * @param array $modnames used for print_section() + * @param array $modnamesused used for print_section() + */ + public function print_multiple_section_page($course, $sections, $mods, $modnames, $modnamesused) { + global $PAGE; + + $context = context_course::instance($course->id); + // Title with completion help icon. + $completioninfo = new completion_info($course); + echo $completioninfo->display_help_icon(); + echo $this->output->heading($this->page_title(), 2, 'headingblock header outline'); + + // Copy activity clipboard.. + echo $this->course_activity_clipboard($course); + + // Now the list of sections.. + echo $this->start_section_list(); + + // General section if non-empty. + $thissection = $sections[0]; + unset($sections[0]); + if ($thissection->summary or $thissection->sequence or $PAGE->user_is_editing()) { + echo $this->section_header($thissection, $course, true); + print_section($course, $thissection, $mods, $modnamesused, true); + if ($PAGE->user_is_editing()) { + print_section_add_menus($course, 0, $modnames); + } + echo $this->section_footer(); + } + + $canviewhidden = has_capability('moodle/course:viewhiddensections', $context); + for ($section = 1; $section <= $course->numsections; $section++) { + if (!empty($sections[$section])) { + $thissection = $sections[$section]; + } else { + // This will create a course section if it doesn't exist.. + $thissection = get_course_section($section, $course->id); + } + $showsection = ($canviewhidden or $thissection->visible or !$course->hiddensections); + if (!$thissection->visible && !$canviewhidden) { + if (!$course->hiddensections) { + echo $this->section_hidden($section); + } + + unset($sections[$section]); + continue; + } + + if (!$PAGE->user_is_editing() && $course->coursedisplay == COURSE_DISPLAY_MULTIPAGE) { + // Display section summary only. + echo $this->section_summary($thissection, $course); + } else { + echo $this->section_header($thissection, $course, false); + print_section($course, $thissection, $mods, $modnamesused); + if ($PAGE->user_is_editing()) { + print_section_add_menus($course, $section, $modnames); + } + echo $this->section_footer(); + } + + unset($sections[$section]); + } + + if ($PAGE->user_is_editing() and has_capability('moodle/course:update', $context)) { + // Print stealth sections if present. + $modinfo = get_fast_modinfo($course); + foreach ($sections as $section => $thissection) { + if (empty($modinfo->sections[$section])) { + continue; + } + echo $this->stealth_section_header($section); + print_section($course, $thissection, $mods, $modnamesused); + echo $this->stealth_section_footer(); + } + } + + echo $this->end_section_list(); + } +} diff --git a/course/format/topics/format.php b/course/format/topics/format.php index 6f2cb3e00dc..0764ceb5b6c 100644 --- a/course/format/topics/format.php +++ b/course/format/topics/format.php @@ -1,28 +1,26 @@ . -// Display the whole course as "topics" made of of modules -// Included from "view.php" /** - * Evaluation topics format for course display - NO layout tables, for accessibility, etc. + * Topics course format. Display the whole course as "topics" made of modules. * - * A duplicate course format to enable the Moodle development team to evaluate - * CSS for the multi-column layout in place of layout tables. - * Less risk for the Moodle 1.6 beta release. - * 1. Straight copy of topics/format.php - * 2. Replace and
with DIVs; inline styles. - * 3. Reorder columns so that in linear view content is first then blocks; - * styles to maintain original graphical (side by side) view. - * - * Target: 3-column graphical view using relative widths for pixel screen sizes - * 800x600, 1024x768... on IE6, Firefox. Below 800 columns will shift downwards. - * - * http://www.maxdesign.com.au/presentation/em/ Ideal length for content. - * http://www.svendtofte.com/code/max_width_in_ie/ Max width in IE. - * - * @copyright © 2006 The Open University + * @package format_topics + * @copyright 2006 The Open University * @author N.D.Freear@open.ac.uk, and others. - * @license http://www.gnu.org/copyleft/gpl.html GNU Public License - * @package + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); @@ -30,7 +28,7 @@ defined('MOODLE_INTERNAL') || die(); require_once($CFG->libdir.'/filelib.php'); require_once($CFG->libdir.'/completionlib.php'); -// Horrible backwards compatible parameter aliasing +// Horrible backwards compatible parameter aliasing.. if ($topic = optional_param('topic', 0, PARAM_INT)) { $url = $PAGE->url; $url->param('section', $topic); @@ -39,244 +37,20 @@ if ($topic = optional_param('topic', 0, PARAM_INT)) { } // End backwards-compatible aliasing.. -$context = get_context_instance(CONTEXT_COURSE, $course->id); +$context = context_course::instance($course->id); if (($marker >=0) && has_capability('moodle/course:setcurrentsection', $context) && confirm_sesskey()) { $course->marker = $marker; course_set_marker($course->id, $marker); } -$streditsummary = get_string('editsummary'); -$stradd = get_string('add'); -$stractivities = get_string('activities'); -$strtopic = get_string('topic'); -$strgroups = get_string('groups'); -$strgroupmy = get_string('groupmy'); -$editing = $PAGE->user_is_editing(); +$renderer = $PAGE->get_renderer('format_topics'); -if ($editing) { - $strtopichide = get_string('hidefromothers', 'format_topics'); - $strtopicshow = get_string('showfromothers', 'format_topics'); - $strmarkthistopic = get_string('markthistopic'); - $strmarkedthistopic = get_string('markedthistopic'); - $strmoveup = get_string('moveup'); - $strmovedown = get_string('movedown'); +if (!empty($displaysection) && $course->coursedisplay == COURSE_DISPLAY_MULTIPAGE) { + $renderer->print_single_section_page($course, $sections, $mods, $modnames, $modnamesused, $displaysection); +} else { + $renderer->print_multiple_section_page($course, $sections, $mods, $modnames, $modnamesused); } -// Print the Your progress icon if the track completion is enabled -$completioninfo = new completion_info($course); -echo $completioninfo->display_help_icon(); - -echo $OUTPUT->heading(get_string('topicoutline'), 2, 'headingblock header outline'); - -// Note, an ordered list would confuse - "1" could be the clipboard or summary. -echo "
    \n"; - -/// If currently moving a file then show the current clipboard -if (ismoving($course->id)) { - $stractivityclipboard = strip_tags(get_string('activityclipboard', '', $USER->activitycopyname)); - $strcancel= get_string('cancel'); - echo '
  • '; - echo $stractivityclipboard.'  ('.$strcancel.')'; - echo "
  • \n"; -} - -/// Print Section 0 with general activities - -$section = 0; -$thissection = $sections[$section]; -unset($sections[0]); - -if ($thissection->summary or $thissection->sequence or $PAGE->user_is_editing()) { - - // Note, no need for a 'left side' cell or DIV. - // Note, 'right side' is BEFORE content. - echo '
  • '; - echo '
     
    '; - echo '
     
    '; - echo '
    '; - if (!is_null($thissection->name)) { - echo $OUTPUT->heading(format_string($thissection->name, true, array('context' => $context)), 3, 'sectionname'); - } - echo '
    '; - - $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); - $summarytext = file_rewrite_pluginfile_urls($thissection->summary, 'pluginfile.php', $coursecontext->id, 'course', 'section', $thissection->id); - $summaryformatoptions = new stdClass(); - $summaryformatoptions->noclean = true; - $summaryformatoptions->overflowdiv = true; - echo format_text($summarytext, $thissection->summaryformat, $summaryformatoptions); - - if ($PAGE->user_is_editing() && has_capability('moodle/course:update', $coursecontext)) { - echo ''.$streditsummary.''; - } - echo '
    '; - - print_section($course, $thissection, $mods, $modnamesused); - - if ($PAGE->user_is_editing()) { - print_section_add_menus($course, $section, $modnames); - } - - echo '
    '; - echo "
  • \n"; -} - - -/// Now all the normal modules by topic -/// Everything below uses "section" terminology - each "section" is a topic. - -$section = 1; -$sectionmenu = array(); - -while ($section <= $course->numsections) { - - if (!empty($sections[$section])) { - $thissection = $sections[$section]; - - } else { - $thissection = new stdClass; - $thissection->course = $course->id; // Create a new section structure - $thissection->section = $section; - $thissection->name = null; - $thissection->summary = ''; - $thissection->summaryformat = FORMAT_HTML; - $thissection->visible = 1; - $thissection->id = $DB->insert_record('course_sections', $thissection); - } - - $showsection = (has_capability('moodle/course:viewhiddensections', $context) or $thissection->visible or !$course->hiddensections); - - if (!empty($displaysection) and $displaysection != $section) { // Check this topic is visible - if ($showsection) { - $sectionmenu[$section] = get_section_name($course, $thissection); - } - $section++; - continue; - } - - if ($showsection) { - - $currenttopic = ($course->marker == $section); - - $currenttext = ''; - if (!$thissection->visible) { - $sectionstyle = ' hidden'; - } else if ($currenttopic) { - $sectionstyle = ' current'; - $currenttext = get_accesshide(get_string('currenttopic','access')); - } else { - $sectionstyle = ''; - } - - echo '
  • '; //'
     
    '; - - echo '
    '.$currenttext.$section.'
    '; - // Note, 'right side' is BEFORE content. - echo '
    '; - - if ($PAGE->user_is_editing() && has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id))) { - - if ($course->marker == $section) { // Show the "light globe" on/off - echo ''.''.$strmarkedthistopic.'
    '; - } else { - echo ''.''.$strmarkthistopic.'
    '; - } - - if ($thissection->visible) { // Show the hide/show eye - echo ''. - ''.$strtopichide.'
    '; - } else { - echo ''. - ''.$strtopicshow.'
    '; - } - if ($section > 1) { // Add a arrow to move section up - echo ''. - ''.$strmoveup.'
    '; - } - - if ($section < $course->numsections) { // Add a arrow to move section down - echo ''. - ''.$strmovedown.'
    '; - } - } - echo '
    '; - - echo '
    '; - if (!has_capability('moodle/course:viewhiddensections', $context) and !$thissection->visible) { // Hidden for students - echo get_string('notavailable'); - } else { - if (!is_null($thissection->name)) { - echo $OUTPUT->heading(format_string($thissection->name, true, array('context' => $context)), 3, 'sectionname'); - } - echo '
    '; - if ($thissection->summary) { - $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); - $summarytext = file_rewrite_pluginfile_urls($thissection->summary, 'pluginfile.php', $coursecontext->id, 'course', 'section', $thissection->id); - $summaryformatoptions = new stdClass(); - $summaryformatoptions->noclean = true; - $summaryformatoptions->overflowdiv = true; - echo format_text($summarytext, $thissection->summaryformat, $summaryformatoptions); - } else { - echo ' '; - } - - if ($PAGE->user_is_editing() && has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id))) { - echo ' '. - ''.$streditsummary.'

    '; - } - echo '
    '; - - print_section($course, $thissection, $mods, $modnamesused); - echo '
    '; - if ($PAGE->user_is_editing()) { - print_section_add_menus($course, $section, $modnames); - } - } - - echo '
    '; - echo "
  • \n"; - } - - unset($sections[$section]); - $section++; -} - -if (!$displaysection and $PAGE->user_is_editing() and has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id))) { - // print stealth sections if present - $modinfo = get_fast_modinfo($course); - foreach ($sections as $section=>$thissection) { - if (empty($modinfo->sections[$section])) { - continue; - } - - echo '\n"; - } -} - - -echo "
\n"; - -if (!empty($sectionmenu)) { - $select = new single_select(new moodle_url('/course/view.php', array('id'=>$course->id)), 'topic', $sectionmenu); - $select->label = get_string('jumpto'); - $select->class = 'jumpmenu'; - $select->formid = 'sectionmenu'; - echo $OUTPUT->render($select); -} - - // Include course format js module - $PAGE->requires->js('/course/format/topics/format.js'); +// Include course format js module +$PAGE->requires->js('/course/format/topics/format.js'); diff --git a/course/format/topics/lang/en/format_topics.php b/course/format/topics/lang/en/format_topics.php index 2a62a7a4c3d..f9766d9a6e4 100644 --- a/course/format/topics/lang/en/format_topics.php +++ b/course/format/topics/lang/en/format_topics.php @@ -23,6 +23,7 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +$string['currentsection'] = 'This topic'; $string['sectionname'] = 'Topic'; $string['pluginname'] = 'Topics format'; $string['section0name'] = 'General'; diff --git a/course/format/topics/renderer.php b/course/format/topics/renderer.php new file mode 100644 index 00000000000..d5760b4e32b --- /dev/null +++ b/course/format/topics/renderer.php @@ -0,0 +1,105 @@ +. + +/** + * Renderer for outputting the topics course format. + * + * @package format_topics + * @copyright 2012 Dan Poltawski + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.3 + */ + + +defined('MOODLE_INTERNAL') || die(); +require_once($CFG->dirroot.'/course/format/renderer.php'); + +/** + * Basic renderer for topics format. + * + * @copyright 2012 Dan Poltawski + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class format_topics_renderer extends format_renderer_base { + + /** + * Generate the starting container html for a list of sections + * @return string HTML to output. + */ + public function start_section_list() { + return html_writer::start_tag('ul', array('class' => 'topics')); + } + + /** + * Generate the closing container html for a list of sections + * @return string HTML to output. + */ + public function end_section_list() { + return html_writer::end_tag('ul'); + } + + /** + * Generate the title for this section page + * @return string the page title + */ + public function page_title() { + return get_string('topicoutline'); + } + + /** + * Generate the edit controls of a section + * + * @param stdClass $course The course entry from DB + * @param stdClass $section The course_section entry from DB + * @param bool $onsectionpage true if being printed on a section page + * @return array of links with edit controls + */ + public function section_edit_controls($course, $section, $onsectionpage = false) { + global $PAGE; + + if (!$PAGE->user_is_editing()) { + return array(); + } + + if (!has_capability('moodle/course:update', context_course::instance($course->id))) { + return array(); + } + + if ($onsectionpage) { + $url = course_get_url($course, $section->section); + } else { + $url = course_get_url($course); + } + $url->param('sesskey', sesskey()); + + $controls = array(); + if ($course->marker == $section->section) { // Show the "light globe" on/off. + $url->param('marker', 0); + $controls[] = html_writer::link($url, + html_writer::empty_tag('img', array('src' => $this->output->pix_url('i/marked'), + 'class' => 'icon ', 'alt' => get_string('markedthistopic'))), + array('title' => get_string('markedthistopic'), 'class' => 'editing_highlight')); + } else { + $url->param('marker', $section->section); + $controls[] = html_writer::link($url, + html_writer::empty_tag('img', array('src' => $this->output->pix_url('i/marker'), + 'class' => 'icon', 'alt' => get_string('markthistopic'))), + array('title' => get_string('markthistopic'), 'class' => 'editing_highlight')); + } + + return array_merge($controls, parent::section_edit_controls($course, $section, $onsectionpage)); + } +} diff --git a/course/format/topics/version.php b/course/format/topics/version.php index fa0cfaac557..6f0e3713bc9 100644 --- a/course/format/topics/version.php +++ b/course/format/topics/version.php @@ -25,6 +25,6 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2011120100; // The current plugin version (Date: YYYYMMDDXX) -$plugin->requires = 2011120100; // Requires this Moodle version -$plugin->component = 'format_topics'; // Full name of the plugin (used for diagnostics) +$plugin->version = 2012042900; // The current plugin version (Date: YYYYMMDDXX). +$plugin->requires = 2012042800.03; // Requires this Moodle version. +$plugin->component = 'format_topics'; // Full name of the plugin (used for diagnostics). diff --git a/course/format/weeks/format.php b/course/format/weeks/format.php index 336df358800..5d70cc51d69 100644 --- a/course/format/weeks/format.php +++ b/course/format/weeks/format.php @@ -1,282 +1,48 @@ . + /** - * Evaluation weekly format for course display - NO layout tables, for accessibility, etc. + * Weeks course format. Display the whole course as "weeks" made of modules. * - * A duplicate course format to enable the Moodle development team to evaluate - * CSS for the multi-column layout in place of layout tables. - * Less risk for the Moodle 1.6 beta release. - * 1. Straight copy of weeks/format.php - * 2. Replace and
with DIVs; inline styles. - * 3. Reorder columns so that in linear view content is first then blocks; - * styles to maintain original graphical (side by side) view. - * - * Target: 3-column graphical view using relative widths for pixel screen sizes - * 800x600, 1024x768... on IE6, Firefox. Below 800 columns will shift downwards. - * - * http://www.maxdesign.com.au/presentation/em/ Ideal length for content. - * http://www.svendtofte.com/code/max_width_in_ie/ Max width in IE. - * - * @copyright © 2006 The Open University + * @package format_weeks + * @copyright 2006 The Open University * @author N.D.Freear@open.ac.uk, and others. - * @license http://www.gnu.org/copyleft/gpl.html GNU Public License - * @package + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); - require_once($CFG->libdir.'/filelib.php'); - require_once($CFG->libdir.'/completionlib.php'); +require_once($CFG->libdir.'/filelib.php'); +require_once($CFG->libdir.'/completionlib.php'); - $streditsummary = get_string('editsummary'); - $stradd = get_string('add'); - $stractivities = get_string('activities'); - $strweek = get_string('week'); - $strgroups = get_string('groups'); - $strgroupmy = get_string('groupmy'); - $editing = $PAGE->user_is_editing(); +// Horrible backwards compatible parameter aliasing.. +if ($week = optional_param('week', 0, PARAM_INT)) { + $url = $PAGE->url; + $url->param('section', $week); + debugging('Outdated week param passed to course/view.php', DEBUG_DEVELOPER); + redirect($url); +} +// End backwards-compatible aliasing.. - if ($editing) { - $strweekhide = get_string('hidefromothers', 'format_topics'); - $strweekshow = get_string('showfromothers', 'format_topics'); - $strmoveup = get_string('moveup'); - $strmovedown = get_string('movedown'); - } +$renderer = $PAGE->get_renderer('format_weeks'); - // Horrible backwards compatible parameter aliasing - if ($week = optional_param('week', 0, PARAM_INT)) { - $url = $PAGE->url; - $url->param('section', $week); - debugging('Outdated week param passed to course/view.php', DEBUG_DEVELOPER); - redirect($url); - } - // End backwards-compatible aliasing.. +if (!empty($displaysection) && $course->coursedisplay == COURSE_DISPLAY_MULTIPAGE) { + $renderer->print_single_section_page($course, $sections, $mods, $modnames, $modnamesused, $displaysection); +} else { + $renderer->print_multiple_section_page($course, $sections, $mods, $modnames, $modnamesused); +} - $context = get_context_instance(CONTEXT_COURSE, $course->id); - - //Print the Your progress icon if the track completion is enabled - $completioninfo = new completion_info($course); - echo $completioninfo->display_help_icon(); - - echo $OUTPUT->heading(get_string('weeklyoutline'), 2, 'headingblock header outline'); - - // Note, an ordered list would confuse - "1" could be the clipboard or summary. - echo "
    \n"; - -/// If currently moving a file then show the current clipboard - if (ismoving($course->id)) { - $stractivityclipboard = strip_tags(get_string('activityclipboard', '', $USER->activitycopyname)); - $strcancel= get_string('cancel'); - echo '
  • '; - echo $stractivityclipboard.'  ('.$strcancel.')'; - echo "
  • \n"; - } - -/// Print Section 0 with general activities - - $section = 0; - $thissection = $sections[$section]; - unset($sections[0]); - - if ($thissection->summary or $thissection->sequence or $PAGE->user_is_editing()) { - - // Note, 'right side' is BEFORE content. - echo '
  • '; - echo '
     
    '; - echo '
     
    '; - echo '
    '; - - if (!empty($thissection->name)) { - echo $OUTPUT->heading(format_string($thissection->name, true, array('context' => $context)), 3, 'sectionname'); - } - - echo '
    '; - - $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); - $summarytext = file_rewrite_pluginfile_urls($thissection->summary, 'pluginfile.php', $coursecontext->id, 'course', 'section', $thissection->id); - $summaryformatoptions = new stdClass; - $summaryformatoptions->noclean = true; - $summaryformatoptions->overflowdiv = true; - echo format_text($summarytext, $thissection->summaryformat, $summaryformatoptions); - - if ($PAGE->user_is_editing() && has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id))) { - echo '

    '.$streditsummary.'

    '; - } - echo '
    '; - - print_section($course, $thissection, $mods, $modnamesused); - - if ($PAGE->user_is_editing()) { - print_section_add_menus($course, $section, $modnames); - } - - echo '
    '; - echo "
  • \n"; - } - - -/// Now all the normal modules by week -/// Everything below uses "section" terminology - each "section" is a week. - - $timenow = time(); - $weekdate = $course->startdate; // this should be 0:00 Monday of that week - $weekdate += 7200; // Add two hours to avoid possible DST problems - $section = 1; - $sectionmenu = array(); - $weekofseconds = 604800; - $course->enddate = $course->startdate + ($weekofseconds * $course->numsections); - - $strftimedateshort = ' '.get_string('strftimedateshort'); - - while ($weekdate < $course->enddate) { - - $nextweekdate = $weekdate + ($weekofseconds); - $weekday = userdate($weekdate, $strftimedateshort); - $endweekday = userdate($weekdate+518400, $strftimedateshort); - - if (!empty($sections[$section])) { - $thissection = $sections[$section]; - - } else { - $thissection = new stdClass(); - $thissection->course = $course->id; // Create a new week structure - $thissection->section = $section; - $thissection->name = null; - $thissection->summary = ''; - $thissection->summaryformat = FORMAT_HTML; - $thissection->visible = 1; - $thissection->id = $DB->insert_record('course_sections', $thissection); - } - - $showsection = (has_capability('moodle/course:viewhiddensections', $context) or $thissection->visible or !$course->hiddensections); - - if (!empty($displaysection) and $displaysection != $section) { // Check this week is visible - if ($showsection) { - $sectionmenu[$section] = get_section_name($course, $thissection); - } - $section++; - $weekdate = $nextweekdate; - continue; - } - - if ($showsection) { - - $currentweek = (($weekdate <= $timenow) && ($timenow < $nextweekdate)); - - $currenttext = ''; - if (!$thissection->visible) { - $sectionstyle = ' hidden'; - } else if ($currentweek) { - $sectionstyle = ' current'; - $currenttext = get_accesshide(get_string('currentweek','access')); - } else { - $sectionstyle = ''; - } - - echo '
  • '; - - echo '
     '.$currenttext.'
    '; - - // Note, 'right side' is BEFORE content. - echo '
    '; - - if ($PAGE->user_is_editing() && has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id))) { - if ($thissection->visible) { // Show the hide/show eye - echo ''. - ''.$strweekhide.'
    '; - } else { - echo ''. - ''.$strweekshow.'
    '; - } - if ($section > 1) { // Add a arrow to move section up - echo ''. - ''.$strmoveup.'
    '; - } - - if ($section < $course->numsections) { // Add a arrow to move section down - echo ''. - ''.$strmovedown.'
    '; - } - } - echo '
    '; - - $weekperiod = $weekday.' - '.$endweekday; - - echo '
    '; - if (!has_capability('moodle/course:viewhiddensections', $context) and !$thissection->visible) { // Hidden for students - echo $OUTPUT->heading($currenttext.$weekperiod.' ('.get_string('notavailable').')', 3, 'weekdates'); - - } else { - if (isset($thissection->name) && ($thissection->name !== NULL)) { // empty string is ok - echo $OUTPUT->heading(format_string($thissection->name, true, array('context' => $context)), 3, 'weekdates'); - } else { - echo $OUTPUT->heading($currenttext.$weekperiod, 3, 'weekdates'); - } - echo '
    '; - $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); - $summarytext = file_rewrite_pluginfile_urls($thissection->summary, 'pluginfile.php', $coursecontext->id, 'course', 'section', $thissection->id); - $summaryformatoptions = new stdClass; - $summaryformatoptions->noclean = true; - $summaryformatoptions->overflowdiv = true; - echo format_text($summarytext, $thissection->summaryformat, $summaryformatoptions); - - if ($PAGE->user_is_editing() && has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id))) { - echo ' '. - ''.$streditsummary.'

    '; - } - echo '
    '; - - print_section($course, $thissection, $mods, $modnamesused); - - if ($PAGE->user_is_editing()) { - print_section_add_menus($course, $section, $modnames); - } - } - - echo '
    '; - echo "
  • \n"; - } - - unset($sections[$section]); - $section++; - $weekdate = $nextweekdate; - } - - if (!$displaysection and $PAGE->user_is_editing() and has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id))) { - // print stealth sections if present - $modinfo = get_fast_modinfo($course); - foreach ($sections as $section=>$thissection) { - if (empty($modinfo->sections[$section])) { - continue; - } - - echo '\n"; - } - } - - echo "
\n"; - - if (!empty($sectionmenu)) { - $select = new single_select(new moodle_url('/course/view.php', array('id'=>$course->id)), 'week', $sectionmenu); - $select->label = get_string('jumpto'); - $select->class = 'jumpmenu'; - $select->formid = 'sectionmenu'; - echo $OUTPUT->render($select); - } - - // Include course format js module - $PAGE->requires->js('/course/format/weeks/format.js'); +$PAGE->requires->js('/course/format/weeks/format.js'); diff --git a/course/format/weeks/lang/en/format_weeks.php b/course/format/weeks/lang/en/format_weeks.php index 02de087623b..fd6c24d09fa 100644 --- a/course/format/weeks/lang/en/format_weeks.php +++ b/course/format/weeks/lang/en/format_weeks.php @@ -23,6 +23,7 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +$string['currentsection'] = 'This week'; $string['sectionname'] = 'Week'; $string['pluginname'] = 'Weekly format'; $string['section0name'] = 'General'; diff --git a/course/format/weeks/renderer.php b/course/format/weeks/renderer.php new file mode 100644 index 00000000000..05836906f27 --- /dev/null +++ b/course/format/weeks/renderer.php @@ -0,0 +1,61 @@ +. + +/** + * Renderer for outputting the weeks course format. + * + * @package format_weeks + * @copyright 2012 Dan Poltawski + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.3 + */ + + +defined('MOODLE_INTERNAL') || die(); +require_once($CFG->dirroot.'/course/format/renderer.php'); + + +/** + * Basic renderer for weeks format. + * + * @copyright 2012 Dan Poltawski + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class format_weeks_renderer extends format_renderer_base { + /** + * Generate the starting container html for a list of sections + * @return string HTML to output. + */ + public function start_section_list() { + return html_writer::start_tag('ul', array('class' => 'weeks')); + } + + /** + * Generate the closing container html for a list of sections + * @return string HTML to output. + */ + public function end_section_list() { + return html_writer::end_tag('ul'); + } + + /** + * Generate the title for this section page + * @return string the page title + */ + public function page_title() { + return get_string('weeklyoutline'); + } +} diff --git a/course/format/weeks/version.php b/course/format/weeks/version.php index cf80a61ed36..281b16e4344 100644 --- a/course/format/weeks/version.php +++ b/course/format/weeks/version.php @@ -25,6 +25,6 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2011120100; // The current plugin version (Date: YYYYMMDDXX) -$plugin->requires = 2011120100; // Requires this Moodle version -$plugin->component = 'format_weeks'; // Full name of the plugin (used for diagnostics) +$plugin->version = 2012042900; // The current plugin version (Date: YYYYMMDDXX). +$plugin->requires = 2012042800.03; // Requires this Moodle version. +$plugin->component = 'format_weeks'; // Full name of the plugin (used for diagnostics). diff --git a/lang/en/access.php b/lang/en/access.php index b09a782be62..b338d424d16 100644 --- a/lang/en/access.php +++ b/lang/en/access.php @@ -30,8 +30,6 @@ $string['accessstatement'] = 'Accessibility statement'; $string['activitynext'] = 'Next activity'; $string['activityprev'] = 'Previous activity'; $string['breadcrumb'] = 'Breadcrumb trail'; -$string['currenttopic'] = 'This topic'; -$string['currentweek'] = 'This week'; $string['hideblocka'] = 'Hide {$a} block'; $string['monthnext'] = 'Next month'; $string['monthprev'] = 'Previous month'; diff --git a/theme/base/style/course.css b/theme/base/style/course.css index ecb2c3c0f72..18652c32c93 100644 --- a/theme/base/style/course.css +++ b/theme/base/style/course.css @@ -8,6 +8,11 @@ .course-content .section .activity img.activityicon {vertical-align:middle;height:16px;width:16px;} .course-content .section .activity .commands img.iconsmall {vertical-align: baseline;} +.course-content .section-summary { border: 1px solid #DDD; margin-top: 5px; } +.course-content .section-summary .section-title { margin: 2px 5px 2px 5px; } +.course-content .section-summary .summarytext { margin: 2px 5px 2px 5px; } +.course-content .section-navigation { display: block; padding: 10px } +.course-content .section-navigation .right { float: right; } #page-site-index .subscribelink {text-align:right;} #page-site-index .headingblock {margin-bottom: 9px;}