Esempio n. 1
0
                        // Attempt to update the grade item if relevant
                        $grademodule = $DB->get_record($cm->modname, array('id' => $cm->instance));
                        $grademodule->cmidnumber = $cm->idnumber;
                        $grademodule->modname = $cm->modname;
                        grade_update_mod_grades($grademodule);
                        // We need to return strings after they've been through filters for multilang
                        $stringoptions = new stdClass();
                        $stringoptions->context = $coursecontext;
                        echo json_encode(array('instancename' => html_entity_decode(format_string($module->name, true, $stringoptions))));
                        break;
                }
                break;
            case 'course':
                switch ($field) {
                    case 'marker':
                        require_capability('moodle/course:setcurrentsection', $coursecontext);
                        course_set_marker($course->id, $value);
                        break;
                }
                break;
        }
        break;
    case 'DELETE':
        switch ($class) {
            case 'resource':
                require_capability('moodle/course:manageactivities', $modcontext);
                course_delete_module($cm->id);
                break;
        }
        break;
}
Esempio n. 2
0
 /**
  * Deletes a section
  *
  * Do not call this function directly, instead call {@link course_delete_section()}
  *
  * @param int|stdClass|section_info $section
  * @param bool $forcedeleteifnotempty if set to false section will not be deleted if it has modules in it.
  * @return bool whether section was deleted
  */
 public function delete_section($section, $forcedeleteifnotempty = false)
 {
     global $DB;
     if (!$this->uses_sections()) {
         // Not possible to delete section if sections are not used.
         return false;
     }
     if (!is_object($section)) {
         $section = $DB->get_record('course_sections', array('course' => $this->get_courseid(), 'section' => $section), 'id,section,sequence,summary');
     }
     if (!$section || !$section->section) {
         // Not possible to delete 0-section.
         return false;
     }
     if (!$forcedeleteifnotempty && (!empty($section->sequence) || !empty($section->summary))) {
         return false;
     }
     $course = $this->get_course();
     // Remove the marker if it points to this section.
     if ($section->section == $course->marker) {
         course_set_marker($course->id, 0);
     }
     $lastsection = $DB->get_field_sql('SELECT max(section) from {course_sections}
                         WHERE course = ?', array($course->id));
     // Find out if we need to descrease the 'numsections' property later.
     $courseformathasnumsections = array_key_exists('numsections', $this->get_format_options());
     $decreasenumsections = $courseformathasnumsections && $section->section <= $course->numsections;
     // Move the section to the end.
     move_section_to($course, $section->section, $lastsection, true);
     // Delete all modules from the section.
     foreach (preg_split('/,/', $section->sequence, -1, PREG_SPLIT_NO_EMPTY) as $cmid) {
         course_delete_module($cmid);
     }
     // Delete section and it's format options.
     $DB->delete_records('course_format_options', array('sectionid' => $section->id));
     $DB->delete_records('course_sections', array('id' => $section->id));
     rebuild_course_cache($course->id, true);
     // Descrease 'numsections' if needed.
     if ($decreasenumsections) {
         $this->update_course_format_options(array('numsections' => $course->numsections - 1));
     }
     return true;
 }
Esempio n. 3
0
/**
 * Moves a section within a course, from a position to another.
 * Be very careful: $section and $destination refer to section number,
 * not id!.
 *
 * @param object $course
 * @param int $section Section number (not id!!!)
 * @param int $destination
 * @return boolean Result
 */
function move_section_to($course, $section, $destination)
{
    /// Moves a whole course section up and down within the course
    global $USER, $DB;
    if (!$destination && $destination != 0) {
        return true;
    }
    if ($destination > $course->numsections) {
        return false;
    }
    // Get all sections for this course and re-order them (2 of them should now share the same section number)
    if (!($sections = $DB->get_records_menu('course_sections', array('course' => $course->id), 'section ASC, id ASC', 'id, section'))) {
        return false;
    }
    $movedsections = reorder_sections($sections, $section, $destination);
    // Update all sections. Do this in 2 steps to avoid breaking database
    // uniqueness constraint
    $transaction = $DB->start_delegated_transaction();
    foreach ($movedsections as $id => $position) {
        if ($sections[$id] !== $position) {
            $DB->set_field('course_sections', 'section', -$position, array('id' => $id));
        }
    }
    foreach ($movedsections as $id => $position) {
        if ($sections[$id] !== $position) {
            $DB->set_field('course_sections', 'section', $position, array('id' => $id));
        }
    }
    // Adjust destination to reflect the actual section
    $moveup = false;
    if ($section > $destination) {
        $destination++;
        $moveup = true;
    }
    // If we move the highlighted section itself, then just highlight the destination.
    // Adjust the higlighted section location if we move something over it either direction.
    if ($section == $course->marker) {
        course_set_marker($course, $destination);
    } elseif ($moveup && $section > $course->marker && $course->marker >= $destination) {
        course_set_marker($course, $course->marker + 1);
    } elseif (!$moveup && $section < $course->marker && $course->marker <= $destination) {
        course_set_marker($course, $course->marker - 1);
    }
    // if the focus is on the section that is being moved, then move the focus along
    if (course_get_display($course->id) == $section) {
        course_set_display($course->id, $destination);
    }
    $transaction->allow_commit();
    return true;
}
Esempio n. 4
0
 /**
  * Moves section to the specified position
  *
  * @param int|section_info $section
  * @param int|section_info $parent
  * @param null|int|section_info $before
  * @return int new section number
  */
 protected function move_section($section, $parent, $before = null)
 {
     global $DB;
     $section = $this->get_section($section);
     $parent = $this->get_section($parent);
     $newsectionnumber = $section->section;
     if (!$this->can_move_section_to($section, $parent, $before)) {
         return $newsectionnumber;
     }
     if ($section->visible != $parent->visible && $section->parent != $parent->section) {
         // section is changing parent and new parent has different visibility than the section
         if ($section->visible) {
             // visible section is moved under hidden parent
             $updatesectionvisible = 0;
             $updatesectionvisibleold = 1;
         } else {
             // hidden section is moved under visible parent
             if ($section->visibleold) {
                 $updatesectionvisible = 1;
                 $updatesectionvisibleold = 1;
             }
         }
     }
     // find the changes in the sections numbering
     $origorder = array();
     foreach ($this->get_sections() as $subsection) {
         $origorder[$subsection->id] = $subsection->section;
     }
     $neworder = array();
     $this->reorder_sections($neworder, 0, $section->section, $parent, $before);
     if (count($origorder) != count($neworder)) {
         die('Error in sections hierarchy');
         // TODO
     }
     $changes = array();
     foreach ($origorder as $id => $num) {
         if ($num == $section->section) {
             $newsectionnumber = $neworder[$id];
         }
         if ($num != $neworder[$id]) {
             $changes[$id] = array('old' => $num, 'new' => $neworder[$id]);
             if ($num && $this->get_course()->marker == $num) {
                 $changemarker = $neworder[$id];
             }
         }
         if ($this->get_section_number($parent) === $num) {
             $newparentnum = $neworder[$id];
         }
     }
     if (empty($changes) && $newparentnum == $section->parent) {
         return $newsectionnumber;
     }
     // build array of required changes in field 'parent'
     // $changeparent[sectionid] = newsectionnum;
     $changeparent = array();
     foreach ($this->get_sections() as $subsection) {
         foreach ($changes as $id => $change) {
             if ($subsection->parent == $change['old']) {
                 $changeparent[$subsection->id] = $change['new'];
             }
         }
     }
     $changeparent[$section->id] = $newparentnum;
     // Update all in database in one transaction
     $transaction = $DB->start_delegated_transaction();
     // Update sections numbers in 2 steps to avoid breaking database uniqueness constraint
     foreach ($changes as $id => $change) {
         $DB->set_field('course_sections', 'section', -$change['new'], array('id' => $id));
     }
     foreach ($changes as $id => $change) {
         $DB->set_field('course_sections', 'section', $change['new'], array('id' => $id));
     }
     // change parents of their subsections
     foreach ($changeparent as $id => $newnum) {
         $this->update_section_format_options(array('id' => $id, 'parent' => $newnum));
     }
     $transaction->allow_commit();
     rebuild_course_cache($this->courseid, true);
     if (isset($changemarker)) {
         course_set_marker($this->courseid, $changemarker);
     }
     if (isset($updatesectionvisible)) {
         $this->set_section_visible($newsectionnumber, $updatesectionvisible, $updatesectionvisibleold);
     }
     return $newsectionnumber;
 }
Esempio n. 5
0
/**
 * Moves a section within a course, from a position to another.
 * Be very careful: $section and $destination refer to section number,
 * not id!.
 *
 * @param object $course
 * @param int $section Section number (not id!!!)
 * @param int $destination
 * @return boolean Result
 */
function move_section_to($course, $section, $destination)
{
    /// Moves a whole course section up and down within the course
    global $USER, $DB;
    if (!$destination && $destination != 0) {
        return true;
    }
    // compartibility with course formats using field 'numsections'
    $courseformatoptions = course_get_format($course)->get_format_options();
    if (array_key_exists('numsections', $courseformatoptions) && $destination > $courseformatoptions['numsections'] || $destination < 1) {
        return false;
    }
    // Get all sections for this course and re-order them (2 of them should now share the same section number)
    if (!($sections = $DB->get_records_menu('course_sections', array('course' => $course->id), 'section ASC, id ASC', 'id, section'))) {
        return false;
    }
    $movedsections = reorder_sections($sections, $section, $destination);
    // Update all sections. Do this in 2 steps to avoid breaking database
    // uniqueness constraint
    $transaction = $DB->start_delegated_transaction();
    foreach ($movedsections as $id => $position) {
        if ($sections[$id] !== $position) {
            $DB->set_field('course_sections', 'section', -$position, array('id' => $id));
        }
    }
    foreach ($movedsections as $id => $position) {
        if ($sections[$id] !== $position) {
            $DB->set_field('course_sections', 'section', $position, array('id' => $id));
        }
    }
    // If we move the highlighted section itself, then just highlight the destination.
    // Adjust the higlighted section location if we move something over it either direction.
    if ($section == $course->marker) {
        course_set_marker($course->id, $destination);
    } elseif ($section > $course->marker && $course->marker >= $destination) {
        course_set_marker($course->id, $course->marker + 1);
    } elseif ($section < $course->marker && $course->marker <= $destination) {
        course_set_marker($course->id, $course->marker - 1);
    }
    $transaction->allow_commit();
    rebuild_course_cache($course->id, true);
    return true;
}
Esempio n. 6
0
// It is based of the "topics" format
defined('MOODLE_INTERNAL') || die;
require_once $CFG->libdir . '/filelib.php';
require_once $CFG->libdir . '/completionlib.php';
// Horrible backwards compatible parameter aliasing..
if ($topic = optional_param('topic', 0, PARAM_INT)) {
    $url = $PAGE->url;
    $url->param('section', $topic);
    debugging('Outdated topic param passed to course/view.php', DEBUG_DEVELOPER);
    redirect($url);
}
// End backwards-compatible aliasing..
$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);
}
// make sure all sections are created
$course = course_get_format($course)->get_course();
course_create_sections_if_missing($course, range(0, $course->numsections));
//onetopic format is always multipage
$course->realcoursedisplay = $course->coursedisplay == COURSE_DISPLAY_MULTIPAGE;
$course->coursedisplay = COURSE_DISPLAY_MULTIPAGE;
$renderer = $PAGE->get_renderer('format_onetopic');
$section = optional_param('section', -1, PARAM_INT);
if (isset($section) && $section >= 0 && $course->numsections >= $section) {
    $USER->display[$course->id] = $section;
    $displaysection = $section;
} else {
    if (isset($USER->display[$course->id]) && $course->numsections >= $USER->display[$course->id]) {
        $displaysection = $USER->display[$course->id];
Esempio n. 7
0
 public function test_course_delete_section()
 {
     global $DB;
     $this->resetAfterTest(true);
     $generator = $this->getDataGenerator();
     $course = $generator->create_course(array('numsections' => 6, 'format' => 'topics'), array('createsections' => true));
     $assign0 = $generator->create_module('assign', array('course' => $course, 'section' => 0));
     $assign1 = $generator->create_module('assign', array('course' => $course, 'section' => 1));
     $assign21 = $generator->create_module('assign', array('course' => $course, 'section' => 2));
     $assign22 = $generator->create_module('assign', array('course' => $course, 'section' => 2));
     $assign3 = $generator->create_module('assign', array('course' => $course, 'section' => 3));
     $assign5 = $generator->create_module('assign', array('course' => $course, 'section' => 5));
     $assign6 = $generator->create_module('assign', array('course' => $course, 'section' => 6));
     $this->setAdminUser();
     // Attempt to delete non-existing section.
     $this->assertFalse(course_delete_section($course, 10, false));
     $this->assertFalse(course_delete_section($course, 9, true));
     // Attempt to delete 0-section.
     $this->assertFalse(course_delete_section($course, 0, true));
     $this->assertTrue($DB->record_exists('course_modules', array('id' => $assign0->cmid)));
     // Delete last section.
     $this->assertTrue(course_delete_section($course, 6, true));
     $this->assertFalse($DB->record_exists('course_modules', array('id' => $assign6->cmid)));
     $this->assertEquals(5, course_get_format($course)->get_course()->numsections);
     // Delete empty section.
     $this->assertTrue(course_delete_section($course, 4, false));
     $this->assertEquals(4, course_get_format($course)->get_course()->numsections);
     // Delete section in the middle (2).
     $this->assertFalse(course_delete_section($course, 2, false));
     $this->assertTrue(course_delete_section($course, 2, true));
     $this->assertFalse($DB->record_exists('course_modules', array('id' => $assign21->cmid)));
     $this->assertFalse($DB->record_exists('course_modules', array('id' => $assign22->cmid)));
     $this->assertEquals(3, course_get_format($course)->get_course()->numsections);
     $this->assertEquals(array(0 => array($assign0->cmid), 1 => array($assign1->cmid), 2 => array($assign3->cmid), 3 => array($assign5->cmid)), get_fast_modinfo($course)->sections);
     // Make last section orphaned.
     update_course((object) array('id' => $course->id, 'numsections' => 2));
     $this->assertEquals(2, course_get_format($course)->get_course()->numsections);
     // Remove orphaned section.
     $this->assertTrue(course_delete_section($course, 3, true));
     $this->assertEquals(2, course_get_format($course)->get_course()->numsections);
     // Remove marked section.
     course_set_marker($course->id, 1);
     $this->assertTrue(course_get_format($course)->is_section_current(1));
     $this->assertTrue(course_delete_section($course, 1, true));
     $this->assertFalse(course_get_format($course)->is_section_current(1));
 }
Esempio n. 8
0
 public function test_move_section_marker()
 {
     global $DB;
     $this->resetAfterTest(true);
     $this->getDataGenerator()->create_course(array('numsections' => 5), array('createsections' => true));
     $course = $this->getDataGenerator()->create_course(array('numsections' => 10), array('createsections' => true));
     // Set course marker to the section we are going to move..
     course_set_marker($course->id, 2);
     // Verify that the course marker is set correctly.
     $course = $DB->get_record('course', array('id' => $course->id));
     $this->assertEquals(2, $course->marker);
     // Test move the marked section down..
     move_section_to($course, 2, 4);
     // Verify that the coruse marker has been moved along with the section..
     $course = $DB->get_record('course', array('id' => $course->id));
     $this->assertEquals(4, $course->marker);
     // Test move the marked section up..
     move_section_to($course, 4, 3);
     // Verify that the course marker has been moved along with the section..
     $course = $DB->get_record('course', array('id' => $course->id));
     $this->assertEquals(3, $course->marker);
     // Test moving a non-marked section above the marked section..
     move_section_to($course, 4, 2);
     // Verify that the course marker has been moved down to accomodate..
     $course = $DB->get_record('course', array('id' => $course->id));
     $this->assertEquals(4, $course->marker);
     // Test moving a non-marked section below the marked section..
     move_section_to($course, 3, 6);
     // Verify that the course marker has been up to accomodate..
     $course = $DB->get_record('course', array('id' => $course->id));
     $this->assertEquals(3, $course->marker);
 }
Esempio n. 9
0
/**
 * Moves a section up or down by 1. CANNOT BE USED DIRECTLY BY AJAX!
 *
 * @param object $course course object
 * @param int $section Section number (not id!!!)
 * @param int $move (-1 or 1)
 * @return boolean true if section moved successfully
 */
function move_section($course, $section, $move)
{
    /// Moves a whole course section up and down within the course
    global $USER, $DB;
    if (!$move) {
        return true;
    }
    $sectiondest = $section + $move;
    if ($sectiondest > $course->numsections or $sectiondest < 1) {
        return false;
    }
    if (!($sectionrecord = $DB->get_record("course_sections", array("course" => $course->id, "section" => $section)))) {
        return false;
    }
    if (!($sectiondestrecord = $DB->get_record("course_sections", array("course" => $course->id, "section" => $sectiondest)))) {
        return false;
    }
    $DB->set_field("course_sections", "section", $sectiondest, array("id" => $sectionrecord->id));
    $DB->set_field("course_sections", "section", $section, array("id" => $sectiondestrecord->id));
    // Update highlighting if the move affects highlighted section
    if ($course->marker == $section) {
        course_set_marker($course->id, $sectiondest);
    } elseif ($course->marker == $sectiondest) {
        course_set_marker($course->id, $section);
    }
    // if the focus is on the section that is being moved, then move the focus along
    if (course_get_display($course->id) == $section) {
        course_set_display($course->id, $sectiondest);
    }
    // Check for duplicates and fix order if needed.
    // There is a very rare case that some sections in the same course have the same section id.
    $sections = $DB->get_records('course_sections', array('course' => $course->id), 'section ASC');
    $n = 0;
    foreach ($sections as $section) {
        if ($section->section != $n) {
            $DB->set_field('course_sections', 'section', $n, array('id' => $section->id));
        }
        $n++;
    }
    return true;
}
 /**
  * fix_course_marker
  */
 function fix_course_marker()
 {
     global $COURSE;
     // get default marker value
     $marker = empty($COURSE->marker) ? 0 : $COURSE->marker;
     // get marker value from form
     $marker = optional_param('marker', $marker, PARAM_INT);
     // update if necessary
     if ($marker == $COURSE->marker) {
         // do nothing
     } else {
         if (has_capability('moodle/course:setcurrentsection', $this->page->context)) {
             $COURSE->marker = $marker;
             course_set_marker($COURSE->id, $marker);
         }
     }
 }
Esempio n. 11
0
 /**
  * @param string $shortname
  * @param int $sectionnumber
  * @param boolean $highlight
  * @throws \required_capability_exception
  * @return array
  */
 public function highlight_section($shortname, $sectionnumber, $highlight)
 {
     global $OUTPUT;
     $course = $this->coursebyshortname($shortname);
     $context = \context_course::instance($course->id);
     require_capability('moodle/course:setcurrentsection', $context);
     $setsectionnumber = empty($highlight) ? 0 : $sectionnumber;
     course_set_marker($course->id, $setsectionnumber);
     $course->marker = $setsectionnumber;
     $modinfo = get_fast_modinfo($course);
     if ($highlight) {
         $section = $modinfo->get_section_info(0);
     } else {
         $section = $modinfo->get_section_info($sectionnumber);
     }
     $actionmodel = new \theme_snap\renderables\course_action_section_highlight($course, $section);
     $toc = new \theme_snap\renderables\course_toc($course);
     return ['actionmodel' => $actionmodel->export_for_template($OUTPUT), 'toc' => $toc->export_for_template($OUTPUT)];
 }