[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 * This file contains main class for the course format Topic 19 * 20 * @since Moodle 2.0 21 * @package format_topics 22 * @copyright 2009 Sam Hemelryk 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 require_once($CFG->dirroot. '/course/format/lib.php'); 28 29 /** 30 * Main class for the Topics course format 31 * 32 * @package format_topics 33 * @copyright 2012 Marina Glancy 34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 */ 36 class format_topics extends format_base { 37 38 /** 39 * Returns true if this course format uses sections 40 * 41 * @return bool 42 */ 43 public function uses_sections() { 44 return true; 45 } 46 47 /** 48 * Returns the display name of the given section that the course prefers. 49 * 50 * Use section name is specified by user. Otherwise use default ("Topic #") 51 * 52 * @param int|stdClass $section Section object from database or just field section.section 53 * @return string Display name that the course format prefers, e.g. "Topic 2" 54 */ 55 public function get_section_name($section) { 56 $section = $this->get_section($section); 57 if ((string)$section->name !== '') { 58 return format_string($section->name, true, 59 array('context' => context_course::instance($this->courseid))); 60 } else { 61 return $this->get_default_section_name($section); 62 } 63 } 64 65 /** 66 * Returns the default section name for the topics course format. 67 * 68 * If the section number is 0, it will use the string with key = section0name from the course format's lang file. 69 * If the section number is not 0, the base implementation of format_base::get_default_section_name which uses 70 * the string with the key = 'sectionname' from the course format's lang file + the section number will be used. 71 * 72 * @param stdClass $section Section object from database or just field course_sections section 73 * @return string The default value for the section name. 74 */ 75 public function get_default_section_name($section) { 76 if ($section->section == 0) { 77 // Return the general section. 78 return get_string('section0name', 'format_topics'); 79 } else { 80 // Use format_base::get_default_section_name implementation which 81 // will display the section name in "Topic n" format. 82 return parent::get_default_section_name($section); 83 } 84 } 85 86 /** 87 * The URL to use for the specified course (with section) 88 * 89 * @param int|stdClass $section Section object from database or just field course_sections.section 90 * if omitted the course view page is returned 91 * @param array $options options for view URL. At the moment core uses: 92 * 'navigation' (bool) if true and section has no separate page, the function returns null 93 * 'sr' (int) used by multipage formats to specify to which section to return 94 * @return null|moodle_url 95 */ 96 public function get_view_url($section, $options = array()) { 97 global $CFG; 98 $course = $this->get_course(); 99 $url = new moodle_url('/course/view.php', array('id' => $course->id)); 100 101 $sr = null; 102 if (array_key_exists('sr', $options)) { 103 $sr = $options['sr']; 104 } 105 if (is_object($section)) { 106 $sectionno = $section->section; 107 } else { 108 $sectionno = $section; 109 } 110 if ($sectionno !== null) { 111 if ($sr !== null) { 112 if ($sr) { 113 $usercoursedisplay = COURSE_DISPLAY_MULTIPAGE; 114 $sectionno = $sr; 115 } else { 116 $usercoursedisplay = COURSE_DISPLAY_SINGLEPAGE; 117 } 118 } else { 119 $usercoursedisplay = $course->coursedisplay; 120 } 121 if ($sectionno != 0 && $usercoursedisplay == COURSE_DISPLAY_MULTIPAGE) { 122 $url->param('section', $sectionno); 123 } else { 124 if (empty($CFG->linkcoursesections) && !empty($options['navigation'])) { 125 return null; 126 } 127 $url->set_anchor('section-'.$sectionno); 128 } 129 } 130 return $url; 131 } 132 133 /** 134 * Returns the information about the ajax support in the given source format 135 * 136 * The returned object's property (boolean)capable indicates that 137 * the course format supports Moodle course ajax features. 138 * 139 * @return stdClass 140 */ 141 public function supports_ajax() { 142 $ajaxsupport = new stdClass(); 143 $ajaxsupport->capable = true; 144 return $ajaxsupport; 145 } 146 147 /** 148 * Loads all of the course sections into the navigation 149 * 150 * @param global_navigation $navigation 151 * @param navigation_node $node The course node within the navigation 152 */ 153 public function extend_course_navigation($navigation, navigation_node $node) { 154 global $PAGE; 155 // if section is specified in course/view.php, make sure it is expanded in navigation 156 if ($navigation->includesectionnum === false) { 157 $selectedsection = optional_param('section', null, PARAM_INT); 158 if ($selectedsection !== null && (!defined('AJAX_SCRIPT') || AJAX_SCRIPT == '0') && 159 $PAGE->url->compare(new moodle_url('/course/view.php'), URL_MATCH_BASE)) { 160 $navigation->includesectionnum = $selectedsection; 161 } 162 } 163 164 // check if there are callbacks to extend course navigation 165 parent::extend_course_navigation($navigation, $node); 166 167 // We want to remove the general section if it is empty. 168 $modinfo = get_fast_modinfo($this->get_course()); 169 $sections = $modinfo->get_sections(); 170 if (!isset($sections[0])) { 171 // The general section is empty to find the navigation node for it we need to get its ID. 172 $section = $modinfo->get_section_info(0); 173 $generalsection = $node->get($section->id, navigation_node::TYPE_SECTION); 174 if ($generalsection) { 175 // We found the node - now remove it. 176 $generalsection->remove(); 177 } 178 } 179 } 180 181 /** 182 * Custom action after section has been moved in AJAX mode 183 * 184 * Used in course/rest.php 185 * 186 * @return array This will be passed in ajax respose 187 */ 188 function ajax_section_move() { 189 global $PAGE; 190 $titles = array(); 191 $course = $this->get_course(); 192 $modinfo = get_fast_modinfo($course); 193 $renderer = $this->get_renderer($PAGE); 194 if ($renderer && ($sections = $modinfo->get_section_info_all())) { 195 foreach ($sections as $number => $section) { 196 $titles[$number] = $renderer->section_title($section, $course); 197 } 198 } 199 return array('sectiontitles' => $titles, 'action' => 'move'); 200 } 201 202 /** 203 * Returns the list of blocks to be automatically added for the newly created course 204 * 205 * @return array of default blocks, must contain two keys BLOCK_POS_LEFT and BLOCK_POS_RIGHT 206 * each of values is an array of block names (for left and right side columns) 207 */ 208 public function get_default_blocks() { 209 return array( 210 BLOCK_POS_LEFT => array(), 211 BLOCK_POS_RIGHT => array('search_forums', 'news_items', 'calendar_upcoming', 'recent_activity') 212 ); 213 } 214 215 /** 216 * Definitions of the additional options that this course format uses for course 217 * 218 * Topics format uses the following options: 219 * - coursedisplay 220 * - numsections 221 * - hiddensections 222 * 223 * @param bool $foreditform 224 * @return array of options 225 */ 226 public function course_format_options($foreditform = false) { 227 static $courseformatoptions = false; 228 if ($courseformatoptions === false) { 229 $courseconfig = get_config('moodlecourse'); 230 $courseformatoptions = array( 231 'numsections' => array( 232 'default' => $courseconfig->numsections, 233 'type' => PARAM_INT, 234 ), 235 'hiddensections' => array( 236 'default' => $courseconfig->hiddensections, 237 'type' => PARAM_INT, 238 ), 239 'coursedisplay' => array( 240 'default' => $courseconfig->coursedisplay, 241 'type' => PARAM_INT, 242 ), 243 ); 244 } 245 if ($foreditform && !isset($courseformatoptions['coursedisplay']['label'])) { 246 $courseconfig = get_config('moodlecourse'); 247 $max = $courseconfig->maxsections; 248 if (!isset($max) || !is_numeric($max)) { 249 $max = 52; 250 } 251 $sectionmenu = array(); 252 for ($i = 0; $i <= $max; $i++) { 253 $sectionmenu[$i] = "$i"; 254 } 255 $courseformatoptionsedit = array( 256 'numsections' => array( 257 'label' => new lang_string('numberweeks'), 258 'element_type' => 'select', 259 'element_attributes' => array($sectionmenu), 260 ), 261 'hiddensections' => array( 262 'label' => new lang_string('hiddensections'), 263 'help' => 'hiddensections', 264 'help_component' => 'moodle', 265 'element_type' => 'select', 266 'element_attributes' => array( 267 array( 268 0 => new lang_string('hiddensectionscollapsed'), 269 1 => new lang_string('hiddensectionsinvisible') 270 ) 271 ), 272 ), 273 'coursedisplay' => array( 274 'label' => new lang_string('coursedisplay'), 275 'element_type' => 'select', 276 'element_attributes' => array( 277 array( 278 COURSE_DISPLAY_SINGLEPAGE => new lang_string('coursedisplay_single'), 279 COURSE_DISPLAY_MULTIPAGE => new lang_string('coursedisplay_multi') 280 ) 281 ), 282 'help' => 'coursedisplay', 283 'help_component' => 'moodle', 284 ) 285 ); 286 $courseformatoptions = array_merge_recursive($courseformatoptions, $courseformatoptionsedit); 287 } 288 return $courseformatoptions; 289 } 290 291 /** 292 * Adds format options elements to the course/section edit form. 293 * 294 * This function is called from {@link course_edit_form::definition_after_data()}. 295 * 296 * @param MoodleQuickForm $mform form the elements are added to. 297 * @param bool $forsection 'true' if this is a section edit form, 'false' if this is course edit form. 298 * @return array array of references to the added form elements. 299 */ 300 public function create_edit_form_elements(&$mform, $forsection = false) { 301 $elements = parent::create_edit_form_elements($mform, $forsection); 302 303 // Increase the number of sections combo box values if the user has increased the number of sections 304 // using the icon on the course page beyond course 'maxsections' or course 'maxsections' has been 305 // reduced below the number of sections already set for the course on the site administration course 306 // defaults page. This is so that the number of sections is not reduced leaving unintended orphaned 307 // activities / resources. 308 if (!$forsection) { 309 $maxsections = get_config('moodlecourse', 'maxsections'); 310 $numsections = $mform->getElementValue('numsections'); 311 $numsections = $numsections[0]; 312 if ($numsections > $maxsections) { 313 $element = $mform->getElement('numsections'); 314 for ($i = $maxsections+1; $i <= $numsections; $i++) { 315 $element->addOption("$i", $i); 316 } 317 } 318 } 319 return $elements; 320 } 321 322 /** 323 * Updates format options for a course 324 * 325 * In case if course format was changed to 'topics', we try to copy options 326 * 'coursedisplay', 'numsections' and 'hiddensections' from the previous format. 327 * If previous course format did not have 'numsections' option, we populate it with the 328 * current number of sections 329 * 330 * @param stdClass|array $data return value from {@link moodleform::get_data()} or array with data 331 * @param stdClass $oldcourse if this function is called from {@link update_course()} 332 * this object contains information about the course before update 333 * @return bool whether there were any changes to the options values 334 */ 335 public function update_course_format_options($data, $oldcourse = null) { 336 global $DB; 337 $data = (array)$data; 338 if ($oldcourse !== null) { 339 $oldcourse = (array)$oldcourse; 340 $options = $this->course_format_options(); 341 foreach ($options as $key => $unused) { 342 if (!array_key_exists($key, $data)) { 343 if (array_key_exists($key, $oldcourse)) { 344 $data[$key] = $oldcourse[$key]; 345 } else if ($key === 'numsections') { 346 // If previous format does not have the field 'numsections' 347 // and $data['numsections'] is not set, 348 // we fill it with the maximum section number from the DB 349 $maxsection = $DB->get_field_sql('SELECT max(section) from {course_sections} 350 WHERE course = ?', array($this->courseid)); 351 if ($maxsection) { 352 // If there are no sections, or just default 0-section, 'numsections' will be set to default 353 $data['numsections'] = $maxsection; 354 } 355 } 356 } 357 } 358 } 359 $changed = $this->update_format_options($data); 360 if ($changed && array_key_exists('numsections', $data)) { 361 // If the numsections was decreased, try to completely delete the orphaned sections (unless they are not empty). 362 $numsections = (int)$data['numsections']; 363 $maxsection = $DB->get_field_sql('SELECT max(section) from {course_sections} 364 WHERE course = ?', array($this->courseid)); 365 for ($sectionnum = $maxsection; $sectionnum > $numsections; $sectionnum--) { 366 if (!$this->delete_section($sectionnum, false)) { 367 break; 368 } 369 } 370 } 371 return $changed; 372 } 373 374 /** 375 * Whether this format allows to delete sections 376 * 377 * Do not call this function directly, instead use {@link course_can_delete_section()} 378 * 379 * @param int|stdClass|section_info $section 380 * @return bool 381 */ 382 public function can_delete_section($section) { 383 return true; 384 } 385 386 /** 387 * Prepares the templateable object to display section name 388 * 389 * @param \section_info|\stdClass $section 390 * @param bool $linkifneeded 391 * @param bool $editable 392 * @param null|lang_string|string $edithint 393 * @param null|lang_string|string $editlabel 394 * @return \core\output\inplace_editable 395 */ 396 public function inplace_editable_render_section_name($section, $linkifneeded = true, 397 $editable = null, $edithint = null, $editlabel = null) { 398 if (empty($edithint)) { 399 $edithint = new lang_string('editsectionname', 'format_topics'); 400 } 401 if (empty($editlabel)) { 402 $title = get_section_name($section->course, $section); 403 $editlabel = new lang_string('newsectionname', 'format_topics', $title); 404 } 405 return parent::inplace_editable_render_section_name($section, $linkifneeded, $editable, $edithint, $editlabel); 406 } 407 } 408 409 /** 410 * Implements callback inplace_editable() allowing to edit values in-place 411 * 412 * @param string $itemtype 413 * @param int $itemid 414 * @param mixed $newvalue 415 * @return \core\output\inplace_editable 416 */ 417 function format_topics_inplace_editable($itemtype, $itemid, $newvalue) { 418 global $DB, $CFG; 419 require_once($CFG->dirroot . '/course/lib.php'); 420 if ($itemtype === 'sectionname' || $itemtype === 'sectionnamenl') { 421 $section = $DB->get_record_sql( 422 'SELECT s.* FROM {course_sections} s JOIN {course} c ON s.course = c.id WHERE s.id = ? AND c.format = ?', 423 array($itemid, 'topics'), MUST_EXIST); 424 return course_get_format($section->course)->inplace_editable_update_section_name($section, $itemtype, $newvalue); 425 } 426 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |