marinaglancy / moodle-format_flexsections

25 stars 25 forks source link

Index problem #82

Open Cristiano1103 opened 5 months ago

Cristiano1103 commented 5 months ago

When several users (we have many teachers) delete some section of the same course, sometimes an index problem occurs.

Some sections and subsections just disappear, I can fix it by manually adjusting in db course_format_options.

I managed to fix it by editing the function delete_section_with_children, adding get_lock_factory

Of course I created a related plugin and extended the classes so as not to edit the original

the result:

public function delete_section_with_children(section_info $section): array

{

    global $DB;

    //added this
    $lockfactory = \core\lock\lock_config::get_lock_factory('type');

    //and this
    if ($lock = $lockfactory->get_lock('course_modification_lock', 10)) {
        try {

            if (!$section->section) {
                // Section 0 does not have parent.
                $lock->release(); //unlock
                return [[], []];
            }

            $sectionid = $section->id;
            $course = $this->get_course();

            $this->move_section($section->section, 0);

            $modinfo = get_fast_modinfo($this->courseid);
            $allsections = $modinfo->get_section_info_all();
            $process = false;
            $sectionstodelete = [];
            $modulestodelete = [];
            foreach ($allsections as $sectioninfo) {
                if ($sectioninfo->id == $sectionid) {
                    $process = true;
                }
                if ($process) {
                    $sectionstodelete[] = $sectioninfo->id;
                    if (!empty($modinfo->sections[$sectioninfo->section])) {
                        $modulestodelete = array_merge(
                            $modulestodelete,
                            $modinfo->sections[$sectioninfo->section]
                        );
                    }
                    if ($sectioninfo->section == $course->marker) {
                        course_set_marker($course->id, 0);
                    }
                }
            }

            foreach ($modulestodelete as $cmid) {
                course_delete_module($cmid);
            }

            [$sectionsql, $params] = $DB->get_in_or_equal($sectionstodelete);
            $transaction = $DB->start_delegated_transaction();
            $DB->execute('DELETE FROM {course_format_options} WHERE sectionid ' . $sectionsql, $params);
            $DB->execute('DELETE FROM {course_sections} WHERE id ' . $sectionsql, $params);
            $transaction->allow_commit();

            foreach ($sectionstodelete as $sectionid) {
                course_modinfo::purge_course_section_cache_by_id($course->id, $sectionid);
                $context = context_course::instance($course->id);
                $fs = get_file_storage();
                $fs->delete_area_files($context->id, 'course', 'section', $sectionid);
            }

            rebuild_course_cache($this->courseid, true, true);

            return [$sectionstodelete, $modulestodelete];
        } finally {
            $lock->release();  // unlock
        }
    } else {

        die('waiting lock release take too long');
    }
}`