/** * Update completion status for the current user in an activity, only for activities with manual tracking. * @param int $cmid Course module id * @param bool $completed Activity completed or not * @return array Result and possible warnings * @since Moodle 2.9 * @throws moodle_exception */ public static function update_activity_completion_status_manually($cmid, $completed) { // Validate and normalize parameters. $params = self::validate_parameters(self::update_activity_completion_status_manually_parameters(), array('cmid' => $cmid, 'completed' => $completed)); $cmid = $params['cmid']; $completed = $params['completed']; $warnings = array(); $context = context_module::instance($cmid); self::validate_context($context); list($course, $cm) = get_course_and_cm_from_cmid($cmid); // Set up completion object and check it is enabled. $completion = new completion_info($course); if (!$completion->is_enabled()) { throw new moodle_exception('completionnotenabled', 'completion'); } // Check completion state is manual. if ($cm->completion != COMPLETION_TRACKING_MANUAL) { throw new moodle_exception('cannotmanualctrack', 'error'); } $targetstate = $completed ? COMPLETION_COMPLETE : COMPLETION_INCOMPLETE; $completion->update_state($cm, $targetstate); $result = array(); $result['status'] = true; $result['warnings'] = $warnings; return $result; }
public function execute() { global $DB, $CFG; $result = $DB->get_records_sql('SELECT ba.id, ba.bookingid, ba.optionid, ba.userid, b.course FROM {booking_answers} AS ba LEFT JOIN {booking_options} AS bo ON bo.id = ba.optionid LEFT JOIN {booking} AS b ON b.id = bo.bookingid WHERE bo.removeafterminutes > 0 AND ba.completed = 1 AND IF(ba.timemodified < (UNIX_TIMESTAMP() - (bo.removeafterminutes*60)), 1, 0) = 1;'); require_once $CFG->libdir . '/completionlib.php'; foreach ($result as $value) { $course = $DB->get_record('course', array('id' => $value->course)); $completion = new \completion_info($course); $cm = get_coursemodule_from_instance('booking', $value->bookingid); $userData = $DB->get_record('booking_answers', array('id' => $value->id)); $booking = $DB->get_record('booking', array('id' => $value->bookingid)); $userData->completed = '0'; $userData->timemodified = time(); $DB->update_record('booking_answers', $userData); if ($completion->is_enabled($cm) && $booking->enablecompletion) { $completion->update_state($cm, COMPLETION_INCOMPLETE, $userData->userid); } } }
/** * * @param cm_info $cm * @param stdClass $stopwatch * @param int $duration */ function mod_stopwatch_update_timer(cm_info $cm, $stopwatch, $duration) { global $USER, $DB, $CFG; require_once $CFG->libdir . '/completionlib.php'; $record = $DB->get_record('stopwatch_user', array('stopwatchid' => $cm->instance, 'courseid' => $cm->course, 'userid' => $USER->id)); if ($record) { $data = array('id' => $record->id, 'timemodified' => time(), 'duration' => $duration); $DB->update_record('stopwatch_user', $data); } else { $data = array('courseid' => $cm->course, 'stopwatchid' => $cm->instance, 'userid' => $USER->id, 'timecreated' => time(), 'timemodified' => time(), 'duration' => $duration); $DB->insert_record('stopwatch_user', $data); } // Update completion state $completion = new completion_info($cm->get_course()); if ($completion->is_enabled($cm) && $stopwatch->completiontimed) { $completion->update_state($cm, COMPLETION_COMPLETE); } }
/** * Updates activity completion status. * * @return void */ public static function update_require_specific_grade(\core\event\base $event) { global $DB; $entryuserid = $event->relateduserid; $giid = $event->other['itemid']; if (!($gitem = \grade_item::fetch(array('id' => $giid, 'itemmodule' => 'dataform')))) { return; } $dataformid = $gitem->iteminstance; $df = \mod_dataform_dataform::instance($dataformid); // Currently only completion by require entries. if ($df->completionspecificgrade) { $completion = new \completion_info($df->course); if ($completion->is_enabled($df->cm) != COMPLETION_TRACKING_AUTOMATIC) { return; } $completion->update_state($df->cm, COMPLETION_UNKNOWN, $entryuserid); } }
function checklist_update_grades($checklist, $userid = 0) { global $CFG, $DB; $items = $DB->get_records('checklist_item', array('checklist' => $checklist->id, 'userid' => 0, 'itemoptional' => CHECKLIST_OPTIONAL_NO, 'hidden' => CHECKLIST_HIDDEN_NO), '', 'id, grouping'); if (!$items) { return; } if (!($course = $DB->get_record('course', array('id' => $checklist->course)))) { return; } if (!($cm = get_coursemodule_from_instance('checklist', $checklist->id, $course->id))) { return; } $checkgroupings = false; // Don't check items against groupings unless we really have to if (isset($CFG->enablegroupmembersonly) && $CFG->enablegroupmembersonly && $checklist->autopopulate) { foreach ($items as $item) { if ($item->grouping) { $checkgroupings = true; break; } } } if ($checklist->teacheredit == CHECKLIST_MARKING_STUDENT) { $date = ', MAX(c.usertimestamp) AS datesubmitted'; $where = 'c.usertimestamp > 0'; } else { $date = ', MAX(c.teachertimestamp) AS dategraded'; $where = 'c.teachermark = ' . CHECKLIST_TEACHERMARK_YES; } if ($checkgroupings) { if ($userid) { $users = $DB->get_records('user', array('id' => $userid), null, 'id, firstname, lastname'); } else { if ($CFG->version < 2011120100) { $context = get_context_instance(CONTEXT_MODULE, $cm->id); } else { $context = context_module::instance($cm->id); } if (!($users = get_users_by_capability($context, 'mod/checklist:updateown', 'u.id, u.firstname, u.lastname', '', '', '', '', '', false))) { return; } } $grades = array(); // With groupings, need to update each user individually (as each has different groupings) foreach ($users as $userid => $user) { $groupings = checklist_class::get_user_groupings($userid, $course->id); $total = 0; $itemlist = ''; foreach ($items as $item) { if ($item->grouping) { if (!in_array($item->grouping, $groupings)) { continue; } } $itemlist .= $item->id . ','; $total++; } if (!$total) { // No items - set score to 0 $ugrade = new stdClass(); $ugrade->userid = $userid; $ugrade->rawgrade = 0; $ugrade->date = time(); } else { $itemlist = substr($itemlist, 0, -1); // Remove trailing ',' $sql = 'SELECT ? AS userid, (SUM(CASE WHEN ' . $where . ' THEN 1 ELSE 0 END) * ? / ? ) AS rawgrade' . $date; $sql .= " FROM {checklist_check} c "; $sql .= " WHERE c.item IN ({$itemlist})"; $sql .= ' AND c.userid = ? '; $ugrade = $DB->get_record_sql($sql, array($userid, $checklist->maxgrade, $total, $userid)); if (!$ugrade) { $ugrade = new stdClass(); $ugrade->userid = $userid; $ugrade->rawgrade = 0; $ugrade->date = time(); } } $ugrade->firstname = $user->firstname; $ugrade->lastname = $user->lastname; $grades[$userid] = $ugrade; } } else { // No need to check groupings, so update all student grades at once if ($userid) { $users = $userid; } else { if ($CFG->version < 2011120100) { $context = get_context_instance(CONTEXT_MODULE, $cm->id); } else { $context = context_module::instance($cm->id); } if (!($users = get_users_by_capability($context, 'mod/checklist:updateown', 'u.id', '', '', '', '', '', false))) { return; } $users = array_keys($users); } $total = count($items); list($usql, $uparams) = $DB->get_in_or_equal($users); list($isql, $iparams) = $DB->get_in_or_equal(array_keys($items)); $sql = 'SELECT u.id AS userid, (SUM(CASE WHEN ' . $where . ' THEN 1 ELSE 0 END) * ? / ? ) AS rawgrade' . $date; $sql .= ' , u.firstname, u.lastname '; $sql .= ' FROM {user} u LEFT JOIN {checklist_check} c ON u.id = c.userid'; $sql .= " WHERE u.id {$usql}"; $sql .= " AND c.item {$isql}"; $sql .= ' GROUP BY u.id, u.firstname, u.lastname'; $params = array_merge($uparams, $iparams); $params = array_merge(array($checklist->maxgrade, $total), $params); $grades = $DB->get_records_sql($sql, $params); } foreach ($grades as $grade) { // Log completion of checklist if ($grade->rawgrade == $checklist->maxgrade) { if ($checklist->emailoncomplete) { $timelimit = time() - 1 * 60 * 60; // Do not send another email if this checklist was already 'completed' in the last hour $filter = "l.time > ? AND l.cmid = ? AND l.userid = ? AND l.action = 'complete'"; get_logs($filter, array($timelimit, $cm->id, $grade->userid), '', 1, 1, $logcount); if ($logcount == 0) { if (!isset($context)) { if ($CFG->version < 2011120100) { $context = get_context_instance(CONTEXT_MODULE, $cm->id); } else { $context = context_module::instance($cm->id); } } if ($recipients = get_users_by_capability($context, 'mod/checklist:emailoncomplete', 'u.*', '', '', '', '', '', false)) { foreach ($recipients as $recipient) { $details = new stdClass(); $details->user = fullname($grade); $details->checklist = s($checklist->name); $subj = get_string('emailoncompletesubject', 'checklist', $details); $content = get_string('emailoncompletebody', 'checklist', $details); $content .= $CFG->wwwroot . '/mod/checklist/view.php?id=' . $cm->id; email_to_user($recipient, $grade, $subj, $content, '', '', '', false); } } } } add_to_log($checklist->course, 'checklist', 'complete', "view.php?id={$cm->id}", $checklist->name, $cm->id, $grade->userid); } $ci = new completion_info($course); if ($cm->completion == COMPLETION_TRACKING_AUTOMATIC) { $ci->update_state($cm, COMPLETION_UNKNOWN, $grade->userid); } } checklist_grade_item_update($checklist, $grades); }
require_course_login($course, false, $cm); if (!($choice = choice_get_choice($cm->instance))) { print_error('invalidcoursemodule'); } $strchoice = get_string('modulename', 'choice'); $strchoices = get_string('modulenameplural', 'choice'); $context = context_module::instance($cm->id); list($choiceavailable, $warnings) = choice_get_availability_status($choice); if ($action == 'delchoice' and confirm_sesskey() and is_enrolled($context, NULL, 'mod/choice:choose') and $choice->allowupdate and $choiceavailable) { $answercount = $DB->count_records('choice_answers', array('choiceid' => $choice->id, 'userid' => $USER->id)); if ($answercount > 0) { $DB->delete_records('choice_answers', array('choiceid' => $choice->id, 'userid' => $USER->id)); // Update completion state $completion = new completion_info($course); if ($completion->is_enabled($cm) && $choice->completionsubmit) { $completion->update_state($cm, COMPLETION_INCOMPLETE); } redirect("view.php?id={$cm->id}"); } } $PAGE->set_title($choice->name); $PAGE->set_heading($course->fullname); /// Submit any new data if there is any if (data_submitted() && is_enrolled($context, NULL, 'mod/choice:choose') && confirm_sesskey()) { $timenow = time(); if (has_capability('mod/choice:deleteresponses', $context) && $action == 'delete') { //some responses need to be deleted choice_delete_responses($attemptids, $choice, $cm, $course); //delete responses. redirect("view.php?id={$cm->id}"); }
$context = context_module::instance($cm->id); require_capability('mod/glossary:approve', $context); if ($newstate != $entry->approved && confirm_sesskey()) { $newentry = new stdClass(); $newentry->id = $entry->id; $newentry->approved = $newstate; $newentry->timemodified = time(); // wee need this date here to speed up recent activity, TODO: use timestamp in approved field instead in 2.0 $DB->update_record("glossary_entries", $newentry); // Trigger event about entry approval/disapproval. $params = array('context' => $context, 'objectid' => $entry->id); if ($newstate) { $event = \mod_glossary\event\entry_approved::create($params); } else { $event = \mod_glossary\event\entry_disapproved::create($params); } $entry->approved = $newstate ? 1 : 0; $entry->timemodified = $newentry->timemodified; $event->add_record_snapshot('glossary_entries', $entry); $event->trigger(); // Update completion state $completion = new completion_info($course); if ($completion->is_enabled($cm) == COMPLETION_TRACKING_AUTOMATIC && $glossary->completionentries) { $completion->update_state($cm, COMPLETION_COMPLETE, $entry->userid); } // Reset caches. if ($entry->usedynalink) { \mod_glossary\local\concept_cache::reset_glossary($glossary); } } redirect("view.php?id={$cm->id}&mode={$mode}&hook={$hook}");
/** * Removes grades and resets completion * * @global object $CFG * @global object $DB * @param int $userid * @param int $courseid * @return boolean */ function facetoface_archive_completion($userid, $courseid) { global $DB, $CFG; require_once($CFG->libdir . '/completionlib.php'); $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST); $completion = new completion_info($course); // All face to face with this course and user $sql = "SELECT f.* FROM {facetoface} f WHERE f.course = :courseid AND EXISTS (SELECT su.id FROM {facetoface_sessions} s JOIN {facetoface_signups} su ON su.sessionid = s.id AND su.userid = :userid WHERE s.facetoface = f.id)"; $facetofaces = $DB->get_records_sql($sql, array('courseid' => $courseid, 'userid' => $userid)); foreach ($facetofaces as $facetoface) { // Add an archive flag $params = array('facetofaceid' => $facetoface->id, 'userid' => $userid, 'archived' => 1, 'archived2' => 1); $sql = "UPDATE {facetoface_signups} SET archived = :archived WHERE userid = :userid AND archived <> :archived2 AND EXISTS (SELECT {facetoface_sessions}.id FROM {facetoface_sessions} WHERE {facetoface_sessions}.id = {facetoface_signups}.sessionid AND {facetoface_sessions}.facetoface = :facetofaceid)"; $DB->execute($sql, $params); // Reset the grades facetoface_update_grades($facetoface, $userid, true); // Set completion to incomplete // Reset viewed $course_module = get_coursemodule_from_instance('facetoface', $facetoface->id, $courseid); $completion->set_module_viewed_reset($course_module, $userid); // And reset completion, in case viewed is not a required condition $completion->update_state($course_module, COMPLETION_INCOMPLETE, $userid); $completion->invalidatecache($courseid, $userid, true); } }
/** * Deletes a single forum post. * * @global object * @param object $post Forum post object * @param mixed $children Whether to delete children. If false, returns false * if there are any children (without deleting the post). If true, * recursively deletes all children. If set to special value 'ignore', deletes * post regardless of children (this is for use only when deleting all posts * in a disussion). * @param object $course Course * @param object $cm Course-module * @param object $forum Forum * @param bool $skipcompletion True to skip updating completion state if it * would otherwise be updated, i.e. when deleting entire forum anyway. * @return bool */ function forum_delete_post($post, $children, $course, $cm, $forum, $skipcompletion = false) { global $DB, $CFG, $USER; require_once $CFG->libdir . '/completionlib.php'; $context = context_module::instance($cm->id); if ($children !== 'ignore' && ($childposts = $DB->get_records('forum_posts', array('parent' => $post->id)))) { if ($children) { foreach ($childposts as $childpost) { forum_delete_post($childpost, true, $course, $cm, $forum, $skipcompletion); } } else { return false; } } // Delete ratings. require_once $CFG->dirroot . '/rating/lib.php'; $delopt = new stdClass(); $delopt->contextid = $context->id; $delopt->component = 'mod_forum'; $delopt->ratingarea = 'post'; $delopt->itemid = $post->id; $rm = new rating_manager(); $rm->delete_ratings($delopt); // Delete attachments. $fs = get_file_storage(); $fs->delete_area_files($context->id, 'mod_forum', 'attachment', $post->id); $fs->delete_area_files($context->id, 'mod_forum', 'post', $post->id); // Delete cached RSS feeds. if (!empty($CFG->enablerssfeeds)) { require_once $CFG->dirroot . '/mod/forum/rsslib.php'; forum_rss_delete_file($forum); } if ($DB->delete_records("forum_posts", array("id" => $post->id))) { forum_tp_delete_read_records(-1, $post->id); // Just in case we are deleting the last post forum_discussion_update_last_post($post->discussion); // Update completion state if we are tracking completion based on number of posts // But don't bother when deleting whole thing if (!$skipcompletion) { $completion = new completion_info($course); if ($completion->is_enabled($cm) == COMPLETION_TRACKING_AUTOMATIC && ($forum->completiondiscussions || $forum->completionreplies || $forum->completionposts)) { $completion->update_state($cm, COMPLETION_INCOMPLETE, $post->userid); } } $params = array('context' => $context, 'objectid' => $post->id, 'other' => array('discussionid' => $post->discussion, 'forumid' => $forum->id, 'forumtype' => $forum->type)); if ($post->userid !== $USER->id) { $params['relateduserid'] = $post->userid; } $event = \mod_forum\event\post_deleted::create($params); $event->add_record_snapshot('forum_posts', $post); $event->trigger(); return true; } return false; }
/** * Add a new discussion into an existing forum. * * @param int $forumid the forum instance id * @param string $subject new discussion subject * @param string $message new discussion message (only html format allowed) * @param int $groupid the user course group * @param array $options optional settings * @return array of warnings and the new discussion id * @since Moodle 3.0 * @throws moodle_exception */ public static function add_discussion($forumid, $subject, $message, $groupid = -1, $options = array()) { global $DB, $CFG; require_once($CFG->dirroot . "/mod/forum/lib.php"); $params = self::validate_parameters(self::add_discussion_parameters(), array( 'forumid' => $forumid, 'subject' => $subject, 'message' => $message, 'groupid' => $groupid, 'options' => $options )); // Validate options. $options = array( 'discussionsubscribe' => true ); foreach ($params['options'] as $option) { $name = trim($option['name']); switch ($name) { case 'discussionsubscribe': $value = clean_param($option['value'], PARAM_BOOL); break; default: throw new moodle_exception('errorinvalidparam', 'webservice', '', $name); } $options[$name] = $value; } $warnings = array(); // Request and permission validation. $forum = $DB->get_record('forum', array('id' => $params['forumid']), '*', MUST_EXIST); list($course, $cm) = get_course_and_cm_from_instance($forum, 'forum'); $context = context_module::instance($cm->id); self::validate_context($context); // Normalize group. if (!groups_get_activity_groupmode($cm)) { // Groups not supported, force to -1. $groupid = -1; } else { // Check if we receive the default or and empty value for groupid, // in this case, get the group for the user in the activity. if ($groupid === -1 or empty($params['groupid'])) { $groupid = groups_get_activity_group($cm); } else { // Here we rely in the group passed, forum_user_can_post_discussion will validate the group. $groupid = $params['groupid']; } } if (!forum_user_can_post_discussion($forum, $groupid, -1, $cm, $context)) { throw new moodle_exception('cannotcreatediscussion', 'forum'); } $thresholdwarning = forum_check_throttling($forum, $cm); forum_check_blocking_threshold($thresholdwarning); // Create the discussion. $discussion = new stdClass(); $discussion->course = $course->id; $discussion->forum = $forum->id; $discussion->message = $params['message']; $discussion->messageformat = FORMAT_HTML; // Force formatting for now. $discussion->messagetrust = trusttext_trusted($context); $discussion->itemid = 0; $discussion->groupid = $groupid; $discussion->mailnow = 0; $discussion->subject = $params['subject']; $discussion->name = $discussion->subject; $discussion->timestart = 0; $discussion->timeend = 0; if ($discussionid = forum_add_discussion($discussion)) { $discussion->id = $discussionid; // Trigger events and completion. $params = array( 'context' => $context, 'objectid' => $discussion->id, 'other' => array( 'forumid' => $forum->id, ) ); $event = \mod_forum\event\discussion_created::create($params); $event->add_record_snapshot('forum_discussions', $discussion); $event->trigger(); $completion = new completion_info($course); if ($completion->is_enabled($cm) && ($forum->completiondiscussions || $forum->completionposts)) { $completion->update_state($cm, COMPLETION_COMPLETE); } $settings = new stdClass(); $settings->discussionsubscribe = $options['discussionsubscribe']; forum_post_subscription($settings, $forum, $discussion); } else { throw new moodle_exception('couldnotadd', 'forum'); } $result = array(); $result['discussionid'] = $discussionid; $result['warnings'] = $warnings; return $result; }
/** * Creates or updates a glossary entry * * @param stdClass $entry entry data * @param stdClass $course course object * @param stdClass $cm course module object * @param stdClass $glossary glossary object * @param stdClass $context context object * @return stdClass the complete new or updated entry * @since Moodle 3.2 */ function glossary_edit_entry($entry, $course, $cm, $glossary, $context) { global $DB, $USER; list($definitionoptions, $attachmentoptions) = glossary_get_editor_and_attachment_options($course, $context, $entry); $timenow = time(); $categories = empty($entry->categories) ? array() : $entry->categories; unset($entry->categories); $aliases = trim($entry->aliases); unset($entry->aliases); if (empty($entry->id)) { $entry->glossaryid = $glossary->id; $entry->timecreated = $timenow; $entry->userid = $USER->id; $entry->timecreated = $timenow; $entry->sourceglossaryid = 0; $entry->teacherentry = has_capability('mod/glossary:manageentries', $context); $isnewentry = true; } else { $isnewentry = false; } $entry->concept = trim($entry->concept); $entry->definition = ''; // Updated later. $entry->definitionformat = FORMAT_HTML; // Updated later. $entry->definitiontrust = 0; // Updated later. $entry->timemodified = $timenow; $entry->approved = 0; $entry->usedynalink = isset($entry->usedynalink) ? $entry->usedynalink : 0; $entry->casesensitive = isset($entry->casesensitive) ? $entry->casesensitive : 0; $entry->fullmatch = isset($entry->fullmatch) ? $entry->fullmatch : 0; if ($glossary->defaultapproval or has_capability('mod/glossary:approve', $context)) { $entry->approved = 1; } if ($isnewentry) { // Add new entry. $entry->id = $DB->insert_record('glossary_entries', $entry); } else { // Update existing entry. $DB->update_record('glossary_entries', $entry); } // Save and relink embedded images and save attachments. if (!empty($entry->definition_editor)) { $entry = file_postupdate_standard_editor($entry, 'definition', $definitionoptions, $context, 'mod_glossary', 'entry', $entry->id); } if (!empty($entry->attachment_filemanager)) { $entry = file_postupdate_standard_filemanager($entry, 'attachment', $attachmentoptions, $context, 'mod_glossary', 'attachment', $entry->id); } // Store the updated value values. $DB->update_record('glossary_entries', $entry); // Refetch complete entry. $entry = $DB->get_record('glossary_entries', array('id' => $entry->id)); // Update entry categories. $DB->delete_records('glossary_entries_categories', array('entryid' => $entry->id)); // TODO: this deletes cats from both both main and secondary glossary :-(. if (!empty($categories) and array_search(0, $categories) === false) { foreach ($categories as $catid) { $newcategory = new stdClass(); $newcategory->entryid = $entry->id; $newcategory->categoryid = $catid; $DB->insert_record('glossary_entries_categories', $newcategory, false); } } // Update aliases. $DB->delete_records('glossary_alias', array('entryid' => $entry->id)); if ($aliases !== '') { $aliases = explode("\n", $aliases); foreach ($aliases as $alias) { $alias = trim($alias); if ($alias !== '') { $newalias = new stdClass(); $newalias->entryid = $entry->id; $newalias->alias = $alias; $DB->insert_record('glossary_alias', $newalias, false); } } } // Trigger event and update completion (if entry was created). $eventparams = array( 'context' => $context, 'objectid' => $entry->id, 'other' => array('concept' => $entry->concept) ); if ($isnewentry) { $event = \mod_glossary\event\entry_created::create($eventparams); } else { $event = \mod_glossary\event\entry_updated::create($eventparams); } $event->add_record_snapshot('glossary_entries', $entry); $event->trigger(); if ($isnewentry) { // Update completion state. $completion = new completion_info($course); if ($completion->is_enabled($cm) == COMPLETION_TRACKING_AUTOMATIC && $glossary->completionentries && $entry->approved) { $completion->update_state($cm, COMPLETION_COMPLETE); } } // Reset caches. if ($isnewentry) { if ($entry->usedynalink and $entry->approved) { \mod_glossary\local\concept_cache::reset_glossary($glossary); } } else { // So many things may affect the linking, let's just purge the cache always on edit. \mod_glossary\local\concept_cache::reset_glossary($glossary); } return $entry; }
function booking_activitycompletion($selectedusers, $booking, $cmid, $optionid) { global $DB; $course = $DB->get_record('course', array('id' => $booking->course)); $completion = new completion_info($course); $cm = get_coursemodule_from_id('booking', $cmid, 0, false, MUST_EXIST); foreach ($selectedusers as $ui) { $userData = $DB->get_record('booking_answers', array('optionid' => $optionid, 'userid' => $ui)); if ($userData->completed == '1') { $userData->completed = '0'; $userData->timemodified = time(); $DB->update_record('booking_answers', $userData); if ($completion->is_enabled($cm) && $booking->enablecompletion) { $completion->update_state($cm, COMPLETION_INCOMPLETE, $ui); } } else { $userData->completed = '1'; $userData->timemodified = time(); $DB->update_record('booking_answers', $userData); if ($completion->is_enabled($cm) && $booking->enablecompletion) { $completion->update_state($cm, COMPLETION_COMPLETE, $ui); } } } }
/** * Verify if user meet issue conditions * * @param int $userid User id * @return string null if user meet issued conditions, or an text with erro */ protected function can_issue($user = null, $chkcompletation = true) { global $DB, $USER, $CFG; if (empty($user)) { $user = $USER; } if (has_capability('mod/simplecertificate:manage', $this->context, $user)) { return get_string('cantissue', 'simplecertificate'); } if ($chkcompletation) { $completion = new completion_info($this->course); if ($completion->is_enabled($this->coursemodule) && $this->get_instance()->requiredtime) { if ($this->get_course_time($user) < $this->get_instance()->requiredtime) { $a = new stdClass(); $a->requiredtime = $this->get_instance()->requiredtime; return get_string('requiredtimenotmet', 'simplecertificate', $a); } // Mark as complete $completion->update_state($this->coursemodule, COMPLETION_COMPLETE, $user->id); } if ($CFG->enableavailability) { $modinfo = get_fast_modinfo($this->get_course()); $cm = $modinfo->get_cm($this->get_course_module()->id); if (!$cm->uservisible) { if ($cm->availableinfo) { return $cm->availableinfo; } else { return get_string('cantissue', 'simplecertificate'); } } return null; } } }
/** * Updates the timer to the current time and returns the new timer object * @param bool $restart If set to true the timer is restarted * @param bool $continue If set to true AND $restart=true then the timer * will continue from a previous attempt * @return stdClass The new timer */ public function update_timer($restart = false, $continue = false, $endreached = false) { global $USER, $DB; $cm = get_coursemodule_from_instance('lesson', $this->properties->id, $this->properties->course); // clock code // get time information for this user $params = array("lessonid" => $this->properties->id, "userid" => $USER->id); if (!($timer = $DB->get_records('lesson_timer', $params, 'starttime DESC', '*', 0, 1))) { $this->start_timer(); $timer = $DB->get_records('lesson_timer', $params, 'starttime DESC', '*', 0, 1); } $timer = current($timer); // This will get the latest start time record. if ($restart) { if ($continue) { // continue a previous test, need to update the clock (think this option is disabled atm) $timer->starttime = time() - ($timer->lessontime - $timer->starttime); // Trigger lesson resumed event. $event = \mod_lesson\event\lesson_resumed::create(array('objectid' => $this->properties->id, 'context' => context_module::instance($cm->id), 'courseid' => $this->properties->course)); $event->trigger(); } else { // starting over, so reset the clock $timer->starttime = time(); // Trigger lesson restarted event. $event = \mod_lesson\event\lesson_restarted::create(array('objectid' => $this->properties->id, 'context' => context_module::instance($cm->id), 'courseid' => $this->properties->course)); $event->trigger(); } } $timer->lessontime = time(); $timer->completed = $endreached; $DB->update_record('lesson_timer', $timer); // Update completion state. $cm = get_coursemodule_from_instance('lesson', $this->properties()->id, $this->properties()->course, false, MUST_EXIST); $course = get_course($cm->course); $completion = new completion_info($course); if ($completion->is_enabled($cm) && $this->properties()->completiontimespent > 0) { $completion->update_state($cm, COMPLETION_COMPLETE); } return $timer; }
/** * Updates Aggregates for a given user * and notify completion, if needed [feature #7] * * @param object $regiser * @param int $userId */ function attendanceregister__update_user_aggregates($register, $userId) { global $DB; // Delete old aggregates $DB->delete_records('attendanceregister_aggregate', array('userid' => $userId, 'register' => $register->id)); $aggregates = array(); $queryParams = array('registerid' => $register->id, 'userid' => $userId); // Calculate aggregates of offline Sessions if ($register->offlinesessions) { // (note that refcourse has passed as first column to avoid warning of duplicate values in first column by get_records()) $sql = 'SELECT sess.refcourse, sess.register, sess.userid, 0 AS onlinesess, SUM(sess.duration) AS duration, 0 AS total, 0 as grandtotal' . ' FROM {attendanceregister_session} sess' . ' WHERE sess.onlinesess = 0 AND sess.register = :registerid AND sess.userid = :userid' . ' GROUP BY sess.register, sess.userid, sess.refcourse'; $offlinePerCourseAggregates = $DB->get_records_sql($sql, $queryParams); // Append records if ($offlinePerCourseAggregates) { $aggregates = array_merge($aggregates, $offlinePerCourseAggregates); } // Calculates total offline, regardless of RefCourse $sql = 'SELECT sess.register, sess.userid, 0 AS onlinesess, null AS refcourse, SUM(sess.duration) AS duration, 1 AS total, 0 as grandtotal' . ' FROM {attendanceregister_session} sess' . ' WHERE sess.onlinesess = 0 AND sess.register = :registerid AND sess.userid = :userid' . ' GROUP BY sess.register, sess.userid'; $totalOfflineAggregate = $DB->get_record_sql($sql, $queryParams); // Append record if ($totalOfflineAggregate) { $aggregates[] = $totalOfflineAggregate; } } // Calculates aggregates of online Sessions (this is a total as no RefCourse may exist) $sql = 'SELECT sess.register, sess.userid, 1 AS onlinesess, null AS refcourse, SUM(sess.duration) AS duration, 1 AS total, 0 as grandtotal' . ' FROM {attendanceregister_session} sess' . ' WHERE sess.onlinesess = 1 AND sess.register = :registerid AND sess.userid = :userid' . ' GROUP BY sess.register, sess.userid'; $onlineAggregate = $DB->get_record_sql($sql, $queryParams); // If User has no Session, generate an online Total record if (!$onlineAggregate) { $onlineAggregate = new stdClass(); $onlineAggregate->register = $register->id; $onlineAggregate->userid = $userId; $onlineAggregate->onlinesess = 1; $onlineAggregate->refcourse = null; $onlineAggregate->duration = 0; $onlineAggregate->total = 1; $onlineAggregate->grandtotal = 0; } // Append record $aggregates[] = $onlineAggregate; // Calculates grand total $sql = 'SELECT sess.register, sess.userid, null AS onlinesess, null AS refcourse, SUM(sess.duration) AS duration, 0 AS total, 1 as grandtotal' . ' FROM {attendanceregister_session} sess' . ' WHERE sess.register = :registerid AND sess.userid = :userid' . ' GROUP BY sess.register, sess.userid'; $grandTotalAggregate = $DB->get_record_sql($sql, $queryParams); // If User has no Session, generate a grandTotal record if (!$grandTotalAggregate) { $grandTotalAggregate = new stdClass(); $grandTotalAggregate->register = $register->id; $grandTotalAggregate->userid = $userId; $grandTotalAggregate->onlinesess = null; $grandTotalAggregate->refcourse = null; $grandTotalAggregate->duration = 0; $grandTotalAggregate->total = 0; $grandTotalAggregate->grandtotal = 1; } // Add lastSessionLogout to GrandTotal $grandTotalAggregate->lastsessionlogout = attendanceregister__calculate_last_user_online_session_logout($register, $userId); // Append record $aggregates[] = $grandTotalAggregate; // Save all as Aggregates foreach ($aggregates as $aggregate) { $DB->insert_record('attendanceregister_aggregate', $aggregate); } // Notify completion if needed // (only if any completion condition is enabled) if (attendanceregister__isAnyCompletionConditionSpecified($register)) { // Retrieve Course-Module an Course instances $cm = get_coursemodule_from_instance('attendanceregister', $register->id, $register->course, null, MUST_EXIST); $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); $completion = new completion_info($course); if ($completion->is_enabled($cm)) { // Check completion values $completionTrackedValues = array('totaldurationsecs' => $grandTotalAggregate->duration); $isComplete = attendanceregister__areCompletionConditionsMet($register, $completionTrackedValues); // Notify complete or incomplete if ($isComplete) { $completion->update_state($cm, COMPLETION_COMPLETE, $userId); } else { $completion->update_state($cm, COMPLETION_INCOMPLETE, $userId); } } } }
/** * Sets activity completion state * * @param object $scorm object * @param int $userid User ID * @param int $completionstate Completion state * @param array $grades grades array of users with grades - used when $userid = 0 */ function scorm_set_completion($scorm, $userid, $completionstate = COMPLETION_COMPLETE, $grades = array()) { $course = new stdClass(); $course->id = $scorm->course; $completion = new completion_info($course); // Check if completion is enabled site-wide, or for the course. if (!$completion->is_enabled()) { return; } $cm = get_coursemodule_from_instance('scorm', $scorm->id, $scorm->course); if (empty($cm) || !$completion->is_enabled($cm)) { return; } if (empty($userid)) { // We need to get all the relevant users from $grades param. foreach ($grades as $grade) { $completion->update_state($cm, $completionstate, $grade->userid); } } else { $completion->update_state($cm, $completionstate, $userid); } }
/** * Updates completion status based on changes made to entire discussion. * @param bool $positive True if the changes will make things complete * that were previously incomplete; false if they will make things * incomplete that were previously complete */ private function update_completion($positive) { // Get list of affected users (if any) $users = array(); if ($this->forum->get_completion_replies() || $this->forum->get_completion_posts()) { // Affected users = everyone who posted $rootpost = $this->get_root_post(); $posts = array(); $rootpost->build_linear_children($posts); foreach ($posts as $post) { $users[$post->get_user()->id] = true; } } else { if ($this->forum->get_completion_discussions()) { // Affected users = discussion poster only $users[$this->get_poster()->id] = true; } } foreach ($users as $userid => $junk) { $course = $this->get_course(); $cm = $this->get_course_module(); $completion = new completion_info($course); $completion->update_state($cm, $positive ? COMPLETION_COMPLETE : COMPLETION_INCOMPLETE, $userid); } }
/** * Log, update completion info and trigger event * * @param object $course * @param \context_module $context * @param object $cm * @param object $forum * @param object $discussion */ public function trigger_discussion_created($course, \context_module $context, $cm, $forum, $discussion) { global $CFG; require_once $CFG->libdir . '/completionlib.php'; $completion = new \completion_info($course); if ($completion->is_enabled($cm) && ($forum->completiondiscussions || $forum->completionposts)) { $completion->update_state($cm, COMPLETION_COMPLETE); } $params = array('context' => $context, 'objectid' => $discussion->id, 'other' => array('forumid' => $forum->id)); $event = discussion_created::create($params); $event->add_record_snapshot('hsuforum_discussions', $discussion); $event->trigger(); }
/** * Revert to draft. * * @param int $userid * @return boolean */ public function revert_to_draft($userid) { global $DB, $USER; // Need grade permission. require_capability('mod/assign:grade', $this->context); if ($this->get_instance()->teamsubmission) { $submission = $this->get_group_submission($userid, 0, false); } else { $submission = $this->get_user_submission($userid, false); } if (!$submission) { return false; } $submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT; $this->update_submission($submission, $userid, true, $this->get_instance()->teamsubmission); // Give each submission plugin a chance to process the reverting to draft. $plugins = $this->get_submission_plugins(); foreach ($plugins as $plugin) { if ($plugin->is_enabled() && $plugin->is_visible()) { $plugin->revert_to_draft($submission); } } // Update the modified time on the grade (grader modified). $grade = $this->get_user_grade($userid, true); $grade->grader = $USER->id; $this->update_grade($grade); $completion = new completion_info($this->get_course()); if ($completion->is_enabled($this->get_course_module()) && $this->get_instance()->completionsubmit) { $completion->update_state($this->get_course_module(), COMPLETION_INCOMPLETE, $userid); } \mod_assign\event\submission_status_updated::create_from_submission($this, $submission)->trigger(); return true; }
/** * @global object * @param array $attemptids * @param object $choice Choice main table row * @param object $cm Course-module object * @param object $course Course object * @return bool */ function choice_delete_responses($attemptids, $choice, $cm, $course) { global $DB, $CFG; require_once $CFG->libdir . '/completionlib.php'; if (!is_array($attemptids) || empty($attemptids)) { return false; } foreach ($attemptids as $num => $attemptid) { if (empty($attemptid)) { unset($attemptids[$num]); } } $completion = new completion_info($course); foreach ($attemptids as $attemptid) { if ($todelete = $DB->get_record('choice_answers', array('choiceid' => $choice->id, 'id' => $attemptid))) { $DB->delete_records('choice_answers', array('choiceid' => $choice->id, 'id' => $attemptid)); // Update completion state if ($completion->is_enabled($cm) && $choice->completionsubmit) { $completion->update_state($cm, COMPLETION_INCOMPLETE, $attemptid); } } } return true; }
/** * @global object * @param array $userids * @param object $choicegroup Choice main table row * @param object $cm Course-module object * @param object $course Course object * @return bool */ function choicegroup_delete_responses($userids, $choicegroup, $cm, $course) { global $CFG, $DB, $context; require_once $CFG->libdir . '/completionlib.php'; if (!is_array($userids) || empty($userids)) { return false; } foreach ($userids as $num => $userid) { if (empty($userid)) { unset($userids[$num]); } } $completion = new completion_info($course); $eventparams = array('context' => $context, 'objectid' => $choicegroup->id); foreach ($userids as $userid) { if ($current = choicegroup_get_user_answer($choicegroup, $userid)) { $currentgroup = $DB->get_record('groups', array('id' => $current->id), 'id,name', MUST_EXIST); if (groups_is_member($current->id, $userid)) { groups_remove_member($current->id, $userid); $event = \mod_choicegroup\event\choice_removed::create($eventparams); $event->add_record_snapshot('course_modules', $cm); $event->add_record_snapshot('course', $course); $event->add_record_snapshot('choicegroup', $choicegroup); $event->trigger(); } // Update completion state if ($completion->is_enabled($cm) && $choicegroup->completionsubmit) { $completion->update_state($cm, COMPLETION_INCOMPLETE, $userid); } } } return true; }
/** * Save the answer for the given survey * * @param stdClass $survey a survey object * @param array $answersrawdata the answers to be saved * @param stdClass $course a course object (required for trigger the submitted event) * @param stdClass $context a context object (required for trigger the submitted event) * @since Moodle 3.0 */ function survey_save_answers($survey, $answersrawdata, $course, $context) { global $DB, $USER; $answers = array(); // Sort through the data and arrange it. // This is necessary because some of the questions may have two answers, eg Question 1 -> 1 and P1. foreach ($answersrawdata as $key => $val) { if ($key != "userid" && $key != "id") { if (substr($key, 0, 1) == "q") { $key = clean_param(substr($key, 1), PARAM_ALPHANUM); // Keep everything but the 'q', number or P number. } if (substr($key, 0, 1) == "P") { $realkey = (int) substr($key, 1); $answers[$realkey][1] = $val; } else { $answers[$key][0] = $val; } } } // Now store the data. $timenow = time(); $answerstoinsert = array(); foreach ($answers as $key => $val) { if ($key != 'sesskey') { $newdata = new stdClass(); $newdata->time = $timenow; $newdata->userid = $USER->id; $newdata->survey = $survey->id; $newdata->question = $key; if (!empty($val[0])) { $newdata->answer1 = $val[0]; } else { $newdata->answer1 = ""; } if (!empty($val[1])) { $newdata->answer2 = $val[1]; } else { $newdata->answer2 = ""; } $answerstoinsert[] = $newdata; } } if (!empty($answerstoinsert)) { $DB->insert_records("survey_answers", $answerstoinsert); } // Update completion state. $cm = get_coursemodule_from_instance('survey', $survey->id, $course->id); $completion = new completion_info($course); if (isloggedin() && !isguestuser() && $completion->is_enabled($cm) && $survey->completionsubmit) { $completion->update_state($cm, COMPLETION_COMPLETE); } $params = array('context' => $context, 'courseid' => $course->id, 'other' => array('surveyid' => $survey->id)); $event = \mod_survey\event\response_submitted::create($params); $event->trigger(); }
/** * Revert to draft. * * @param int $userid * @return boolean */ public function revert_to_draft($userid) { global $DB, $USER; // Need grade permission. require_capability('mod/assign:grade', $this->context); if ($this->get_instance()->teamsubmission) { $submission = $this->get_group_submission($userid, 0, false); } else { $submission = $this->get_user_submission($userid, false); } if (!$submission) { return false; } $submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT; $this->update_submission($submission, $userid, true, $this->get_instance()->teamsubmission); // Give each submission plugin a chance to process the reverting to draft. $plugins = $this->get_submission_plugins(); foreach ($plugins as $plugin) { if ($plugin->is_enabled() && $plugin->is_visible()) { $plugin->revert_to_draft($submission); } } // Update the modified time on the grade (grader modified). $grade = $this->get_user_grade($userid, true); $grade->grader = $USER->id; $this->update_grade($grade); $user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST); $completion = new completion_info($this->get_course()); if ($completion->is_enabled($this->get_course_module()) && $this->get_instance()->completionsubmit) { $completion->update_state($this->get_course_module(), COMPLETION_INCOMPLETE, $userid); } $logmessage = get_string('reverttodraftforstudent', 'assign', array('id' => $user->id, 'fullname' => fullname($user))); $addtolog = $this->add_to_log('revert submission to draft', $logmessage, '', true); $params = array('context' => $this->context, 'objectid' => $submission->id, 'relateduserid' => $this->get_instance()->teamsubmission ? null : $userid, 'other' => array('newstatus' => $submission->status)); $event = \mod_assign\event\submission_status_updated::create($params); $event->set_legacy_logdata($addtolog); $event->trigger(); return true; }
/** * Test update_activity_completion_status */ public function test_get_activities_completion_status() { global $DB, $CFG; $this->resetAfterTest(true); $CFG->enablecompletion = true; $student = $this->getDataGenerator()->create_user(); $teacher = $this->getDataGenerator()->create_user(); $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1, 'groupmode' => SEPARATEGROUPS, 'groupmodeforce' => 1)); $data = $this->getDataGenerator()->create_module('data', array('course' => $course->id), array('completion' => 1)); $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id), array('completion' => 1)); $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id)); $page = $this->getDataGenerator()->create_module('page', array('course' => $course->id), array('completion' => 1, 'visible' => 0)); $cmdata = get_coursemodule_from_id('data', $data->cmid); $cmforum = get_coursemodule_from_id('forum', $forum->cmid); $studentrole = $DB->get_record('role', array('shortname' => 'student')); $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher')); $this->getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id); $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); // Teacher and student in different groups initially. groups_add_member($group1->id, $student->id); groups_add_member($group2->id, $teacher->id); $this->setUser($student); // Forum complete. $completion = new completion_info($course); $completion->update_state($cmforum, COMPLETION_COMPLETE); $result = core_completion_external::get_activities_completion_status($course->id, $student->id); // We need to execute the return values cleaning process to simulate the web service server. $result = external_api::clean_returnvalue(core_completion_external::get_activities_completion_status_returns(), $result); // We added 4 activities, but only 3 with completion enabled and one of those is hidden. $this->assertCount(2, $result['statuses']); $activitiesfound = 0; foreach ($result['statuses'] as $status) { if ($status['cmid'] == $forum->cmid and $status['modname'] == 'forum' and $status['instance'] == $forum->id) { $activitiesfound++; $this->assertEquals(COMPLETION_COMPLETE, $status['state']); $this->assertEquals(COMPLETION_TRACKING_MANUAL, $status['tracking']); } else { if ($status['cmid'] == $data->cmid and $status['modname'] == 'data' and $status['instance'] == $data->id) { $activitiesfound++; $this->assertEquals(COMPLETION_INCOMPLETE, $status['state']); $this->assertEquals(COMPLETION_TRACKING_MANUAL, $status['tracking']); } } } $this->assertEquals(2, $activitiesfound); // Teacher should see students status, they are in different groups but the teacher can access all groups. $this->setUser($teacher); $result = core_completion_external::get_activities_completion_status($course->id, $student->id); // We need to execute the return values cleaning process to simulate the web service server. $result = external_api::clean_returnvalue(core_completion_external::get_activities_completion_status_returns(), $result); // We added 4 activities, but only 3 with completion enabled and one of those is hidden. $this->assertCount(3, $result['statuses']); // Change teacher role capabilities (disable access al goups). $context = context_course::instance($course->id); assign_capability('moodle/site:accessallgroups', CAP_PROHIBIT, $teacherrole->id, $context); accesslib_clear_all_caches_for_unit_testing(); try { $result = core_completion_external::get_activities_completion_status($course->id, $student->id); $this->fail('Exception expected due to groups permissions.'); } catch (moodle_exception $e) { $this->assertEquals('accessdenied', $e->errorcode); } // Now add the teacher in the same group. groups_add_member($group1->id, $teacher->id); $result = core_completion_external::get_activities_completion_status($course->id, $student->id); // We need to execute the return values cleaning process to simulate the web service server. $result = external_api::clean_returnvalue(core_completion_external::get_activities_completion_status_returns(), $result); // We added 4 activities, but only 3 with completion enabled and one of those is hidden. $this->assertCount(3, $result['statuses']); }
/** * deletes a completed given by completedid. * all related data such values or tracking data also will be deleted * * @global object * @param int $completedid * @return boolean */ function feedback_delete_completed($completedid) { global $DB, $CFG; require_once($CFG->libdir.'/completionlib.php'); if (!$completed = $DB->get_record('feedback_completed', array('id'=>$completedid))) { return false; } if (!$feedback = $DB->get_record('feedback', array('id'=>$completed->feedback))) { return false; } if (!$course = $DB->get_record('course', array('id'=>$feedback->course))) { return false; } if (!$cm = get_coursemodule_from_instance('feedback', $feedback->id)) { return false; } //first we delete all related values $DB->delete_records('feedback_value', array('completed'=>$completed->id)); //now we delete all tracking data $params = array('completed'=>$completed->id, 'feedback'=>$completed->feedback); if ($tracking = $DB->get_record('feedback_tracking', $params)) { $DB->delete_records('feedback_tracking', array('completed'=>$completed->id)); } // Update completion state $completion = new completion_info($course); if ($completion->is_enabled($cm) && $feedback->completionsubmit) { $completion->update_state($cm, COMPLETION_INCOMPLETE, $completed->userid); } //last we delete the completed-record return $DB->delete_records('feedback_completed', array('id'=>$completed->id)); }
$DB->set_field('ouwiki_versions', 'deletedat', null, array('id' => $versionid)); // Get first undeleted (current) page version (there must be one) $pageversions = ouwiki_get_page_history($pageversion->pageid, false, 0, 1); $currentpageversion = reset($pageversions); if (!$currentpageversion) { throw new Exception('Error deleting/undeleting ouwiki page version'); } // Check if version that has been undeleted should be the new current version if ($pageversion->currentversionid != $currentpageversion->versionid) { // Set new current version id $DB->set_field('ouwiki_pages', 'currentversionid', $currentpageversion->versionid, array('id' => $pageversion->pageid)); } // Update completion status for user $completion = new completion_info($course); if ($completion->is_enabled($cm) && ($ouwiki->completionedits || $ouwiki->completionpages)) { $completion->update_state($cm, COMPLETION_COMPLETE, $pageversion->userid); } } } catch (Exception $e) { // Unlock page ouwiki_release_lock($pageversion->pageid); ouwiki_dberror('Error deleting/undeleting ouwiki page version ' . $e); } // Unlock page ouwiki_release_lock($pageversion->pageid); // Log delete or undelete action $ouwikiparamsurl = ouwiki_display_wiki_parameters($pagename, $subwiki, $cm, OUWIKI_PARAMS_URL); add_to_log($course->id, 'ouwiki', 'version' . $action, 'delete.php?' . $ouwikiparamsurl . '&version=' . $versionid, '', $cm->id); $redirecturl = new moodle_url('/mod/ouwiki/history.php'); // Redirect to view what is now the current version redirect($redirecturl . '?' . $ouwikiparamsurl);
default: break; } } if ($optionIDPos > -1 && $userIDPos > -1 && $completedPos > -1) { array_shift($csvArr); $completion = new completion_info($course); foreach ($csvArr as $line) { if (count($line) >= 3) { $user = $DB->get_record('booking_answers', array('bookingid' => $booking->id, 'userid' => $line[$userIDPos], 'optionid' => $line[$optionIDPos])); if ($user !== FALSE) { $user->completed = $line[$completedPos]; $user->timemodified = time(); $DB->update_record('booking_answers', $user, false); if ($completion->is_enabled($cm) && $booking->enablecompletion && $user->completed == 0) { $completion->update_state($cm, COMPLETION_INCOMPLETE, $user->userid); } if ($completion->is_enabled($cm) && $booking->enablecompletion && $user->completed == 1) { $completion->update_state($cm, COMPLETION_COMPLETE, $user->userid); } } } } redirect($urlRedirect, get_string('importfinished', 'booking'), 5); } else { redirect($urlRedirect, get_string('wrongfile', 'booking'), 5); } //In this case you process validated data. $mform->get_data() returns data posted in form. } else { echo $OUTPUT->header(); echo $OUTPUT->heading(get_string("importexceltitle", "booking"), 3, 'helptitle', 'uniqueid');
/** * revert to draft * Uses url parameter userid * * @param int $userid * @return void */ private function process_revert_to_draft($userid = 0) { global $DB, $USER; // Need grade permission require_capability('mod/assign:grade', $this->context); require_sesskey(); if (!$userid) { $userid = required_param('userid', PARAM_INT); } $submission = $this->get_user_submission($userid, false); if (!$submission) { return; } $submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT; $this->update_submission($submission, $USER->id, true, $this->get_instance()->teamsubmission); // Update the modified time on the grade (grader modified). $grade = $this->get_user_grade($userid, true); $grade->grader = $USER->id; $this->update_grade($grade); $user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST); $completion = new completion_info($this->get_course()); if ($completion->is_enabled($this->get_course_module()) && $this->get_instance()->completionsubmit) { $completion->update_state($this->get_course_module(), COMPLETION_INCOMPLETE, $userid); } $this->add_to_log('revert submission to draft', get_string('reverttodraftforstudent', 'assign', array('id'=>$user->id, 'fullname'=>fullname($user)))); }
/** * Deletes a single forum post. * * @global object * @param object $post Forum post object * @param mixed $children Whether to delete children. If false, returns false * if there are any children (without deleting the post). If true, * recursively deletes all children. If set to special value 'ignore', deletes * post regardless of children (this is for use only when deleting all posts * in a disussion). * @param object $course Course * @param object $cm Course-module * @param object $forum Forum * @param bool $skipcompletion True to skip updating completion state if it * would otherwise be updated, i.e. when deleting entire forum anyway. * @return bool */ function forum_delete_post($post, $children, $course, $cm, $forum, $skipcompletion=false) { global $DB, $CFG; require_once($CFG->libdir.'/completionlib.php'); $context = context_module::instance($cm->id); if ($children !== 'ignore' && ($childposts = $DB->get_records('forum_posts', array('parent'=>$post->id)))) { if ($children) { foreach ($childposts as $childpost) { forum_delete_post($childpost, true, $course, $cm, $forum, $skipcompletion); } } else { return false; } } //delete ratings require_once($CFG->dirroot.'/rating/lib.php'); $delopt = new stdClass; $delopt->contextid = $context->id; $delopt->component = 'mod_forum'; $delopt->ratingarea = 'post'; $delopt->itemid = $post->id; $rm = new rating_manager(); $rm->delete_ratings($delopt); //delete attachments $fs = get_file_storage(); $fs->delete_area_files($context->id, 'mod_forum', 'attachment', $post->id); $fs->delete_area_files($context->id, 'mod_forum', 'post', $post->id); if ($DB->delete_records("forum_posts", array("id" => $post->id))) { forum_tp_delete_read_records(-1, $post->id); // Just in case we are deleting the last post forum_discussion_update_last_post($post->discussion); // Update completion state if we are tracking completion based on number of posts // But don't bother when deleting whole thing if (!$skipcompletion) { $completion = new completion_info($course); if ($completion->is_enabled($cm) == COMPLETION_TRACKING_AUTOMATIC && ($forum->completiondiscussions || $forum->completionreplies || $forum->completionposts)) { $completion->update_state($cm, COMPLETION_INCOMPLETE, $post->userid); } } return true; } return false; }
public function view() { global $CFG, $USER, $PAGE, $OUTPUT; $PAGE->set_title(format_string($this->name)); $PAGE->set_heading(format_string($this->course->fullname)); // Initialise the JavaScript. $PAGE->requires->js_init_call('M.mod_questionnaire.init_attempt_form', null, false, questionnaire_get_js_module()); echo $OUTPUT->header(); $questionnaire = $this; if (!$this->cm->visible && !$this->capabilities->viewhiddenactivities) { notice(get_string("activityiscurrentlyhidden")); } if (!$this->capabilities->view) { echo '<br/>'; questionnaire_notify(get_string("noteligible", "questionnaire", $this->name)); echo '<div><a href="' . $CFG->wwwroot . '/course/view.php?id=' . $this->course->id . '">' . get_string("continue") . '</a></div>'; exit; } // Print the main part of the page. if (!$this->is_active()) { echo '<div class="notifyproblem">' . get_string('notavail', 'questionnaire') . '</div>'; } else { if (!$this->is_open()) { echo '<div class="notifyproblem">' . get_string('notopen', 'questionnaire', userdate($this->opendate)) . '</div>'; } else { if ($this->is_closed()) { echo '<div class="notifyproblem">' . get_string('closed', 'questionnaire', userdate($this->closedate)) . '</div>'; } else { if (!$this->user_is_eligible($USER->id)) { echo '<div class="notifyproblem">' . get_string('noteligible', 'questionnaire') . '</div>'; } else { if ($this->user_can_take($USER->id)) { $quser = $USER->id; if ($this->survey->realm == 'template') { print_string('templatenotviewable', 'questionnaire'); echo $OUTPUT->footer($this->course); exit; } $msg = $this->print_survey($USER->id, $quser); // If Questionnaire was submitted with all required fields completed ($msg is empty), // then record the submittal. $viewform = data_submitted($CFG->wwwroot . "/mod/questionnaire/complete.php"); if (!empty($viewform->rid)) { $viewform->rid = (int) $viewform->rid; } if (!empty($viewform->sec)) { $viewform->sec = (int) $viewform->sec; } if (data_submitted() && confirm_sesskey() && isset($viewform->submit) && isset($viewform->submittype) && $viewform->submittype == "Submit Survey" && empty($msg)) { $this->response_delete($viewform->rid, $viewform->sec); $this->rid = $this->response_insert($this->survey->id, $viewform->sec, $viewform->rid, $quser); $this->response_commit($this->rid); // If it was a previous save, rid is in the form... if (!empty($viewform->rid) && is_numeric($viewform->rid)) { $rid = $viewform->rid; // Otherwise its in this object. } else { $rid = $this->rid; } questionnaire_record_submission($this, $USER->id, $rid); if ($this->grade != 0) { $questionnaire = new stdClass(); $questionnaire->id = $this->id; $questionnaire->name = $this->name; $questionnaire->grade = $this->grade; $questionnaire->cmidnumber = $this->cm->idnumber; $questionnaire->courseid = $this->course->id; questionnaire_update_grades($questionnaire, $quser); } // Update completion state. $completion = new completion_info($this->course); if ($completion->is_enabled($this->cm) && $this->completionsubmit) { $completion->update_state($this->cm, COMPLETION_COMPLETE); } // Log this submitted response. $context = context_module::instance($this->cm->id); $anonymous = $this->respondenttype == 'anonymous'; $params = array('context' => $context, 'courseid' => $this->course->id, 'relateduserid' => $USER->id, 'anonymous' => $anonymous, 'other' => array('questionnaireid' => $questionnaire->id)); $event = \mod_questionnaire\event\attempt_submitted::create($params); $event->trigger(); $this->response_send_email($this->rid); $this->response_goto_thankyou(); } } else { switch ($this->qtype) { case QUESTIONNAIREDAILY: $msgstring = ' ' . get_string('today', 'questionnaire'); break; case QUESTIONNAIREWEEKLY: $msgstring = ' ' . get_string('thisweek', 'questionnaire'); break; case QUESTIONNAIREMONTHLY: $msgstring = ' ' . get_string('thismonth', 'questionnaire'); break; default: $msgstring = ''; break; } echo '<div class="notifyproblem">' . get_string("alreadyfilled", "questionnaire", $msgstring) . '</div>'; } } } } } // Finish the page. echo $OUTPUT->footer($this->course); }