Store a course module in the recycle bin.

@param \stdClass $cm Course module
@throws \moodle_exception
436473
public function store_item($cm) {
        global $CFG, $DB;

        require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');

        // Get more information.
        $modinfo = get_fast_modinfo($cm->course);

        if (!isset($modinfo->cms[$cm->id])) {
            return; // Can't continue without the module information.
        }

        $cminfo = $modinfo->cms[$cm->id];

        // Check backup/restore support.
        if (!plugin_supports('mod', $cminfo->modname , FEATURE_BACKUP_MOODLE2)) {
            return;
        }

        // As far as recycle bin is using MODE_AUTOMATED, it observes the backup_auto_storage
        // setting (storing backups @ real location. For recycle bin we want to ensure that
        // backup files are always stored in Moodle file area. In order to achieve that, we
        // hack the setting here via $CFG->forced_plugin_settings, so it won't interfere other
        // operations.  See MDL-65218 for more information.
        // This hack will be removed once recycle bin switches to use its own backup mode, with
        // own preferences and 100% appart from MODLE_AUTOMATED.
        // TODO: Remove this as part of MDL-65228.
        $CFG->forced_plugin_settings['backup'] = ['backup_auto_storage' => 0];

        // Backup the activity.
        $user = get_admin();
        $controller = new \backup_controller(
            \backup::TYPE_1ACTIVITY,
            $cm->id,
            \backup::FORMAT_MOODLE,
            \backup::INTERACTIVE_NO,
            \backup::MODE_AUTOMATED,
            $user->id
        );
        $controller->execute_plan();

        // We don't need the forced setting anymore, hence unsetting it.
        // TODO: Remove this as part of MDL-65228.
        unset($CFG->forced_plugin_settings['backup']);

        // Grab the result.
        $result = $controller->get_results();
        if (!isset($result['backup_destination'])) {
            throw new \moodle_exception('Failed to backup activity prior to deletion.');
        }

        // Have finished with the controller, let's destroy it, freeing mem and resources.
        $controller->destroy();

        // Grab the filename.
        $file = $result['backup_destination'];
        if (!$file->get_contenthash()) {
            throw new \moodle_exception('Failed to backup activity prior to deletion (invalid file).');
        }

        // Record the activity, get an ID.
        $activity = new \stdClass();
        $activity->courseid = $cm->course;
        $activity->section = $cm->section;
        $activity->module = $cm->module;
        $activity->name = $cminfo->name;
        $activity->timecreated = time();
        $binid = $DB->insert_record('tool_recyclebin_course', $activity);

        // Create the location we want to copy this file to.
        $filerecord = array(
            'contextid' => \context_course::instance($this->_courseid)->id,
            'component' => 'tool_recyclebin',
            'filearea' => TOOL_RECYCLEBIN_COURSE_BIN_FILEAREA,
            'itemid' => $binid,
            'timemodified' => time()
        );

        // Move the file to our own special little place.
        $fs = get_file_storage();
        if (!$fs->create_file_from_storedfile($filerecord, $file)) {
            // Failed, cleanup first.
            $DB->delete_records('tool_recyclebin_course', array(
                'id' => $binid
            ));

            throw new \moodle_exception("Failed to copy backup file to recyclebin.");
        }

        // Delete the old file.
        $file->delete();

        // Fire event.
        $event = \tool_recyclebin\event\course_bin_item_created::create(array(
            'objectid' => $binid,
            'context' => \context_course::instance($cm->course)
        ));
        $event->trigger();
    }
1201052
public function process_group($data) {
        global $DB;

        $data = (object)$data; // handy
        $data->courseid = $this->get_courseid();

        // Only allow the idnumber to be set if the user has permission and the idnumber is not already in use by
        // another a group in the same course
        $context = context_course::instance($data->courseid);
        if (isset($data->idnumber) and has_capability('moodle/course:changeidnumber', $context, $this->task->get_userid())) {
            if (groups_get_group_by_idnumber($data->courseid, $data->idnumber)) {
                unset($data->idnumber);
            }
        } else {
            unset($data->idnumber);
        }

        $oldid = $data->id;    // need this saved for later

        $restorefiles = false; // Only if we end creating the group

        // Search if the group already exists (by name & description) in the target course
        $description_clause = '';
        $params = array('courseid' => $this->get_courseid(), 'grname' => $data->name);
        if (!empty($data->description)) {
            $description_clause = ' AND ' .
                                  $DB->sql_compare_text('description') . ' = ' . $DB->sql_compare_text(':description');
           $params['description'] = $data->description;
        }
        if (!$groupdb = $DB->get_record_sql("SELECT *
                                               FROM {groups}
                                              WHERE courseid = :courseid
                                                AND name = :grname $description_clause", $params)) {
            // group doesn't exist, create
            $newitemid = $DB->insert_record('groups', $data);
            $restorefiles = true; // We'll restore the files
        } else {
            // group exists, use it
            $newitemid = $groupdb->id;
        }
        // Save the id mapping
        $this->set_mapping('group', $oldid, $newitemid, $restorefiles);
        // Invalidate the course group data cache just in case.
        cache_helper::invalidate_by_definition('core', 'groupdata', array(), array($data->courseid));
    }
683192
protected function savePClasses()
    {
        //Insert PClass SQL statement.
        $sql = <<<SQL
            INSERT INTO `{$this->dbName}`.`{$this->dbTable}`
                (`eid`, `id`, `type`, `description`, `months`, `interestrate`,
       	         `invoicefee`, `startfee`, `minamount`, `country`, `expire`)
           	VALUES
                (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
SQL;

        foreach ($this->pclasses as $pclasses) {
            foreach ($pclasses as $pclass) {
                try {
                    //Remove the pclass if it exists.
                    $sth = $this->pdo->prepare(
                        "DELETE FROM `{$this->dbName}`.`{$this->dbTable}`
                        WHERE `id` = ? AND `eid` = ?"
                    );
                    $sth->execute(
                        array(
                            $pclass->getId(), $pclass->getEid()
                        )
                    );

                    $sth->closeCursor();
                    $sth = null;
                } catch(PDOException $e) {
                    //Fail silently, we don't care if the removal failed.
                }

                try {
                    //Attempt to insert the PClass into the DB.
                    $sth = $this->pdo->prepare($sql);
                    $sth->execute(
                        array(
                            $pclass->getEid(),
                            $pclass->getId(),
                            $pclass->getType(),
                            $pclass->getDescription(),
                            $pclass->getMonths(),
                            $pclass->getInterestRate(),
                            $pclass->getInvoiceFee(),
                            $pclass->getStartFee(),
                            $pclass->getMinAmount(),
                            $pclass->getCountry(),
                            $pclass->getExpire()
                        )
                    );

                    $sth->closeCursor();
                    $sth = null;
                } catch(PDOException $e) {
                    throw new Klarna_DatabaseException(
                        'Failed to insert PClass into database!'
                    );
                }
            }
        }
    }
59411
public function get_cm($cmid) {
        if (empty($this->cms[$cmid])) {
            throw new moodle_exception('invalidcoursemodule', 'error');
        }
        return $this->cms[$cmid];
    }
989705
public static function course_module_deleted(\core\event\course_module_deleted $event) {
        $cmid = $event->contextinstanceid;
        subscription_manager::delete_cm_subscriptions($cmid);
    }
527439
public function cmdUninstallModule()
    {
        $result = $this->module_model->uninstall($this->getParam(0));

        if ($result !== true) {
            $this->errorAndExit($result);
        }

        $this->output();
    }
800801
public function delete_all_state($cm) {
        global $DB;

        // Delete from database
        $DB->delete_records('course_modules_completion', array('coursemoduleid'=>$cm->id));

        // Check if there is an associated course completion criteria
        $criteria = $this->get_criteria(COMPLETION_CRITERIA_TYPE_ACTIVITY);
        $acriteria = false;
        foreach ($criteria as $criterion) {
            if ($criterion->moduleinstance == $cm->id) {
                $acriteria = $criterion;
                break;
            }
        }

        if ($acriteria) {
            // Delete all criteria completions relating to this activity
            $DB->delete_records('course_completion_crit_compl', array('course' => $this->course_id, 'criteriaid' => $acriteria->id));
            $DB->delete_records('course_completions', array('course' => $this->course_id));
        }

        // Difficult to find affected users, just purge all completion cache.
        cache::make('core', 'completion')->purge();
        cache::make('core', 'coursecompletion')->purge();
    }
783829
public function course_section_cm_text(cm_info $mod, $displayoptions = array()) {
        $output = '';
        if (!$mod->is_visible_on_course_page()) {
            // nothing to be displayed to the user
            return $output;
        }
        $content = $mod->get_formatted_content(array('overflowdiv' => true, 'noclean' => true));
        list($linkclasses, $textclasses) = $this->course_section_cm_classes($mod);
        if ($mod->url && $mod->uservisible) {
            if ($content) {
                // If specified, display extra content after link.
                $output = html_writer::tag('div', $content, array('class' =>
                        trim('contentafterlink ' . $textclasses)));
            }
        } else {
            $groupinglabel = $mod->get_grouping_label($textclasses);

            // No link, so display only content.
            $output = html_writer::tag('div', $content . $groupinglabel,
                    array('class' => 'contentwithoutlink ' . $textclasses));
        }
        return $output;
    }
603851
public function restore_instance(restore_enrolments_structure_step $step, stdClass $data, $course, $oldid) {
        global $DB, $CFG;

        if (!$step->get_task()->is_samesite()) {
            // No cohort restore from other sites.
            $step->set_mapping('enrol', $oldid, 0);
            return;
        }

        if (!empty($data->customint2)) {
            $data->customint2 = $step->get_mappingid('group', $data->customint2);
        }

        if ($data->roleid and $DB->record_exists('cohort', array('id'=>$data->customint1))) {
            $instance = $DB->get_record('enrol', array('roleid'=>$data->roleid, 'customint1'=>$data->customint1, 'courseid'=>$course->id, 'enrol'=>$this->get_name()));
            if ($instance) {
                $instanceid = $instance->id;
            } else {
                $instanceid = $this->add_instance($course, (array)$data);
            }
            $step->set_mapping('enrol', $oldid, $instanceid);

            require_once("$CFG->dirroot/enrol/cohort/locallib.php");
            $trace = new null_progress_trace();
            enrol_cohort_sync($trace, $course->id);
            $trace->finished();

        } else if ($this->get_config('unenrolaction') == ENROL_EXT_REMOVED_SUSPENDNOROLES) {
            $data->customint1 = 0;
            $instance = $DB->get_record('enrol', array('roleid'=>$data->roleid, 'customint1'=>$data->customint1, 'courseid'=>$course->id, 'enrol'=>$this->get_name()));

            if ($instance) {
                $instanceid = $instance->id;
            } else {
                $data->status = ENROL_INSTANCE_DISABLED;
                $instanceid = $this->add_instance($course, (array)$data);
            }
            $step->set_mapping('enrol', $oldid, $instanceid);

            require_once("$CFG->dirroot/enrol/cohort/locallib.php");
            $trace = new null_progress_trace();
            enrol_cohort_sync($trace, $course->id);
            $trace->finished();

        } else {
            $step->set_mapping('enrol', $oldid, 0);
        }
    }
770948
private function get_mod_instance($cmid) {
        global $DB;
        $rec = $DB->get_record_sql("SELECT md.name
                               FROM {course_modules} cm,
                                    {modules} md
                               WHERE cm.id = ? AND
                                     md.id = cm.module", array($cmid));

        if ($rec) {
            return get_coursemodule_from_id($rec->name, $cmid);
        } else {
            return null;
        }
    }
548798
public static function store(\core\event\base $event) {
        global $DB;
        $eventdata = new \stdClass();
        switch ($event->eventname) {
            case '\core\event\course_module_created':
                $eventdata->action = self::CM_CREATED;
                break;
            case '\core\event\course_module_updated':
                $eventdata->action = self::CM_UPDATED;
                break;
            case '\core\event\course_module_deleted':
                $eventdata->action = self::CM_DELETED;
                $eventdata->modname = $event->other['modulename'];
                break;
            default:
                return;
        }
        $eventdata->timecreated = $event->timecreated;
        $eventdata->courseid = $event->courseid;
        $eventdata->cmid = $event->objectid;
        $eventdata->userid = $event->userid;
        $DB->insert_record('block_recent_activity', $eventdata);
    }
504895
public function execute() {
        global $CFG;

        require_once($CFG->dirroot . '/course/lib.php');

        // Specific list of plugins that need to be refreshed. If not set, then all mod plugins will be refreshed.
        $pluginstorefresh = null;
        if (isset($this->get_custom_data()->plugins)) {
            $pluginstorefresh = $this->get_custom_data()->plugins;
        }

        // Is course id set?
        if (isset($this->get_custom_data()->courseid)) {
            $courseid = $this->get_custom_data()->courseid;
        } else {
            $courseid = 0;
        }

        $pluginmanager = core_plugin_manager::instance();
        $modplugins = $pluginmanager->get_plugins_of_type('mod');
        foreach ($modplugins as $plugin) {
            // Check if a specific list of plugins is defined and check if it contains the plugin that is currently being evaluated.
            if (!empty($pluginstorefresh) && !in_array($plugin->name, $pluginstorefresh)) {
                // This plugin is not in the list, move on to the next one.
                continue;
            }
            // Refresh events.
            mtrace('Refreshing events for ' . $plugin->name);
            course_module_bulk_update_calendar_events($plugin->name, $courseid);
        }
    }
244213
final public function delete() {
        global $DB;

        $cm = get_coursemodule_from_instance('lesson', $this->lesson->id, $this->lesson->course);
        $context = context_module::instance($cm->id);

        // Delete files associated with attempts.
        $fs = get_file_storage();
        if ($attempts = $DB->get_records('lesson_attempts', array("pageid" => $this->properties->id))) {
            foreach ($attempts as $attempt) {
                $fs->delete_area_files($context->id, 'mod_lesson', 'essay_responses', $attempt->id);
                $fs->delete_area_files($context->id, 'mod_lesson', 'essay_answers', $attempt->id);
            }
        }

        // Then delete all the associated records...
        $DB->delete_records("lesson_attempts", array("pageid" => $this->properties->id));

        $DB->delete_records("lesson_branch", array("pageid" => $this->properties->id));

        // Delete files related to answers and responses.
        if ($answers = $DB->get_records("lesson_answers", array("pageid" => $this->properties->id))) {
            foreach ($answers as $answer) {
                $fs->delete_area_files($context->id, 'mod_lesson', 'page_answers', $answer->id);
                $fs->delete_area_files($context->id, 'mod_lesson', 'page_responses', $answer->id);
            }
        }

        // ...now delete the answers...
        $DB->delete_records("lesson_answers", array("pageid" => $this->properties->id));
        // ..and the page itself
        $DB->delete_records("lesson_pages", array("id" => $this->properties->id));

        // Trigger an event: page deleted.
        $eventparams = array(
            'context' => $context,
            'objectid' => $this->properties->id,
            'other' => array(
                'pagetype' => $this->get_typestring()
                )
            );
        $event = \mod_lesson\event\page_deleted::create($eventparams);
        $event->add_record_snapshot('lesson_pages', $this->properties);
        $event->trigger();

        // Delete files associated with this page.
        $fs->delete_area_files($context->id, 'mod_lesson', 'page_contents', $this->properties->id);

        // repair the hole in the linkage
        if (!$this->properties->prevpageid && !$this->properties->nextpageid) {
            //This is the only page, no repair needed
        } elseif (!$this->properties->prevpageid) {
            // this is the first page...
            $page = $this->lesson->load_page($this->properties->nextpageid);
            $page->move(null, 0);
        } elseif (!$this->properties->nextpageid) {
            // this is the last page...
            $page = $this->lesson->load_page($this->properties->prevpageid);
            $page->move(0);
        } else {
            // page is in the middle...
            $prevpage = $this->lesson->load_page($this->properties->prevpageid);
            $nextpage = $this->lesson->load_page($this->properties->nextpageid);

            $prevpage->move($nextpage->id);
            $nextpage->move(null, $prevpage->id);
        }
        return true;
    }
783172
public static function remove_competency_from_course_module($cmorid, $competencyid) {
        static::require_enabled();
        $cm = $cmorid;
        if (!is_object($cmorid)) {
            $cm = get_coursemodule_from_id('', $cmorid, 0, true, MUST_EXIST);
        }
        // Check the user have access to the course module.
        self::validate_course_module($cm);

        // First we do a permissions check.
        $context = context_module::instance($cm->id);

        require_capability('moodle/competency:coursecompetencymanage', $context);

        $record = new stdClass();
        $record->cmid = $cm->id;
        $record->competencyid = $competencyid;

        $competency = new competency($competencyid);
        $exists = course_module_competency::get_record(array('cmid' => $cm->id, 'competencyid' => $competencyid));
        if ($exists) {
            return $exists->delete();
        }
        return false;
    }
1276309
public function get_course_module() {
        if ($this->coursemodule) {
            return $this->coursemodule;
        }
        if (!$this->context) {
            return null;
        }

        if ($this->context->contextlevel == CONTEXT_MODULE) {
            $modinfo = get_fast_modinfo($this->get_course());
            $this->coursemodule = $modinfo->get_cm($this->context->instanceid);
            return $this->coursemodule;
        }
        return null;
    }
922316
protected function reset($course) {
        global $DB;

        $resetdata = new stdClass();
        $resetdata->id = $course->id;
        $resetdata->reset_start_date = time();
        $resetdata->reset_events = true;
        $resetdata->reset_notes = true;
        $resetdata->delete_blog_associations = true;
        $resetdata->reset_completion = true;
        $resetdata->reset_roles_overrides = true;
        $resetdata->reset_roles_local = true;
        $resetdata->reset_groups_members = true;
        $resetdata->reset_groups_remove = true;
        $resetdata->reset_groupings_members = true;
        $resetdata->reset_groupings_remove = true;
        $resetdata->reset_gradebook_items = true;
        $resetdata->reset_gradebook_grades = true;
        $resetdata->reset_comments = true;

        if (empty($course->startdate)) {
            $course->startdate = $DB->get_field_select('course', 'startdate', 'id = :id', array('id' => $course->id));
        }
        $resetdata->reset_start_date_old = $course->startdate;

        if (empty($course->enddate)) {
            $course->enddate = $DB->get_field_select('course', 'enddate', 'id = :id', array('id' => $course->id));
        }
        $resetdata->reset_end_date_old = $course->enddate;

        // Add roles.
        $roles = tool_uploadcourse_helper::get_role_ids();
        $resetdata->unenrol_users = array_values($roles);
        $resetdata->unenrol_users[] = 0;    // Enrolled without role.

        return reset_course_userdata($resetdata);
    }
629503
public function process_label($data) {
        // get the course module id and context id
        $instanceid = $data['id'];
        $cminfo     = $this->get_cminfo($instanceid);
        $moduleid   = $cminfo['id'];
        $contextid  = $this->converter->get_contextid(CONTEXT_MODULE, $moduleid);

        // get a fresh new file manager for this instance
        $fileman = $this->converter->get_file_manager($contextid, 'mod_label');

        // convert course files embedded into the intro
        $fileman->filearea = 'intro';
        $fileman->itemid   = 0;
        $data['intro'] = moodle1_converter::migrate_referenced_files($data['intro'], $fileman);

        // write inforef.xml
        $this->open_xml_writer("activities/label_{$moduleid}/inforef.xml");
        $this->xmlwriter->begin_tag('inforef');
        $this->xmlwriter->begin_tag('fileref');
        foreach ($fileman->get_fileids() as $fileid) {
            $this->write_xml('file', array('id' => $fileid));
        }
        $this->xmlwriter->end_tag('fileref');
        $this->xmlwriter->end_tag('inforef');
        $this->close_xml_writer();

        // write label.xml
        $this->open_xml_writer("activities/label_{$moduleid}/label.xml");
        $this->xmlwriter->begin_tag('activity', array('id' => $instanceid, 'moduleid' => $moduleid,
            'modulename' => 'label', 'contextid' => $contextid));
        $this->write_xml('label', $data, array('/label/id'));
        $this->xmlwriter->end_tag('activity');
        $this->close_xml_writer();

        return $data;
    }