/** * Tests getting forum object from id and cmid, inc clones. */ public function test_lib_hooks() { global $USER, $DB; $this->resetAfterTest(); $generator = $this->getDataGenerator()->get_plugin_generator('mod_forumng'); $course = $this->get_new_course(); $suser = $this->get_new_user('student', $course->id); $forum = $this->get_new_forumng($course->id, array('name' => 'TEST', 'intro' => 'abc123', 'enableratings' => mod_forumng::FORUMNG_STANDARD_RATING, 'ratingscale' => 10)); $cm = get_coursemodule_from_instance('forumng', $forum->get_id()); $result = forumng_rating_permissions($forum->get_context()->id, 'mod_forumng', 'post'); $this->assertTrue(is_array($result)); foreach ($result as $cap) { $this->assertFalse($cap); } $this->setAdminUser(); $result = forumng_rating_permissions($forum->get_context()->id, 'mod_forumng', 'post'); $this->assertTrue(is_array($result)); foreach ($result as $cap) { $this->assertTrue($cap); } $did1 = $generator->create_discussion(array('course' => $course, 'forum' => $forum->get_id(), 'userid' => $USER->id)); $post = $generator->create_post(array('discussionid' => $did1[0], 'parentpostid' => $did1[1], 'userid' => $suser->id)); $rm = new rating_manager(); $params = array(); $params['context'] = $forum->get_context(); $params['component'] = 'mod_forumng'; $params['ratingarea'] = 'post'; $params['itemid'] = $did1[1]; $params['scaleid'] = $forum->get_rating_scale(); $params['rateduserid'] = $USER->id; $params['rating'] = 21; // Check rating valid, should fail with same user + rating too high. $this->setExpectedException('rating_exception', get_string('nopermissiontorate', 'error')); $rm->check_rating_is_valid($params); $params['itemid'] = $post->id; $params['rateduserid'] = $suser->id; $this->setExpectedException('rating_exception', get_string('invalidnum', 'error')); $rm->check_rating_is_valid($params); $params['rating'] = 10; $result = $rm->check_rating_is_valid($params); $this->assertTrue($result); // Call to update grades (should do nothing as grading not set, no assertions). forumng_update_grades($DB->get_record('forumng', array('id' => $forum->get_id()))); // Check clones. $forum1 = $this->get_new_forumng($course->id, array('name' => 'TEST', 'intro' => 'abc123', 'shared' => true, 'cmidnumber' => 'SF1', 'enableratings' => mod_forumng::FORUMNG_STANDARD_RATING, 'ratingscale' => 10)); $forum2 = $this->get_new_forumng($course->id, array('name' => 'TEST', 'usesharedgroup' => array('useshared' => true, 'originalcmidnumber' => 'SF1'))); $did1 = $generator->create_discussion(array('course' => $course, 'forum' => $forum1->get_id(), 'userid' => $USER->id)); $post = $generator->create_post(array('discussionid' => $did1[0], 'parentpostid' => $did1[1], 'userid' => $suser->id)); $params['itemid'] = $post->id; $params['context'] = $forum2->get_context(true); $result = $rm->check_rating_is_valid($params); $this->assertTrue($result); }
$userrating = required_param('rating', PARAM_INT); $rateduserid = required_param('rateduserid', PARAM_INT); // The user being rated. Required to update their grade. $aggregationmethod = optional_param('aggregation', RATING_AGGREGATE_NONE, PARAM_INT); // Used to calculate the aggregate to return. $result = new stdClass(); // If session has expired and its an ajax request so we cant do a page redirect. if (!isloggedin()) { $result->error = get_string('sessionerroruser', 'error'); echo json_encode($result); die; } list($context, $course, $cm) = get_context_info_array($contextid); require_login($course, false, $cm); $contextid = null; // Now we have a context object, throw away the id from the user. $PAGE->set_context($context); $PAGE->set_url('/rating/rate_ajax.php', array('contextid' => $context->id)); if (!confirm_sesskey() || !has_capability('moodle/rating:rate', $context)) { echo $OUTPUT->header(); echo get_string('ratepermissiondenied', 'rating'); echo $OUTPUT->footer(); die; } $rm = new rating_manager(); $result = $rm->add_rating($cm, $context, $component, $ratingarea, $itemid, $scaleid, $userrating, $rateduserid, $aggregationmethod); // Return translated error. if (!empty($result->error)) { $result->error = get_string($result->error, 'rating'); } echo json_encode($result);
/** * This function is used by the reset_course_userdata function in moodlelib. * This function will remove all posts from the specified forum * and clean up any related data. * * @global object * @global object * @param $data the data submitted from the reset course. * @return array status array */ function forum_reset_userdata($data) { global $CFG, $DB; require_once($CFG->dirroot.'/rating/lib.php'); $componentstr = get_string('modulenameplural', 'forum'); $status = array(); $params = array($data->courseid); $removeposts = false; $typesql = ""; if (!empty($data->reset_forum_all)) { $removeposts = true; $typesstr = get_string('resetforumsall', 'forum'); $types = array(); } else if (!empty($data->reset_forum_types)){ $removeposts = true; $typesql = ""; $types = array(); $forum_types_all = forum_get_forum_types_all(); foreach ($data->reset_forum_types as $type) { if (!array_key_exists($type, $forum_types_all)) { continue; } $typesql .= " AND f.type=?"; $types[] = $forum_types_all[$type]; $params[] = $type; } $typesstr = get_string('resetforums', 'forum').': '.implode(', ', $types); } $alldiscussionssql = "SELECT fd.id FROM {forum_discussions} fd, {forum} f WHERE f.course=? AND f.id=fd.forum"; $allforumssql = "SELECT f.id FROM {forum} f WHERE f.course=?"; $allpostssql = "SELECT fp.id FROM {forum_posts} fp, {forum_discussions} fd, {forum} f WHERE f.course=? AND f.id=fd.forum AND fd.id=fp.discussion"; $forumssql = $forums = $rm = null; if( $removeposts || !empty($data->reset_forum_ratings) ) { $forumssql = "$allforumssql $typesql"; $forums = $forums = $DB->get_records_sql($forumssql, $params); $rm = new rating_manager(); $ratingdeloptions = new stdClass; $ratingdeloptions->component = 'mod_forum'; $ratingdeloptions->ratingarea = 'post'; } if ($removeposts) { $discussionssql = "$alldiscussionssql $typesql"; $postssql = "$allpostssql $typesql"; // now get rid of all attachments $fs = get_file_storage(); if ($forums) { foreach ($forums as $forumid=>$unused) { if (!$cm = get_coursemodule_from_instance('forum', $forumid)) { continue; } $context = context_module::instance($cm->id); $fs->delete_area_files($context->id, 'mod_forum', 'attachment'); $fs->delete_area_files($context->id, 'mod_forum', 'post'); //remove ratings $ratingdeloptions->contextid = $context->id; $rm->delete_ratings($ratingdeloptions); } } // first delete all read flags $DB->delete_records_select('forum_read', "forumid IN ($forumssql)", $params); // remove tracking prefs $DB->delete_records_select('forum_track_prefs', "forumid IN ($forumssql)", $params); // remove posts from queue $DB->delete_records_select('forum_queue', "discussionid IN ($discussionssql)", $params); // all posts - initial posts must be kept in single simple discussion forums $DB->delete_records_select('forum_posts', "discussion IN ($discussionssql) AND parent <> 0", $params); // first all children $DB->delete_records_select('forum_posts', "discussion IN ($discussionssql AND f.type <> 'single') AND parent = 0", $params); // now the initial posts for non single simple // finally all discussions except single simple forums $DB->delete_records_select('forum_discussions', "forum IN ($forumssql AND f.type <> 'single')", $params); // remove all grades from gradebook if (empty($data->reset_gradebook_grades)) { if (empty($types)) { forum_reset_gradebook($data->courseid); } else { foreach ($types as $type) { forum_reset_gradebook($data->courseid, $type); } } } $status[] = array('component'=>$componentstr, 'item'=>$typesstr, 'error'=>false); } // remove all ratings in this course's forums if (!empty($data->reset_forum_ratings)) { if ($forums) { foreach ($forums as $forumid=>$unused) { if (!$cm = get_coursemodule_from_instance('forum', $forumid)) { continue; } $context = context_module::instance($cm->id); //remove ratings $ratingdeloptions->contextid = $context->id; $rm->delete_ratings($ratingdeloptions); } } // remove all grades from gradebook if (empty($data->reset_gradebook_grades)) { forum_reset_gradebook($data->courseid); } } // remove all subscriptions unconditionally - even for users still enrolled in course if (!empty($data->reset_forum_subscriptions)) { $DB->delete_records_select('forum_subscriptions', "forum IN ($allforumssql)", $params); $status[] = array('component'=>$componentstr, 'item'=>get_string('resetsubscriptions','forum'), 'error'=>false); } // remove all tracking prefs unconditionally - even for users still enrolled in course if (!empty($data->reset_forum_track_prefs)) { $DB->delete_records_select('forum_track_prefs', "forumid IN ($allforumssql)", $params); $status[] = array('component'=>$componentstr, 'item'=>get_string('resettrackprefs','forum'), 'error'=>false); } /// updating dates - shift may be negative too if ($data->timeshift) { shift_course_mod_dates('forum', array('assesstimestart', 'assesstimefinish'), $data->timeshift, $data->courseid); $status[] = array('component'=>$componentstr, 'item'=>get_string('datechanged'), 'error'=>false); } return $status; }
$returnurl = required_param('returnurl', PARAM_LOCALURL); //required for non-ajax requests $result = new stdClass(); list($context, $course, $cm) = get_context_info_array($contextid); require_login($course, false, $cm); $contextid = null; //now we have a context object throw away the id from the user $PAGE->set_context($context); $PAGE->set_url('/rating/rate.php', array('contextid' => $context->id)); if (!confirm_sesskey() || !has_capability('moodle/rating:rate', $context)) { echo $OUTPUT->header(); echo get_string('ratepermissiondenied', 'rating'); echo $OUTPUT->footer(); die; } $rm = new rating_manager(); //check the module rating permissions //doing this check here rather than within rating_manager::get_ratings() so we can return a json error response $pluginpermissionsarray = $rm->get_plugin_permissions_array($context->id, $component, $ratingarea); if (!$pluginpermissionsarray['rate']) { $result->error = get_string('ratepermissiondenied', 'rating'); echo json_encode($result); die; } else { $params = array('context' => $context, 'component' => $component, 'ratingarea' => $ratingarea, 'itemid' => $itemid, 'scaleid' => $scaleid, 'rating' => $userrating, 'rateduserid' => $rateduserid); if (!$rm->check_rating_is_valid($params)) { echo $OUTPUT->header(); echo get_string('ratinginvalid', 'rating'); echo $OUTPUT->footer(); die; }
/** * Produces the html that represents this rating in the UI * * @param rating $rating the page object on which this rating will appear * @return string */ function render_rating(rating $rating) { global $CFG, $USER; if ($rating->settings->aggregationmethod == RATING_AGGREGATE_NONE) { return null;//ratings are turned off } $ratingmanager = new rating_manager(); // Initialise the JavaScript so ratings can be done by AJAX. $ratingmanager->initialise_rating_javascript($this->page); $strrate = get_string("rate", "rating"); $ratinghtml = ''; //the string we'll return // permissions check - can they view the aggregate? if ($rating->user_can_view_aggregate()) { $aggregatelabel = $ratingmanager->get_aggregate_label($rating->settings->aggregationmethod); $aggregatestr = $rating->get_aggregate_string(); $aggregatehtml = html_writer::tag('span', $aggregatestr, array('id' => 'ratingaggregate'.$rating->itemid, 'class' => 'ratingaggregate')).' '; if ($rating->count > 0) { $countstr = "({$rating->count})"; } else { $countstr = '-'; } $aggregatehtml .= html_writer::tag('span', $countstr, array('id'=>"ratingcount{$rating->itemid}", 'class' => 'ratingcount')).' '; $ratinghtml .= html_writer::tag('span', $aggregatelabel, array('class'=>'rating-aggregate-label')); if ($rating->settings->permissions->viewall && $rating->settings->pluginpermissions->viewall) { $nonpopuplink = $rating->get_view_ratings_url(); $popuplink = $rating->get_view_ratings_url(true); $action = new popup_action('click', $popuplink, 'ratings', array('height' => 400, 'width' => 600)); $ratinghtml .= $this->action_link($nonpopuplink, $aggregatehtml, $action); } else { $ratinghtml .= $aggregatehtml; } } $formstart = null; // if the item doesn't belong to the current user, the user has permission to rate // and we're within the assessable period if ($rating->user_can_rate()) { $rateurl = $rating->get_rate_url(); $inputs = $rateurl->params(); //start the rating form $formattrs = array( 'id' => "postrating{$rating->itemid}", 'class' => 'postratingform', 'method' => 'post', 'action' => $rateurl->out_omit_querystring() ); $formstart = html_writer::start_tag('form', $formattrs); $formstart .= html_writer::start_tag('div', array('class' => 'ratingform')); // add the hidden inputs foreach ($inputs as $name => $value) { $attributes = array('type' => 'hidden', 'class' => 'ratinginput', 'name' => $name, 'value' => $value); $formstart .= html_writer::empty_tag('input', $attributes); } if (empty($ratinghtml)) { $ratinghtml .= $strrate.': '; } $ratinghtml = $formstart.$ratinghtml; $scalearray = array(RATING_UNSET_RATING => $strrate.'...') + $rating->settings->scale->scaleitems; $scaleattrs = array('class'=>'postratingmenu ratinginput','id'=>'menurating'.$rating->itemid); $ratinghtml .= html_writer::label($rating->rating, 'menurating'.$rating->itemid, false, array('class' => 'accesshide')); $ratinghtml .= html_writer::select($scalearray, 'rating', $rating->rating, false, $scaleattrs); //output submit button $ratinghtml .= html_writer::start_tag('span', array('class'=>"ratingsubmit")); $attributes = array('type' => 'submit', 'class' => 'postratingmenusubmit', 'id' => 'postratingsubmit'.$rating->itemid, 'value' => s(get_string('rate', 'rating'))); $ratinghtml .= html_writer::empty_tag('input', $attributes); if (!$rating->settings->scale->isnumeric) { // If a global scale, try to find current course ID from the context if (empty($rating->settings->scale->courseid) and $coursecontext = $rating->context->get_course_context(false)) { $courseid = $coursecontext->instanceid; } else { $courseid = $rating->settings->scale->courseid; } $ratinghtml .= $this->help_icon_scale($courseid, $rating->settings->scale); } $ratinghtml .= html_writer::end_tag('span'); $ratinghtml .= html_writer::end_tag('div'); $ratinghtml .= html_writer::end_tag('form'); } return $ratinghtml; }
/** * Clear a course out completely, deleting all content but don't delete the course itself. * * This function does not verify any permissions. * * Please note this function also deletes all user enrolments, * enrolment instances and role assignments by default. * * $options: * - 'keep_roles_and_enrolments' - false by default * - 'keep_groups_and_groupings' - false by default * * @param int $courseid The id of the course that is being deleted * @param bool $showfeedback Whether to display notifications of each action the function performs. * @param array $options extra options * @return bool true if all the removals succeeded. false if there were any failures. If this * method returns false, some of the removals will probably have succeeded, and others * failed, but you have no way of knowing which. */ function remove_course_contents($courseid, $showfeedback = true, array $options = null) { global $CFG, $DB, $OUTPUT; require_once $CFG->libdir . '/badgeslib.php'; require_once $CFG->libdir . '/completionlib.php'; require_once $CFG->libdir . '/questionlib.php'; require_once $CFG->libdir . '/gradelib.php'; require_once $CFG->dirroot . '/group/lib.php'; require_once $CFG->dirroot . '/comment/lib.php'; require_once $CFG->dirroot . '/rating/lib.php'; require_once $CFG->dirroot . '/notes/lib.php'; // Handle course badges. badges_handle_course_deletion($courseid); // NOTE: these concatenated strings are suboptimal, but it is just extra info... $strdeleted = get_string('deleted') . ' - '; // Some crazy wishlist of stuff we should skip during purging of course content. $options = (array) $options; $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST); $coursecontext = context_course::instance($courseid); $fs = get_file_storage(); // Delete course completion information, this has to be done before grades and enrols. $cc = new completion_info($course); $cc->clear_criteria(); if ($showfeedback) { echo $OUTPUT->notification($strdeleted . get_string('completion', 'completion'), 'notifysuccess'); } // Remove all data from gradebook - this needs to be done before course modules // because while deleting this information, the system may need to reference // the course modules that own the grades. remove_course_grades($courseid, $showfeedback); remove_grade_letters($coursecontext, $showfeedback); // Delete course blocks in any all child contexts, // they may depend on modules so delete them first. $childcontexts = $coursecontext->get_child_contexts(); // Returns all subcontexts since 2.2. foreach ($childcontexts as $childcontext) { blocks_delete_all_for_context($childcontext->id); } unset($childcontexts); blocks_delete_all_for_context($coursecontext->id); if ($showfeedback) { echo $OUTPUT->notification($strdeleted . get_string('type_block_plural', 'plugin'), 'notifysuccess'); } // Get the list of all modules that are properly installed. $allmodules = $DB->get_records_menu('modules', array(), '', 'name, id'); // Delete every instance of every module, // this has to be done before deleting of course level stuff. $locations = core_component::get_plugin_list('mod'); foreach ($locations as $modname => $moddir) { if ($modname === 'NEWMODULE') { continue; } if (array_key_exists($modname, $allmodules)) { $sql = "SELECT cm.*, m.id AS modinstance, m.name, '{$modname}' AS modname\n FROM {" . $modname . "} m\n LEFT JOIN {course_modules} cm ON cm.instance = m.id AND cm.module = :moduleid\n WHERE m.course = :courseid"; $instances = $DB->get_records_sql($sql, array('courseid' => $course->id, 'modulename' => $modname, 'moduleid' => $allmodules[$modname])); include_once "{$moddir}/lib.php"; // Shows php warning only if plugin defective. $moddelete = $modname . '_delete_instance'; // Delete everything connected to an instance. $moddeletecourse = $modname . '_delete_course'; // Delete other stray stuff (uncommon). if ($instances) { foreach ($instances as $cm) { if ($cm->id) { // Delete activity context questions and question categories. question_delete_activity($cm, $showfeedback); // Notify the competency subsystem. \core_competency\api::hook_course_module_deleted($cm); } if (function_exists($moddelete)) { // This purges all module data in related tables, extra user prefs, settings, etc. $moddelete($cm->modinstance); } else { // NOTE: we should not allow installation of modules with missing delete support! debugging("Defective module '{$modname}' detected when deleting course contents: missing function {$moddelete}()!"); $DB->delete_records($modname, array('id' => $cm->modinstance)); } if ($cm->id) { // Delete cm and its context - orphaned contexts are purged in cron in case of any race condition. context_helper::delete_instance(CONTEXT_MODULE, $cm->id); $DB->delete_records('course_modules', array('id' => $cm->id)); } } } if (function_exists($moddeletecourse)) { // Execute optional course cleanup callback. Deprecated since Moodle 3.2. TODO MDL-53297 remove in 3.6. debugging("Callback delete_course is deprecated. Function {$moddeletecourse} should be converted " . 'to observer of event \\core\\event\\course_content_deleted', DEBUG_DEVELOPER); $moddeletecourse($course, $showfeedback); } if ($instances and $showfeedback) { echo $OUTPUT->notification($strdeleted . get_string('pluginname', $modname), 'notifysuccess'); } } else { // Ooops, this module is not properly installed, force-delete it in the next block. } } // We have tried to delete everything the nice way - now let's force-delete any remaining module data. // Remove all data from availability and completion tables that is associated // with course-modules belonging to this course. Note this is done even if the // features are not enabled now, in case they were enabled previously. $DB->delete_records_select('course_modules_completion', 'coursemoduleid IN (SELECT id from {course_modules} WHERE course=?)', array($courseid)); // Remove course-module data that has not been removed in modules' _delete_instance callbacks. $cms = $DB->get_records('course_modules', array('course' => $course->id)); $allmodulesbyid = array_flip($allmodules); foreach ($cms as $cm) { if (array_key_exists($cm->module, $allmodulesbyid)) { try { $DB->delete_records($allmodulesbyid[$cm->module], array('id' => $cm->instance)); } catch (Exception $e) { // Ignore weird or missing table problems. } } context_helper::delete_instance(CONTEXT_MODULE, $cm->id); $DB->delete_records('course_modules', array('id' => $cm->id)); } if ($showfeedback) { echo $OUTPUT->notification($strdeleted . get_string('type_mod_plural', 'plugin'), 'notifysuccess'); } // Cleanup the rest of plugins. Deprecated since Moodle 3.2. TODO MDL-53297 remove in 3.6. $cleanuplugintypes = array('report', 'coursereport', 'format'); $callbacks = get_plugins_with_function('delete_course', 'lib.php'); foreach ($cleanuplugintypes as $type) { if (!empty($callbacks[$type])) { foreach ($callbacks[$type] as $pluginfunction) { debugging("Callback delete_course is deprecated. Function {$pluginfunction} should be converted " . 'to observer of event \\core\\event\\course_content_deleted', DEBUG_DEVELOPER); $pluginfunction($course->id, $showfeedback); } if ($showfeedback) { echo $OUTPUT->notification($strdeleted . get_string('type_' . $type . '_plural', 'plugin'), 'notifysuccess'); } } } // Delete questions and question categories. question_delete_course($course, $showfeedback); if ($showfeedback) { echo $OUTPUT->notification($strdeleted . get_string('questions', 'question'), 'notifysuccess'); } // Make sure there are no subcontexts left - all valid blocks and modules should be already gone. $childcontexts = $coursecontext->get_child_contexts(); // Returns all subcontexts since 2.2. foreach ($childcontexts as $childcontext) { $childcontext->delete(); } unset($childcontexts); // Remove all roles and enrolments by default. if (empty($options['keep_roles_and_enrolments'])) { // This hack is used in restore when deleting contents of existing course. role_unassign_all(array('contextid' => $coursecontext->id, 'component' => ''), true); enrol_course_delete($course); if ($showfeedback) { echo $OUTPUT->notification($strdeleted . get_string('type_enrol_plural', 'plugin'), 'notifysuccess'); } } // Delete any groups, removing members and grouping/course links first. if (empty($options['keep_groups_and_groupings'])) { groups_delete_groupings($course->id, $showfeedback); groups_delete_groups($course->id, $showfeedback); } // Filters be gone! filter_delete_all_for_context($coursecontext->id); // Notes, you shall not pass! note_delete_all($course->id); // Die comments! comment::delete_comments($coursecontext->id); // Ratings are history too. $delopt = new stdclass(); $delopt->contextid = $coursecontext->id; $rm = new rating_manager(); $rm->delete_ratings($delopt); // Delete course tags. core_tag_tag::remove_all_item_tags('core', 'course', $course->id); // Notify the competency subsystem. \core_competency\api::hook_course_deleted($course); // Delete calendar events. $DB->delete_records('event', array('courseid' => $course->id)); $fs->delete_area_files($coursecontext->id, 'calendar'); // Delete all related records in other core tables that may have a courseid // This array stores the tables that need to be cleared, as // table_name => column_name that contains the course id. $tablestoclear = array('backup_courses' => 'courseid', 'user_lastaccess' => 'courseid'); foreach ($tablestoclear as $table => $col) { $DB->delete_records($table, array($col => $course->id)); } // Delete all course backup files. $fs->delete_area_files($coursecontext->id, 'backup'); // Cleanup course record - remove links to deleted stuff. $oldcourse = new stdClass(); $oldcourse->id = $course->id; $oldcourse->summary = ''; $oldcourse->cacherev = 0; $oldcourse->legacyfiles = 0; if (!empty($options['keep_groups_and_groupings'])) { $oldcourse->defaultgroupingid = 0; } $DB->update_record('course', $oldcourse); // Delete course sections. $DB->delete_records('course_sections', array('course' => $course->id)); // Delete legacy, section and any other course files. $fs->delete_area_files($coursecontext->id, 'course'); // Files from summary and section. // Delete all remaining stuff linked to context such as files, comments, ratings, etc. if (empty($options['keep_roles_and_enrolments']) and empty($options['keep_groups_and_groupings'])) { // Easy, do not delete the context itself... $coursecontext->delete_content(); } else { // Hack alert!!!! // We can not drop all context stuff because it would bork enrolments and roles, // there might be also files used by enrol plugins... } // Delete legacy files - just in case some files are still left there after conversion to new file api, // also some non-standard unsupported plugins may try to store something there. fulldelete($CFG->dataroot . '/' . $course->id); // Delete from cache to reduce the cache size especially makes sense in case of bulk course deletion. $cachemodinfo = cache::make('core', 'coursemodinfo'); $cachemodinfo->delete($courseid); // Trigger a course content deleted event. $event = \core\event\course_content_deleted::create(array('objectid' => $course->id, 'context' => $coursecontext, 'other' => array('shortname' => $course->shortname, 'fullname' => $course->fullname, 'options' => $options))); $event->add_record_snapshot('course', $course); $event->trigger(); return true; }
/** * Actual implementation of the reset course functionality, delete all the * data responses for course $data->courseid. * * @global object * @global object * @param object $data the data submitted from the reset course. * @return array status array */ function data_reset_userdata($data) { global $CFG, $DB; require_once $CFG->libdir . '/filelib.php'; require_once $CFG->dirroot . '/rating/lib.php'; $componentstr = get_string('modulenameplural', 'data'); $status = array(); $allrecordssql = "SELECT r.id\n FROM {data_records} r\n INNER JOIN {data} d ON r.dataid = d.id\n WHERE d.course = ?"; $alldatassql = "SELECT d.id\n FROM {data} d\n WHERE d.course=?"; $rm = new rating_manager(); $ratingdeloptions = new stdClass(); $ratingdeloptions->component = 'mod_data'; $ratingdeloptions->ratingarea = 'entry'; // Set the file storage - may need it to remove files later. $fs = get_file_storage(); // delete entries if requested if (!empty($data->reset_data)) { $DB->delete_records_select('comments', "itemid IN ({$allrecordssql}) AND commentarea='database_entry'", array($data->courseid)); $DB->delete_records_select('data_content', "recordid IN ({$allrecordssql})", array($data->courseid)); $DB->delete_records_select('data_records', "dataid IN ({$alldatassql})", array($data->courseid)); if ($datas = $DB->get_records_sql($alldatassql, array($data->courseid))) { foreach ($datas as $dataid => $unused) { if (!($cm = get_coursemodule_from_instance('data', $dataid))) { continue; } $datacontext = context_module::instance($cm->id); // Delete any files that may exist. $fs->delete_area_files($datacontext->id, 'mod_data', 'content'); $ratingdeloptions->contextid = $datacontext->id; $rm->delete_ratings($ratingdeloptions); } } if (empty($data->reset_gradebook_grades)) { // remove all grades from gradebook data_reset_gradebook($data->courseid); } $status[] = array('component' => $componentstr, 'item' => get_string('deleteallentries', 'data'), 'error' => false); } // remove entries by users not enrolled into course if (!empty($data->reset_data_notenrolled)) { $recordssql = "SELECT r.id, r.userid, r.dataid, u.id AS userexists, u.deleted AS userdeleted\n FROM {data_records} r\n JOIN {data} d ON r.dataid = d.id\n LEFT JOIN {user} u ON r.userid = u.id\n WHERE d.course = ? AND r.userid > 0"; $course_context = context_course::instance($data->courseid); $notenrolled = array(); $fields = array(); $rs = $DB->get_recordset_sql($recordssql, array($data->courseid)); foreach ($rs as $record) { if (array_key_exists($record->userid, $notenrolled) or !$record->userexists or $record->userdeleted or !is_enrolled($course_context, $record->userid)) { //delete ratings if (!($cm = get_coursemodule_from_instance('data', $record->dataid))) { continue; } $datacontext = context_module::instance($cm->id); $ratingdeloptions->contextid = $datacontext->id; $ratingdeloptions->itemid = $record->id; $rm->delete_ratings($ratingdeloptions); // Delete any files that may exist. if ($contents = $DB->get_records('data_content', array('recordid' => $record->id), '', 'id')) { foreach ($contents as $content) { $fs->delete_area_files($datacontext->id, 'mod_data', 'content', $content->id); } } $notenrolled[$record->userid] = true; $DB->delete_records('comments', array('itemid' => $record->id, 'commentarea' => 'database_entry')); $DB->delete_records('data_content', array('recordid' => $record->id)); $DB->delete_records('data_records', array('id' => $record->id)); } } $rs->close(); $status[] = array('component' => $componentstr, 'item' => get_string('deletenotenrolled', 'data'), 'error' => false); } // remove all ratings if (!empty($data->reset_data_ratings)) { if ($datas = $DB->get_records_sql($alldatassql, array($data->courseid))) { foreach ($datas as $dataid => $unused) { if (!($cm = get_coursemodule_from_instance('data', $dataid))) { continue; } $datacontext = context_module::instance($cm->id); $ratingdeloptions->contextid = $datacontext->id; $rm->delete_ratings($ratingdeloptions); } } if (empty($data->reset_gradebook_grades)) { // remove all grades from gradebook data_reset_gradebook($data->courseid); } $status[] = array('component' => $componentstr, 'item' => get_string('deleteallratings'), 'error' => false); } // remove all comments if (!empty($data->reset_data_comments)) { $DB->delete_records_select('comments', "itemid IN ({$allrecordssql}) AND commentarea='database_entry'", array($data->courseid)); $status[] = array('component' => $componentstr, 'item' => get_string('deleteallcomments'), 'error' => false); } // updating dates - shift may be negative too if ($data->timeshift) { shift_course_mod_dates('data', array('timeavailablefrom', 'timeavailableto', 'timeviewfrom', 'timeviewto'), $data->timeshift, $data->courseid); $status[] = array('component' => $componentstr, 'item' => get_string('datechanged'), 'error' => false); } return $status; }
/** * Adds all the standard elements to a form to edit the settings for an activity module. */ function standard_coursemodule_elements() { global $COURSE, $CFG, $DB; $mform =& $this->_form; $this->_outcomesused = false; if ($this->_features->outcomes) { if ($outcomes = grade_outcome::fetch_all_available($COURSE->id)) { $this->_outcomesused = true; $mform->addElement('header', 'modoutcomes', get_string('outcomes', 'grades')); foreach ($outcomes as $outcome) { $mform->addElement('advcheckbox', 'outcome_' . $outcome->id, $outcome->get_name()); } } } if ($this->_features->rating) { require_once $CFG->dirroot . '/rating/lib.php'; $rm = new rating_manager(); $mform->addElement('header', 'modstandardratings', get_string('ratings', 'rating')); $permission = CAP_ALLOW; $rolenamestring = null; if (!empty($this->_cm)) { $context = context_module::instance($this->_cm->id); $rolenames = get_role_names_with_caps_in_context($context, array('moodle/rating:rate', 'mod/' . $this->_cm->modname . ':rate')); $rolenamestring = implode(', ', $rolenames); } else { $rolenamestring = get_string('capabilitychecknotavailable', 'rating'); } $mform->addElement('static', 'rolewarning', get_string('rolewarning', 'rating'), $rolenamestring); $mform->addHelpButton('rolewarning', 'rolewarning', 'rating'); $mform->addElement('select', 'assessed', get_string('aggregatetype', 'rating'), $rm->get_aggregate_types()); $mform->setDefault('assessed', 0); $mform->addHelpButton('assessed', 'aggregatetype', 'rating'); $mform->addElement('modgrade', 'scale', get_string('scale'), false); $mform->disabledIf('scale', 'assessed', 'eq', 0); $mform->addElement('checkbox', 'ratingtime', get_string('ratingtime', 'rating')); $mform->disabledIf('ratingtime', 'assessed', 'eq', 0); $mform->addElement('date_time_selector', 'assesstimestart', get_string('from')); $mform->disabledIf('assesstimestart', 'assessed', 'eq', 0); $mform->disabledIf('assesstimestart', 'ratingtime'); $mform->addElement('date_time_selector', 'assesstimefinish', get_string('to')); $mform->disabledIf('assesstimefinish', 'assessed', 'eq', 0); $mform->disabledIf('assesstimefinish', 'ratingtime'); } //doing this here means splitting up the grade related settings on the lesson settings page //$this->standard_grading_coursemodule_elements(); $mform->addElement('header', 'modstandardelshdr', get_string('modstandardels', 'form')); if ($this->_features->groups) { $options = array(NOGROUPS => get_string('groupsnone'), SEPARATEGROUPS => get_string('groupsseparate'), VISIBLEGROUPS => get_string('groupsvisible')); $mform->addElement('select', 'groupmode', get_string('groupmode', 'group'), $options, NOGROUPS); $mform->addHelpButton('groupmode', 'groupmode', 'group'); } if ($this->_features->groupings or $this->_features->groupmembersonly) { //groupings selector - used for normal grouping mode or also when restricting access with groupmembersonly $options = array(); $options[0] = get_string('none'); if ($groupings = $DB->get_records('groupings', array('courseid' => $COURSE->id))) { foreach ($groupings as $grouping) { $options[$grouping->id] = format_string($grouping->name); } } $mform->addElement('select', 'groupingid', get_string('grouping', 'group'), $options); $mform->addHelpButton('groupingid', 'grouping', 'group'); $mform->setAdvanced('groupingid'); } if ($this->_features->groupmembersonly) { $mform->addElement('checkbox', 'groupmembersonly', get_string('groupmembersonly', 'group')); $mform->addHelpButton('groupmembersonly', 'groupmembersonly', 'group'); $mform->setAdvanced('groupmembersonly'); } $mform->addElement('modvisible', 'visible', get_string('visible')); if (!empty($this->_cm)) { $context = context_module::instance($this->_cm->id); if (!has_capability('moodle/course:activityvisibility', $context)) { $mform->hardFreeze('visible'); } } if ($this->_features->idnumber) { $mform->addElement('text', 'cmidnumber', get_string('idnumbermod')); $mform->addHelpButton('cmidnumber', 'idnumbermod'); } if (!empty($CFG->enableavailability)) { // String used by conditions $strnone = get_string('none', 'condition'); // Conditional availability // Available from/to defaults to midnight because then the display // will be nicer where it tells users when they can access it (it // shows only the date and not time). $date = usergetdate(time()); $midnight = make_timestamp($date['year'], $date['mon'], $date['mday']); // From/until controls $mform->addElement('header', 'availabilityconditionsheader', get_string('availabilityconditions', 'condition')); $mform->addElement('date_time_selector', 'availablefrom', get_string('availablefrom', 'condition'), array('optional' => true, 'defaulttime' => $midnight)); $mform->addHelpButton('availablefrom', 'availablefrom', 'condition'); $mform->addElement('date_time_selector', 'availableuntil', get_string('availableuntil', 'condition'), array('optional' => true, 'defaulttime' => $midnight)); // Conditions based on grades $gradeoptions = array(); $items = grade_item::fetch_all(array('courseid' => $COURSE->id)); $items = $items ? $items : array(); foreach ($items as $id => $item) { // Do not include grades for current item if (!empty($this->_cm) && $this->_cm->instance == $item->iteminstance && $this->_cm->modname == $item->itemmodule && $item->itemtype == 'mod') { continue; } $gradeoptions[$id] = $item->get_name(); } asort($gradeoptions); $gradeoptions = array(0 => $strnone) + $gradeoptions; $grouparray = array(); $grouparray[] =& $mform->createElement('select', 'conditiongradeitemid', '', $gradeoptions); $grouparray[] =& $mform->createElement('static', '', '', ' ' . get_string('grade_atleast', 'condition') . ' '); $grouparray[] =& $mform->createElement('text', 'conditiongrademin', '', array('size' => 3)); $grouparray[] =& $mform->createElement('static', '', '', '% ' . get_string('grade_upto', 'condition') . ' '); $grouparray[] =& $mform->createElement('text', 'conditiongrademax', '', array('size' => 3)); $grouparray[] =& $mform->createElement('static', '', '', '%'); $group = $mform->createElement('group', 'conditiongradegroup', get_string('gradecondition', 'condition'), $grouparray); // Get version with condition info and store it so we don't ask // twice if (!empty($this->_cm)) { $ci = new condition_info($this->_cm, CONDITION_MISSING_EXTRATABLE); $this->_cm = $ci->get_full_course_module(); $count = count($this->_cm->conditionsgrade) + 1; $fieldcount = count($this->_cm->conditionsfield) + 1; } else { $count = 1; $fieldcount = 1; } $this->repeat_elements(array($group), $count, array(), 'conditiongraderepeats', 'conditiongradeadds', 2, get_string('addgrades', 'condition'), true); $mform->addHelpButton('conditiongradegroup[0]', 'gradecondition', 'condition'); // Conditions based on user fields $operators = condition_info::get_condition_user_field_operators(); $useroptions = condition_info::get_condition_user_fields(); asort($useroptions); $useroptions = array(0 => $strnone) + $useroptions; $grouparray = array(); $grouparray[] =& $mform->createElement('select', 'conditionfield', '', $useroptions); $grouparray[] =& $mform->createElement('select', 'conditionfieldoperator', '', $operators); $grouparray[] =& $mform->createElement('text', 'conditionfieldvalue'); $mform->setType('conditionfieldvalue', PARAM_RAW); $group = $mform->createElement('group', 'conditionfieldgroup', get_string('userfield', 'condition'), $grouparray); $this->repeat_elements(array($group), $fieldcount, array(), 'conditionfieldrepeats', 'conditionfieldadds', 2, get_string('adduserfields', 'condition'), true); $mform->addHelpButton('conditionfieldgroup[0]', 'userfield', 'condition'); // Conditions based on completion $completion = new completion_info($COURSE); if ($completion->is_enabled()) { $completionoptions = array(); $modinfo = get_fast_modinfo($COURSE); foreach ($modinfo->cms as $id => $cm) { // Add each course-module if it: // (a) has completion turned on // (b) is not the same as current course-module if ($cm->completion && (empty($this->_cm) || $this->_cm->id != $id)) { $completionoptions[$id] = $cm->name; } } asort($completionoptions); $completionoptions = array(0 => $strnone) + $completionoptions; $completionvalues = array(COMPLETION_COMPLETE => get_string('completion_complete', 'condition'), COMPLETION_INCOMPLETE => get_string('completion_incomplete', 'condition'), COMPLETION_COMPLETE_PASS => get_string('completion_pass', 'condition'), COMPLETION_COMPLETE_FAIL => get_string('completion_fail', 'condition')); $grouparray = array(); $grouparray[] =& $mform->createElement('select', 'conditionsourcecmid', '', $completionoptions); $grouparray[] =& $mform->createElement('select', 'conditionrequiredcompletion', '', $completionvalues); $group = $mform->createElement('group', 'conditioncompletiongroup', get_string('completioncondition', 'condition'), $grouparray); $count = empty($this->_cm) ? 1 : count($this->_cm->conditionscompletion) + 1; $this->repeat_elements(array($group), $count, array(), 'conditioncompletionrepeats', 'conditioncompletionadds', 2, get_string('addcompletions', 'condition'), true); $mform->addHelpButton('conditioncompletiongroup[0]', 'completioncondition', 'condition'); } // Do we display availability info to students? $mform->addElement('select', 'showavailability', get_string('showavailability', 'condition'), array(CONDITION_STUDENTVIEW_SHOW => get_string('showavailability_show', 'condition'), CONDITION_STUDENTVIEW_HIDE => get_string('showavailability_hide', 'condition'))); $mform->setDefault('showavailability', CONDITION_STUDENTVIEW_SHOW); } // Conditional activities: completion tracking section if (!isset($completion)) { $completion = new completion_info($COURSE); } if ($completion->is_enabled()) { $mform->addElement('header', 'activitycompletionheader', get_string('activitycompletion', 'completion')); // Unlock button for if people have completed it (will // be removed in definition_after_data if they haven't) $mform->addElement('submit', 'unlockcompletion', get_string('unlockcompletion', 'completion')); $mform->registerNoSubmitButton('unlockcompletion'); $mform->addElement('hidden', 'completionunlocked', 0); $mform->setType('completionunlocked', PARAM_INT); $mform->addElement('select', 'completion', get_string('completion', 'completion'), array(COMPLETION_TRACKING_NONE => get_string('completion_none', 'completion'), COMPLETION_TRACKING_MANUAL => get_string('completion_manual', 'completion'))); $mform->setDefault('completion', $this->_features->defaultcompletion ? COMPLETION_TRACKING_MANUAL : COMPLETION_TRACKING_NONE); $mform->addHelpButton('completion', 'completion', 'completion'); // Automatic completion once you view it $gotcompletionoptions = false; if (plugin_supports('mod', $this->_modname, FEATURE_COMPLETION_TRACKS_VIEWS, false)) { $mform->addElement('checkbox', 'completionview', get_string('completionview', 'completion'), get_string('completionview_desc', 'completion')); $mform->disabledIf('completionview', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC); $gotcompletionoptions = true; } // Automatic completion once it's graded if (plugin_supports('mod', $this->_modname, FEATURE_GRADE_HAS_GRADE, false)) { $mform->addElement('checkbox', 'completionusegrade', get_string('completionusegrade', 'completion'), get_string('completionusegrade_desc', 'completion')); $mform->disabledIf('completionusegrade', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC); $mform->addHelpButton('completionusegrade', 'completionusegrade', 'completion'); $gotcompletionoptions = true; } // Automatic completion according to module-specific rules $this->_customcompletionelements = $this->add_completion_rules(); foreach ($this->_customcompletionelements as $element) { $mform->disabledIf($element, 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC); } $gotcompletionoptions = $gotcompletionoptions || count($this->_customcompletionelements) > 0; // Automatic option only appears if possible if ($gotcompletionoptions) { $mform->getElement('completion')->addOption(get_string('completion_automatic', 'completion'), COMPLETION_TRACKING_AUTOMATIC); } // Completion expected at particular date? (For progress tracking) $mform->addElement('date_selector', 'completionexpected', get_string('completionexpected', 'completion'), array('optional' => true)); $mform->addHelpButton('completionexpected', 'completionexpected', 'completion'); $mform->disabledIf('completionexpected', 'completion', 'eq', COMPLETION_TRACKING_NONE); } $this->standard_hidden_coursemodule_elements(); }
/** * Remove a context record and any dependent entries, * removes context from static context cache too * * @param int $level * @param int $instanceid * @param bool $deleterecord false means keep record for now * @return bool returns true or throws an exception */ function delete_context($contextlevel, $instanceid, $deleterecord = true) { global $DB, $ACCESSLIB_PRIVATE, $CFG; // do not use get_context_instance(), because the related object might not exist, // or the context does not exist yet and it would be created now if ($context = $DB->get_record('context', array('contextlevel' => $contextlevel, 'instanceid' => $instanceid))) { // delete these first because they might fetch the context and try to recreate it! blocks_delete_all_for_context($context->id); filter_delete_all_for_context($context->id); require_once $CFG->dirroot . '/comment/lib.php'; comment::delete_comments(array('contextid' => $context->id)); require_once $CFG->dirroot . '/rating/lib.php'; $delopt = new stdclass(); $delopt->contextid = $context->id; $rm = new rating_manager(); $rm->delete_ratings($delopt); // delete all files attached to this context $fs = get_file_storage(); $fs->delete_area_files($context->id); // now delete stuff from role related tables, role_unassign_all // and unenrol should be called earlier to do proper cleanup $DB->delete_records('role_assignments', array('contextid' => $context->id)); $DB->delete_records('role_capabilities', array('contextid' => $context->id)); $DB->delete_records('role_names', array('contextid' => $context->id)); // and finally it is time to delete the context record if requested if ($deleterecord) { $DB->delete_records('context', array('id' => $context->id)); // purge static context cache if entry present $ACCESSLIB_PRIVATE->contexcache->remove($context); } // do not mark dirty contexts if parents unknown if (!is_null($context->path) and $context->depth > 0) { mark_context_dirty($context->path); } } return true; }
public function test_course_check_module_updates_since() { global $CFG, $DB, $USER; require_once $CFG->dirroot . '/mod/glossary/lib.php'; require_once $CFG->dirroot . '/rating/lib.php'; require_once $CFG->dirroot . '/comment/lib.php'; $this->resetAfterTest(true); $CFG->enablecompletion = true; $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); $glossary = $this->getDataGenerator()->create_module('glossary', array('course' => $course->id, 'completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1, 'allowcomments' => 1, 'assessed' => RATING_AGGREGATE_AVERAGE, 'scale' => 100)); $glossarygenerator = $this->getDataGenerator()->get_plugin_generator('mod_glossary'); $context = context_module::instance($glossary->cmid); $modinfo = get_fast_modinfo($course); $cm = $modinfo->get_cm($glossary->cmid); $user = $this->getDataGenerator()->create_user(); $studentrole = $DB->get_record('role', array('shortname' => 'student')); $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id); $from = time(); $teacher = $this->getDataGenerator()->create_user(); $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); assign_capability('mod/glossary:viewanyrating', CAP_ALLOW, $studentrole->id, $context->id, true); // Check nothing changed right now. $updates = course_check_module_updates_since($cm, $from); $this->assertFalse($updates->configuration->updated); $this->assertFalse($updates->completion->updated); $this->assertFalse($updates->gradeitems->updated); $this->assertFalse($updates->comments->updated); $this->assertFalse($updates->ratings->updated); $this->assertFalse($updates->introfiles->updated); $this->assertFalse($updates->outcomes->updated); $this->waitForSecond(); // Do some changes. $this->setUser($user); $entry = $glossarygenerator->create_content($glossary); $this->setUser($teacher); // Name. set_coursemodule_name($glossary->cmid, 'New name'); // Add some ratings. $rm = new rating_manager(); $result = $rm->add_rating($cm, $context, 'mod_glossary', 'entry', $entry->id, 100, 50, $user->id, RATING_AGGREGATE_AVERAGE); // Change grades. $glossary->cmidnumber = $glossary->cmid; glossary_update_grades($glossary, $user->id); $this->setUser($user); // Completion status. glossary_view($glossary, $course, $cm, $context, 'letter'); // Add one comment. $args = new stdClass(); $args->context = $context; $args->course = $course; $args->cm = $cm; $args->area = 'glossary_entry'; $args->itemid = $entry->id; $args->client_id = 1; $args->component = 'mod_glossary'; $manager = new comment($args); $manager->add('blah blah blah'); // Check upgrade status. $updates = course_check_module_updates_since($cm, $from); $this->assertTrue($updates->configuration->updated); $this->assertTrue($updates->completion->updated); $this->assertTrue($updates->gradeitems->updated); $this->assertTrue($updates->comments->updated); $this->assertTrue($updates->ratings->updated); $this->assertFalse($updates->introfiles->updated); $this->assertFalse($updates->outcomes->updated); }
/** * This function display the hub homepage * It is called early when loading any Moodle page. * @return integer return true if Moodle index.php home page must continue normal display */ public function display_homepage() { global $PAGE, $SITE, $OUTPUT, $CFG, $USER; //check if the front page search should not be displayed //=> hand over the home page to Moodle index.php //Two cases possible: //1- the hub is private and the users are not logged in //2- the hub is set with no search form on the login page $hubprivacy = get_config('local_hub', 'privacy'); $searchfornologin = get_config('local_hub', 'searchfornologin'); if (($hubprivacy == HUBPRIVATE or $searchfornologin === '0') and !isloggedin()) { return true; } require_once $CFG->dirroot . "/local/hub/forms.php"; $PAGE->set_url('/'); $PAGE->set_pagetype('site-index'); $PAGE->set_docs_path(''); $PAGE->set_pagelayout('frontpage'); $PAGE->set_title($SITE->fullname); $PAGE->set_heading($SITE->fullname); //little trick to require login in order to rate or comment $mustbelogged = optional_param('mustbelogged', false, PARAM_BOOL); if ($mustbelogged) { require_login(); } //log redirection to a course page $redirectcourseid = optional_param('redirectcourseid', false, PARAM_INT); if (!empty($redirectcourseid)) { //do not check sesskey because can be call by RSS feed $course = $this->get_course($redirectcourseid); if (!empty($course->courseurl)) { $courseurl = new moodle_url($course->courseurl); } else { if (!empty($course->demourl)) { $courseurl = new moodle_url($course->demourl); } else { //we try to display a demo site but none has been set echo $OUTPUT->header(); echo get_string('nodemo', 'local_hub'); echo $OUTPUT->footer(); die; } } $rss = optional_param('rss', false, PARAM_BOOL); $rss = empty($rss) ? '' : 'rss'; add_to_log(SITEID, 'local_hub', 'course redirection ' . $rss, '', $redirectcourseid); redirect(new moodle_url($courseurl)); } $search = optional_param('search', null, PARAM_TEXT); $renderer = $PAGE->get_renderer('local_hub'); //forms //Warning: because we want to support GET and we want people to be able to give the url, // we need to bypass the sesskey form checking $_GET['sesskey'] = sesskey(); $fromformdata['coverage'] = optional_param('coverage', 'all', PARAM_TEXT); $fromformdata['licence'] = optional_param('licence', 'all', PARAM_ALPHANUMEXT); $fromformdata['subject'] = optional_param('subject', 'all', PARAM_ALPHANUMEXT); $fromformdata['siteid'] = optional_param('siteid', 'all', PARAM_ALPHANUMEXT); $fromformdata['lastmodified'] = optional_param('lastmodified', HUB_LASTMODIFIED_WEEK, PARAM_ALPHANUMEXT); $fromformdata['audience'] = optional_param('audience', 'all', PARAM_ALPHANUMEXT); $currentlanguage = explode('_', current_language()); $fromformdata['language'] = optional_param('language', $currentlanguage[0], PARAM_ALPHANUMEXT); $fromformdata['educationallevel'] = optional_param('educationallevel', 'all', PARAM_ALPHANUMEXT); $fromformdata['downloadable'] = optional_param('downloadable', 1, PARAM_ALPHANUM); $fromformdata['orderby'] = optional_param('orderby', 'newest', PARAM_ALPHA); $fromformdata['search'] = $search; $coursesearchform = new course_search_form('', $fromformdata, 'get'); $fromform = $coursesearchform->get_data(); $coursesearchform->set_data($fromformdata); $fromform = (object) $fromformdata; //Retrieve courses by web service $options = array(); //special shortcut if a course id is given in param, we search straight forward this id if ($courseid = optional_param('courseid', 0, PARAM_INTEGER)) { $options['onlyvisible'] = true; $options['ids'] = array($courseid); $options['downloadable'] = true; $options['enrollable'] = true; $courses = $this->get_courses($options); $coursetotal = 1; //Add the name of the course to the page title //(useful because some sites as Facebook is going to read it to build a shared link name) foreach ($courses as $course) { $PAGE->set_title($course->fullname . ' - ' . $SITE->fullname); } } else { if (!empty($fromform) and optional_param('submitbutton', 0, PARAM_ALPHANUMEXT)) { $downloadable = optional_param('downloadable', false, PARAM_INTEGER); if (!empty($fromform->coverage)) { $options['coverage'] = $fromform->coverage; } if ($fromform->licence != 'all') { $options['licenceshortname'] = $fromform->licence; } if ($fromform->subject != 'all') { $options['subject'] = $fromform->subject; } if ($fromform->audience != 'all') { $options['audience'] = $fromform->audience; } if ($fromform->educationallevel != 'all') { $options['educationallevel'] = $fromform->educationallevel; } if ($fromform->language != 'all') { $options['language'] = $fromform->language; } //sort method switch ($fromform->orderby) { case 'newest': $options['orderby'] = 'timemodified DESC'; break; case 'eldest': $options['orderby'] = 'timemodified ASC'; break; case 'publisher': $options['orderby'] = 'publishername ASC'; break; case 'fullname': $options['orderby'] = 'fullname ASC'; break; case 'ratingaverage': $options['orderby'] = 'ratingaverage DESC'; break; default: break; } //get courses $options['search'] = $search; $options['onlyvisible'] = true; $options['downloadable'] = $downloadable; $options['enrollable'] = !$downloadable; $page = optional_param('page', 0, PARAM_INT); $courses = $this->get_courses($options, $page * HUB_COURSE_PER_PAGE, HUB_COURSE_PER_PAGE); $coursetotal = $this->get_courses($options, 0, 0, true); //reset the options $options['orderby'] = $fromform->orderby; unset($options['onlyvisible']); } } if (!empty($courses)) { //load javascript $courseids = array(); //all result courses $courseimagenumbers = array(); //number of screenshots of all courses (must be exact same order than $courseids) foreach ($courses as $course) { $courseids[] = $course->id; $courseimagenumbers[] = $course->screenshots; } $PAGE->requires->yui_module('moodle-block_community-imagegallery', 'M.blocks_community.init_imagegallery', array(array('imageids' => $courseids, 'imagenumbers' => $courseimagenumbers, 'huburl' => $CFG->wwwroot))); //get courses content foreach ($courses as $course) { $contents = $this->get_course_contents($course->id); if (!empty($contents)) { foreach ($contents as $content) { $course->contents[] = $content; } } } //load ratings and comments require_once $CFG->dirroot . '/rating/lib.php'; $ratingoptions = new stdclass(); $ratingoptions->context = context_course::instance(SITEID); //front page course $ratingoptions->items = $courses; $ratingoptions->aggregate = RATING_AGGREGATE_COUNT; //the aggregation method $ratingoptions->scaleid = 0 - get_config('local_hub', 'courseratingscaleid'); //rating API is expecting "minus scaleid" $ratingoptions->userid = $USER->id; $ratingoptions->returnurl = $CFG->wwwroot . "/local/hub/index.php"; $ratingoptions->component = 'local_hub'; $ratingoptions->ratingarea = 'featured'; $rm = new rating_manager(); $courses = $rm->get_ratings($ratingoptions); //this function return $ratingoptions->items with information about the ratings foreach ($courses as $course) { $course->rating->settings->permissions->viewany = 1; } require_once $CFG->dirroot . '/comment/lib.php'; foreach ($courses as $course) { $commentoptions = new stdClass(); $commentoptions->context = context_course::instance(SITEID); $commentoptions->area = 'local_hub'; $commentoptions->itemid = $course->id; $commentoptions->showcount = true; $commentoptions->component = 'local_hub'; $course->comment = new comment($commentoptions); $course->comment->set_view_permission(true); } } //create rss feed link $enablerssfeeds = get_config('local_hub', 'enablerssfeeds'); if (!empty($enablerssfeeds)) { require $CFG->libdir . '/rsslib.php'; $audience = key_exists('audience', $options) ? $options['audience'] : 'all'; $educationallevel = key_exists('educationallevel', $options) ? $options['educationallevel'] : 'all'; if (key_exists('downloadable', $options)) { $downloadable = empty($options['downloadable']) ? 0 : 1; } else { $downloadable = 'all'; } $subject = key_exists('subject', $options) ? $options['subject'] : 'all'; $licence = key_exists('licence', $options) ? $options['licence'] : 'all'; $language = key_exists('language', $options) ? $options['language'] : 'all'; $audience = key_exists('audience', $options) ? $options['audience'] : 'all'; $orderby = key_exists('orderby', $options) ? $options['orderby'] : 'newest'; $search = empty($search) ? 0 : urlencode($search); //retrieve guest user if user not logged in $userid = empty($USER->id) ? $CFG->siteguest : $USER->id; $ctx = context_course::instance(SITEID); //add the link tage to the header $rsslink = rss_get_url($ctx->id, $userid, 'local_hub', $downloadable . '/' . $audience . '/' . $educationallevel . '/' . $subject . '/' . $licence . '/' . $language . '/' . $search . '/'); $PAGE->add_alternate_version('RSS', $rsslink, 'application/rss+xml'); //create the rss icon $rssicon = rss_get_link($ctx->id, $userid, 'local_hub', $downloadable . '/' . $audience . '/' . $educationallevel . '/' . $subject . '/' . $licence . '/' . $language . '/' . $search . '/' . $orderby . '/', get_string('rsstooltip', 'local_hub')); } /// OUTPUT echo $OUTPUT->header(); //notification message sent to publisher if (optional_param('messagesent', 0, PARAM_INTEGER)) { echo $OUTPUT->notification(get_string('messagesentsuccess', 'local_hub'), 'notifysuccess'); } //search form $coursesearchform->display(); //Course listing $options['submitbutton'] = 1; //need to set up the submitbutton to 1 for the paging bar (simulate search) //and paramlink //set language value back to 'all' if (!key_exists('language', $options)) { $options['language'] = 'all'; } if (isset($courses) and empty($courseid)) { if (empty($coursetotal)) { $coursetotalhtml = get_string('nocourse', 'local_hub'); } else { $coursetotalhtml = get_string('coursetotal', 'local_hub', $coursetotal); } echo html_writer::tag('div', $coursetotalhtml, array('class' => 'hubcoursetotal')); } if (!empty($courses)) { //paging bar if ($coursetotal > HUB_COURSE_PER_PAGE) { $baseurl = new moodle_url('', $options); $pagingbarhtml = $OUTPUT->paging_bar($coursetotal, $page, HUB_COURSE_PER_PAGE, $baseurl); $pagingbarhtml = html_writer::tag('div', $pagingbarhtml, array('class' => 'pagingbar')); echo $pagingbarhtml; } echo highlight($search, $renderer->course_list($courses)); if (!empty($pagingbarhtml)) { echo $pagingbarhtml; } } //rss icon if (!empty($enablerssfeeds)) { echo html_writer::tag('div', $rssicon, array('class' => 'hubrsslink')); } //permalink if (!empty($courses)) { $permalinkparams = array(); //special case: course list is a unique course for a given ID if (!empty($courseid)) { $permalinkparams['courseid'] = $courseid; } else { $permalinkparams = $options; } $permalink = html_writer::tag('div', html_writer::tag('a', get_string('permalink', 'local_hub'), array('href' => new moodle_url('', $permalinkparams))), array('class' => 'hubcoursepermalink')); echo $permalink; } echo $OUTPUT->footer(); }
/** * Displays the ratingsfor a specific episode * @global stdClass $CFG * @global stdClass $USER * @global stdClass $DB * @global stdClass $OUTPUT * @param object $episode * @param object $cm * @param object $course */ function pcast_display_episode_ratings($episode, $cm, $course) { global $CFG, $USER, $DB, $OUTPUT; $sql = pcast_get_episode_sql(); $sql .= " WHERE p.id = ?"; $episodes = $DB->get_records_sql($sql, array('id' => $episode->id)); $context = get_context_instance(CONTEXT_MODULE, $cm->id); // load ratings require_once $CFG->dirroot . '/rating/lib.php'; if ($episode->assessed != RATING_AGGREGATE_NONE) { $ratingoptions = new stdClass(); // $ratingoptions->plugintype = 'mod'; // $ratingoptions->pluginname = 'pcast'; $ratingoptions->component = 'mod_pcast'; $ratingoptions->context = $context; $ratingoptions->items = $episodes; $ratingoptions->aggregate = $episode->assessed; //the aggregation method $ratingoptions->scaleid = $episode->scale; $ratingoptions->userid = $USER->id; $ratingoptions->returnurl = new moodle_url('/mod/pcast/showepisode.php', array('eid' => $episode->id, 'mode' => PCAST_EPISODE_COMMENT_AND_RATE)); $ratingoptions->assesstimestart = $episode->assesstimestart; $ratingoptions->assesstimefinish = $episode->assesstimefinish; $ratingoptions->ratingarea = 'episode'; $rm = new rating_manager(); $allepisodes = $rm->get_ratings($ratingoptions); } foreach ($allepisodes as $thisepisode) { if (!empty($thisepisode->rating)) { echo html_writer::tag('div', $OUTPUT->render($thisepisode->rating), array('class' => 'pcast-episode-rating')); } } }
/** * Test the current get_ratings method main sql */ function test_get_ratings_sql() { // We load 3 items. Each is rated twice. For simplicity itemid == user id of the item owner $ctxid = SYSCONTEXTID; $this->load_test_data('rating', array('contextid', 'component', 'ratingarea', 'itemid', 'scaleid', 'rating', 'userid', 'timecreated', 'timemodified'), array( //user 1's items. Average == 2 array( $ctxid , 'mod_forum', 'post', 1 , 10 , 1 , 2 , 1 , 1), array( $ctxid , 'mod_forum', 'post', 1 , 10 , 3 , 3 , 1 , 1), //user 2's items. Average == 3 array( $ctxid , 'mod_forum', 'post', 2 , 10 , 1 , 1 , 1 , 1), array( $ctxid , 'mod_forum', 'post', 2 , 10 , 5 , 3 , 1 , 1), //user 3's items. Average == 4 array( $ctxid , 'mod_forum', 'post', 3 , 10 , 3 , 1 , 1 , 1), array( $ctxid , 'mod_forum', 'post', 3 , 10 , 5 , 2 , 1 , 1) )); // a post (item) by user 1 (rated above by user 2 and 3 with average = 2) $user1posts = array( (object)array('id' => 1, 'userid' => 1, 'message' => 'hello')); // a post (item) by user 2 (rated above by user 1 and 3 with average = 3) $user2posts = array( (object)array('id' => 2, 'userid' => 2, 'message' => 'world')); // a post (item) by user 3 (rated above by user 1 and 2 with average = 4) $user3posts = array( (object)array('id' => 3, 'userid' => 3, 'message' => 'moodle')); // Prepare the default options $defaultoptions = array ( 'context' => get_context_instance(CONTEXT_SYSTEM), 'component' => 'mod_forum', 'ratingarea' => 'post', 'scaleid' => 10, 'aggregate' => RATING_AGGREGATE_AVERAGE); $rm = new rating_manager(); // STEP 1: Retreive ratings using the current user // Get results for user 1's item (expected average 1 + 3 / 2 = 2) $toptions = (object)array_merge($defaultoptions, array('items' => $user1posts)); $result = $rm->get_ratings($toptions); $this->assertEqual(count($result), count($user1posts)); $this->assertEqual($result[0]->id, $user1posts[0]->id); $this->assertEqual($result[0]->userid, $user1posts[0]->userid); $this->assertEqual($result[0]->message, $user1posts[0]->message); $this->assertEqual($result[0]->rating->count, 2); $this->assertEqual($result[0]->rating->aggregate, 2); // Note that $result[0]->rating->rating is somewhat random // We didn't supply a user ID so $USER was used which will vary depending on who runs the tests // Get results for items of user 2 (expected average 1 + 5 / 2 = 3) $toptions = (object)array_merge($defaultoptions, array('items' => $user2posts)); $result = $rm->get_ratings($toptions); $this->assertEqual(count($result), count($user2posts)); $this->assertEqual($result[0]->id, $user2posts[0]->id); $this->assertEqual($result[0]->userid, $user2posts[0]->userid); $this->assertEqual($result[0]->message, $user2posts[0]->message); $this->assertEqual($result[0]->rating->count, 2); $this->assertEqual($result[0]->rating->aggregate, 3); // Note that $result[0]->rating->rating is somewhat random // We didn't supply a user ID so $USER was used which will vary depending on who runs the tests // Get results for items of user 3 (expected average 3 + 5 / 2 = 4) $toptions = (object)array_merge($defaultoptions, array('items' => $user3posts)); $result = $rm->get_ratings($toptions); $this->assertEqual(count($result), count($user3posts)); $this->assertEqual($result[0]->id, $user3posts[0]->id); $this->assertEqual($result[0]->userid, $user3posts[0]->userid); $this->assertEqual($result[0]->message, $user3posts[0]->message); $this->assertEqual($result[0]->rating->count, 2); $this->assertEqual($result[0]->rating->aggregate, 4); // Note that $result[0]->rating->rating is somewhat random // We didn't supply a user ID so $USER was used which will vary depending on who runs the tests // Get results for items of user 1 & 2 together (expected averages are 2 and 3, as tested above) $posts = array_merge($user1posts, $user2posts); $toptions = (object)array_merge($defaultoptions, array('items' => $posts)); $result = $rm->get_ratings($toptions); $this->assertEqual(count($result), count($posts)); $this->assertEqual($result[0]->id, $posts[0]->id); $this->assertEqual($result[0]->userid, $posts[0]->userid); $this->assertEqual($result[0]->message, $posts[0]->message); $this->assertEqual($result[0]->rating->count, 2); $this->assertEqual($result[0]->rating->aggregate, 2); // Note that $result[0]->rating->rating is somewhat random // We didn't supply a user ID so $USER was used which will vary depending on who runs the tests $this->assertEqual($result[1]->id, $posts[1]->id); $this->assertEqual($result[1]->userid, $posts[1]->userid); $this->assertEqual($result[1]->message, $posts[1]->message); $this->assertEqual($result[1]->rating->count, 2); $this->assertEqual($result[1]->rating->aggregate, 3); // Note that $result[0]->rating->rating is somewhat random // We didn't supply a user ID so $USER was used which will vary depending on who runs the tests // STEP 2: Retrieve ratings by a specified user // We still expect complete aggregations and counts // Get results for items of user 1 rated by user 2 (avg 2, rating 1) $toptions = (object)array_merge($defaultoptions, array('items' => $user1posts, 'userid' => 2)); $result = $rm->get_ratings($toptions); $this->assertEqual(count($result), count($user1posts)); $this->assertEqual($result[0]->id, $user1posts[0]->id); $this->assertEqual($result[0]->userid, $user1posts[0]->userid); $this->assertEqual($result[0]->message, $user1posts[0]->message); $this->assertEqual($result[0]->rating->count, 2); $this->assertEqual($result[0]->rating->aggregate, 2); $this->assertEqual($result[0]->rating->rating, 1); //user 2 rated user 1 "1" $this->assertEqual($result[0]->rating->userid, $toptions->userid); // Must be the passed userid // Get results for items of user 1 rated by user 3 $toptions = (object)array_merge($defaultoptions, array('items' => $user1posts, 'userid' => 3)); $result = $rm->get_ratings($toptions); $this->assertEqual(count($result), count($user1posts)); $this->assertEqual($result[0]->id, $user1posts[0]->id); $this->assertEqual($result[0]->userid, $user1posts[0]->userid); $this->assertEqual($result[0]->message, $user1posts[0]->message); $this->assertEqual($result[0]->rating->count, 2); $this->assertEqual($result[0]->rating->aggregate, 2); $this->assertEqual($result[0]->rating->rating, 3); //user 3 rated user 1 "3" $this->assertEqual($result[0]->rating->userid, $toptions->userid); // Must be the passed userid // Get results for items of user 1 & 2 together rated by user 3 $posts = array_merge($user1posts, $user2posts); $toptions = (object)array_merge($defaultoptions, array('items' => $posts, 'userid' => 3)); $result = $rm->get_ratings($toptions); $this->assertEqual(count($result), count($posts)); $this->assertEqual($result[0]->id, $posts[0]->id); $this->assertEqual($result[0]->userid, $posts[0]->userid); $this->assertEqual($result[0]->message, $posts[0]->message); $this->assertEqual($result[0]->rating->count, 2); $this->assertEqual($result[0]->rating->aggregate, 2); $this->assertEqual($result[0]->rating->rating, 3); //user 3 rated user 1 "3" $this->assertEqual($result[0]->rating->userid, $toptions->userid); // Must be the passed userid $this->assertEqual($result[1]->id, $posts[1]->id); $this->assertEqual($result[1]->userid, $posts[1]->userid); $this->assertEqual($result[1]->message, $posts[1]->message); $this->assertEqual($result[1]->rating->count, 2); $this->assertEqual($result[1]->rating->aggregate, 3); $this->assertEqual($result[0]->rating->rating, 3); //user 3 rated user 2 "5" $this->assertEqual($result[1]->rating->userid, $toptions->userid); // Must be the passed userid // STEP 3: Some special cases // Get results for user 1's items (expected average 1 + 3 / 2 = 2) // supplying a non-existent user id so no rating from that user should be found $toptions = (object)array_merge($defaultoptions, array('items' => $user1posts)); $toptions->userid = 123456; //non-existent user $result = $rm->get_ratings($toptions); $this->assertNull($result[0]->rating->userid); $this->assertNull($result[0]->rating->rating); $this->assertEqual($result[0]->rating->aggregate, 2);//should still get the aggregate // Get results for items of user 2 (expected average 1 + 5 / 2 = 3) // Supplying the user id of the user who owns the items so no rating should be found $toptions = (object)array_merge($defaultoptions, array('items' => $user2posts)); $toptions->userid = 2; //user 2 viewing the ratings of their own item $result = $rm->get_ratings($toptions); //these should be null as the user is viewing their own item and thus cannot rate $this->assertNull($result[0]->rating->userid); $this->assertNull($result[0]->rating->rating); $this->assertEqual($result[0]->rating->aggregate, 3);//should still get the aggregate }
/** * Returns all posts in this forum by the given user within the given group. * @param object $forum * @param int $userid * @param int $groupid * @param int $ratedstart * @param int $ratedend * @param string $order Sort order; the default is fp.id - note this is preferable * to fp.timecreated because it works correctly if there are two posts in * the same second * @param bool $hasrating if true only returns posts which ahve been rated * @return array Array of mod_forumng_post objects */ public function get_rated_posts_by_user($forum, $userid, $groupid, $order = 'fp.id', $ratedstart = null, $ratedend = null, $start = null, $end = null) { global $CFG, $USER; if ($forum->get_enableratings() != mod_forumng::FORUMNG_STANDARD_RATING) { return array(); } $where = 'fd.forumngid = ? AND fp.userid <> ? AND fp.oldversion = 0 AND fp.deleted = 0'; $whereparams = array($this->get_id(), $userid); if ($groupid != self::NO_GROUPS && $groupid != self::ALL_GROUPS) { $where .= ' AND (fd.groupid = ? OR fd.groupid IS NULL)'; $whereparams[] = $groupid; } if (!empty($start)) { $where .= ' AND fp.created >= ?'; $whereparams[] = $start; } if (!empty($end)) { $where .= ' AND fp.created <= ?'; $whereparams[] = $end; } $sqlselectstring = 'SELECT r.itemid FROM {rating} r WHERE r.itemid = fp.id AND r.ratingarea = \'post\' AND r.contextid = ? AND r.userid = ?'; $extraparams = array(); if (!empty($ratedstart)) { $sqlselectstring .= ' AND r.timemodified >= ?'; $extraparams[] = $ratedstart; } if (!empty($ratedend)) { $sqlselectstring .= ' AND r.timemodified <= ?'; $extraparams[] = $ratedend; } $where .= ' AND ' . self::select_exists($sqlselectstring); $whereparams[] = $this->get_context(true)->id; $whereparams[] = $userid; $whereparams = array_merge($whereparams, $extraparams); $result = array(); $posts = mod_forumng_post::query_posts($where, $whereparams, $order, false, false, true, 0, true, true); // Add standard ratings if enabled. if ($this->get_enableratings() == mod_forumng::FORUMNG_STANDARD_RATING) { require_once $CFG->dirroot . '/rating/lib.php'; // If grading is 'No grading' or 'Teacher grades students'. if ($this->get_grading() == mod_forumng::GRADING_NONE || $this->get_grading() == mod_forumng::GRADING_MANUAL) { // Set the aggregation method. if ($this->get_rating_scale() > 0) { $aggregate = RATING_AGGREGATE_AVERAGE; } else { $aggregate = RATING_AGGREGATE_COUNT; } } else { $aggregate = $this->get_grading(); } $ratingoptions = new stdClass(); $ratingoptions->context = $this->get_context(true); $ratingoptions->component = 'mod_forumng'; $ratingoptions->ratingarea = 'post'; $ratingoptions->items = $posts; $ratingoptions->aggregate = $aggregate; $ratingoptions->scaleid = $this->get_rating_scale(); $ratingoptions->userid = $USER->id; $ratingoptions->assesstimestart = $this->get_ratingfrom(); $ratingoptions->assesstimefinish = $this->get_ratinguntil(); $rm = new rating_manager(); $posts = $rm->get_ratings($ratingoptions); } foreach ($posts as $fields) { $discussionfields = mod_forumng_utils::extract_subobject($fields, 'fd_'); $discussion = new mod_forumng_discussion($this, $discussionfields, false, -1); $result[$fields->id] = new mod_forumng_post($discussion, $fields); } return $result; }
if (!$individualparams) { $words = $search; } forum_print_big_search_form($course); echo $OUTPUT->footer(); exit; } //including this here to prevent it being included if there are no search results require_once $CFG->dirroot . '/rating/lib.php'; //set up the ratings information that will be the same for all posts $ratingoptions = new stdClass(); $ratingoptions->component = 'mod_forum'; $ratingoptions->ratingarea = 'post'; $ratingoptions->userid = $USER->id; $ratingoptions->returnurl = $PAGE->url->out(false); $rm = new rating_manager(); $PAGE->set_title($strsearchresults); $PAGE->set_heading($course->fullname); $PAGE->set_button($searchform); echo $OUTPUT->header(); echo '<div class="reportlink">'; echo '<a href="search.php?id=' . $course->id . '&user='******'&userid=' . $userid . '&forumid=' . $forumid . '&subject=' . urlencode($subject) . '&phrase=' . urlencode($phrase) . '&words=' . urlencode($words) . '&fullwords=' . urlencode($fullwords) . '&notwords=' . urlencode($notwords) . '&dateto=' . $dateto . '&datefrom=' . $datefrom . '&showform=1' . '">' . get_string('advancedsearch', 'forum') . '...</a>'; echo '</div>'; echo $OUTPUT->heading("{$strsearchresults}: {$totalcount}"); $url = new moodle_url('search.php', array('search' => $search, 'id' => $course->id, 'perpage' => $perpage)); echo $OUTPUT->paging_bar($totalcount, $page, $perpage, $url); //added to implement highlighting of search terms found only in HTML markup //fiedorow - 9/2/2005 $strippedsearch = str_replace('user:'******'', $search); $strippedsearch = str_replace('subject:', '', $strippedsearch); $strippedsearch = str_replace('"', '', $strippedsearch);
/** * Update this rating in the database * * @param int $rating the integer value of this rating */ public function update_rating($rating) { global $DB; $time = time(); $data = new stdClass(); $data->rating = $rating; $data->timemodified = $time; $item = new stdclass(); $item->id = $this->itemid; $items = array($item); $ratingoptions = new stdClass(); $ratingoptions->context = $this->context; $ratingoptions->component = $this->component; $ratingoptions->ratingarea = $this->ratingarea; $ratingoptions->items = $items; $ratingoptions->aggregate = RATING_AGGREGATE_AVERAGE; // We dont actually care what aggregation method is applied. $ratingoptions->scaleid = $this->scaleid; $ratingoptions->userid = $this->userid; $rm = new rating_manager(); $items = $rm->get_ratings($ratingoptions); $firstitem = $items[0]->rating; if (empty($firstitem->id)) { // Insert a new rating. $data->contextid = $this->context->id; $data->component = $this->component; $data->ratingarea = $this->ratingarea; $data->rating = $rating; $data->scaleid = $this->scaleid; $data->userid = $this->userid; $data->itemid = $this->itemid; $data->timecreated = $time; $data->timemodified = $time; $DB->insert_record('rating', $data); } else { // Update the rating. $data->id = $firstitem->id; $DB->update_record('rating', $data); } }
} echo $OUTPUT->footer(); die; } // Post output will contain an entry containing HTML to display each post by the // time we are done. $postoutput = array(); $discussions = array(); foreach ($result->posts as $post) { $discussions[] = $post->discussion; } $discussions = $DB->get_records_list('forum_discussions', 'id', array_unique($discussions)); //todo Rather than retrieving the ratings for each post individually it would be nice to do them in groups //however this requires creating arrays of posts with each array containing all of the posts from a particular forum, //retrieving the ratings then reassembling them all back into a single array sorted by post.modified (descending) $rm = new rating_manager(); $ratingoptions = new stdClass(); $ratingoptions->component = 'mod_forum'; $ratingoptions->ratingarea = 'post'; foreach ($result->posts as $post) { if (!isset($result->forums[$post->forum]) || !isset($discussions[$post->discussion])) { // Something very VERY dodgy has happened if we end up here continue; } $forum = $result->forums[$post->forum]; $cm = $forum->cm; $discussion = $discussions[$post->discussion]; $course = $result->courses[$discussion->course]; $forumurl = new moodle_url('/mod/forum/view.php', array('id' => $cm->id)); $discussionurl = new moodle_url('/mod/forum/discuss.php', array('d' => $post->discussion)); // load ratings
$DB->delete_records("comments", array('itemid' => $entry->id, 'commentarea' => 'glossary_entry', 'contextid' => $context->id)); $DB->delete_records("glossary_alias", array("entryid" => $entry->id)); $DB->delete_records("glossary_entries", array("id" => $entry->id)); // Update completion state $completion = new completion_info($course); if ($completion->is_enabled($cm) == COMPLETION_TRACKING_AUTOMATIC && $glossary->completionentries) { $completion->update_state($cm, COMPLETION_INCOMPLETE, $entry->userid); } //delete glossary entry ratings require_once $CFG->dirroot . '/rating/lib.php'; $delopt = new stdClass(); $delopt->contextid = $context->id; $delopt->component = 'mod_glossary'; $delopt->ratingarea = 'entry'; $delopt->itemid = $entry->id; $rm = new rating_manager(); $rm->delete_ratings($delopt); } add_to_log($course->id, "glossary", "delete entry", "view.php?id={$cm->id}&mode={$prevmode}&hook={$hook}", $entry->id, $cm->id); redirect("view.php?id={$cm->id}&mode={$prevmode}&hook={$hook}"); } else { // the operation has not been confirmed yet so ask the user to do so $PAGE->navbar->add(get_string('delete')); $PAGE->set_title(format_string($glossary->name)); $PAGE->set_heading($course->fullname); echo $OUTPUT->header(); $areyousure = "<b>" . format_string($entry->concept) . "</b><p>{$strareyousuredelete}</p>"; $linkyes = 'deleteentry.php'; $linkno = 'view.php'; $optionsyes = array('id' => $cm->id, 'entry' => $entry->id, 'confirm' => 1, 'sesskey' => sesskey(), 'prevmode' => $prevmode, 'hook' => $hook); $optionsno = array('id' => $cm->id, 'mode' => $prevmode, 'hook' => $hook);
/** * Update this rating in the database * @param int $rating the integer value of this rating * @return void */ public function update_rating($rating) { global $DB; $data = new stdclass(); $table = 'rating'; $item = new stdclass(); $item->id = $this->itemid; $items = array($item); $ratingoptions = new stdclass(); $ratingoptions->context = $this->context; $ratingoptions->items = $items; $ratingoptions->aggregate = RATING_AGGREGATE_AVERAGE;//we dont actually care what aggregation method is applied $ratingoptions->scaleid = $this->scaleid; $ratingoptions->userid = $this->userid; $rm = new rating_manager(); $items = $rm->get_ratings($ratingoptions); if( empty($items) || empty($items[0]->rating) || empty($items[0]->rating->id) ) { $data->contextid = $this->context->id; $data->rating = $rating; $data->scaleid = $this->scaleid; $data->userid = $this->userid; $data->itemid = $this->itemid; $time = time(); $data->timecreated = $time; $data->timemodified = $time; $DB->insert_record($table, $data); } else { $data->id = $items[0]->rating->id; $data->rating = $rating; $time = time(); $data->timemodified = $time; $DB->update_record($table, $data); } }
/** * Obtains the root post of the discussion. This actually requests all * posts from the database; the first is returned, but others are * accessible from methods in the first. * If available, cached information is used unless * you set $usecache to false. The cache is stored within the discussion * object so will not persist beyond a request unless you make the * discussion object persist too. * @param bool $usecache True to use cache if available, false to * request fresh data * @param int $userid User ID to get user-specific data (initially, post * flags) for; 0 = current * @return mod_forumng_post Post object */ public function get_root_post($usecache = true, $userid = 0) { global $CFG, $USER; require_once $CFG->dirroot . '/rating/lib.php'; if (!$usecache || !$this->rootpost) { if (!$usecache || !$this->postscache) { $read = !mod_forumng::mark_read_automatically($userid); // Retrieve most posts in the discussion - even deleted // ones. These are necessary in case somebody deletes a post that has // replies. They will display as 'deleted post'. We don't retrieve // old versions of edited posts. Posts are retrieved in created order // so that the order of replies remains constant when we build the tree. $posts = mod_forumng_post::query_posts('fp.discussionid=? AND fp.oldversion=0', array($this->discussionfields->id), 'fp.created', $this->forum->has_ratings(), true, false, $userid, false, false, '', '', $read); // Load standard ratings. if ($this->get_forum()->get_enableratings() == mod_forumng::FORUMNG_STANDARD_RATING) { // If grading is 'No grading' or 'Teacher grades students'. if ($this->get_forum()->get_grading() == mod_forumng::GRADING_NONE || $this->get_forum()->get_grading() == mod_forumng::GRADING_MANUAL) { // Set the aggregation method. if ($this->get_forum()->get_rating_scale() > 0) { $aggregate = RATING_AGGREGATE_AVERAGE; } else { $aggregate = RATING_AGGREGATE_COUNT; } } else { $aggregate = $this->get_forum()->get_grading(); } $ratingoptions = new stdClass(); $ratingoptions->context = $this->get_forum()->get_context(); $ratingoptions->component = 'mod_forumng'; $ratingoptions->ratingarea = 'post'; $ratingoptions->items = $posts; $ratingoptions->aggregate = $aggregate; $ratingoptions->scaleid = $this->get_forum()->get_rating_scale(); $ratingoptions->userid = $USER->id; $ratingoptions->assesstimestart = $this->forum->get_ratingfrom(); $ratingoptions->assesstimefinish = $this->forum->get_ratinguntil(); $ratingoptions->returnurl = $this->get_moodle_url(); $rm = new rating_manager(); $posts = $rm->get_ratings($ratingoptions); } $this->postscache = serialize($posts); } else { $posts = unserialize($this->postscache); } // Add numbers to posts $i = 1; foreach ($posts as $post) { $post->number = $i++; } // Obtain post relationships $children = array(); foreach ($posts as $id => $fields) { if (!array_key_exists($fields->parentpostid, $children)) { $children[$fields->parentpostid] = array(); } $children[$fields->parentpostid][] = $id; } // Recursively build posts $this->rootpost = $this->build_posts($posts, $children, $this->discussionfields->postid, null); // Update the 'next/previous' unread lists stored in posts if ($this->get_unread_data_user_id() != -1) { $linear = array(); $this->rootpost->build_linear_children($linear); $nextunread = array(); $dump = ''; foreach ($linear as $index => $post) { $nextunread[$index] = null; if ($post->is_unread() && (!$post->get_deleted() || $post->can_undelete($dump))) { for ($j = $index - 1; $j >= 0; $j--) { if ($nextunread[$j]) { break; } $nextunread[$j] = $post; } } } $previous = null; foreach ($linear as $index => $post) { $post->set_unread_list($nextunread[$index], $previous); if ($post->is_unread() && (!$post->get_deleted() || $post->can_undelete($dump))) { $previous = $post; } } // Update cached version to include this data if ($this->incache) { $this->cache(); } } } return $this->rootpost; }
$strrating = get_string('rating', 'rating'); $strname = get_string('name'); $strtime = get_string('time'); $PAGE->set_title(get_string('allratingsforitem','rating')); echo $OUTPUT->header(); $ratingoptions = new stdClass; $ratingoptions->context = $context; $ratingoptions->component = $component; $ratingoptions->ratingarea = $ratingarea; $ratingoptions->itemid = $itemid; $ratingoptions->sort = $sqlsort; $rm = new rating_manager(); $ratings = $rm->get_all_ratings_for_item($ratingoptions); if (!$ratings) { $msg = get_string('noratings','rating'); echo html_writer::tag('div', $msg, array('class'=>'mdl-align')); } else { $sorturl = new moodle_url('/index.php', array('contextid' => $contextid, 'itemid' => $itemid, 'scaleid' => $scaleid)); if ($popup) { $sorturl->param('popup', $popup); } $table = new html_table; $table->cellpadding = 3; $table->cellspacing = 3; $table->attributes['class'] = 'generalbox ratingtable'; $table->head = array(
/** * Returns a list of ratings for a particular post - sorted. * * @param stdClass $context * @param int $postid * @param string $sort * @return array Array of ratings or false * @deprecated since Moodle 2.0 MDL-21657 - please do not use this function any more. */ function quora_get_ratings($context, $postid, $sort = "u.firstname ASC") { debugging('quora_get_ratings() is deprecated.', DEBUG_DEVELOPER); $options = new stdClass(); $options->context = $context; $options->component = 'mod_quora'; $options->ratingarea = 'post'; $options->itemid = $postid; $options->sort = "ORDER BY {$sort}"; $rm = new rating_manager(); return $rm->get_all_ratings_for_item($options); }
/** * Adds all the standard elements to a form to edit the settings for an activity module. */ function standard_coursemodule_elements() { global $COURSE, $CFG, $DB; $mform =& $this->_form; $this->_outcomesused = false; if ($this->_features->outcomes) { if ($outcomes = grade_outcome::fetch_all_available($COURSE->id)) { $this->_outcomesused = true; $mform->addElement('header', 'modoutcomes', get_string('outcomes', 'grades')); foreach ($outcomes as $outcome) { $mform->addElement('advcheckbox', 'outcome_' . $outcome->id, $outcome->get_name()); } } } if ($this->_features->rating) { require_once $CFG->dirroot . '/rating/lib.php'; $rm = new rating_manager(); $mform->addElement('header', 'modstandardratings', get_string('ratings', 'rating')); $permission = CAP_ALLOW; $rolenamestring = null; if (!empty($this->_cm)) { $context = context_module::instance($this->_cm->id); $rolenames = get_role_names_with_caps_in_context($context, array('moodle/rating:rate', 'mod/' . $this->_cm->modname . ':rate')); $rolenamestring = implode(', ', $rolenames); } else { $rolenamestring = get_string('capabilitychecknotavailable', 'rating'); } $mform->addElement('static', 'rolewarning', get_string('rolewarning', 'rating'), $rolenamestring); $mform->addHelpButton('rolewarning', 'rolewarning', 'rating'); $mform->addElement('select', 'assessed', get_string('aggregatetype', 'rating'), $rm->get_aggregate_types()); $mform->setDefault('assessed', 0); $mform->addHelpButton('assessed', 'aggregatetype', 'rating'); $mform->addElement('modgrade', 'scale', get_string('scale'), false); $mform->disabledIf('scale', 'assessed', 'eq', 0); $mform->addHelpButton('scale', 'modgrade', 'grades'); $mform->setDefault('scale', $CFG->gradepointdefault); $mform->addElement('checkbox', 'ratingtime', get_string('ratingtime', 'rating')); $mform->disabledIf('ratingtime', 'assessed', 'eq', 0); $mform->addElement('date_time_selector', 'assesstimestart', get_string('from')); $mform->disabledIf('assesstimestart', 'assessed', 'eq', 0); $mform->disabledIf('assesstimestart', 'ratingtime'); $mform->addElement('date_time_selector', 'assesstimefinish', get_string('to')); $mform->disabledIf('assesstimefinish', 'assessed', 'eq', 0); $mform->disabledIf('assesstimefinish', 'ratingtime'); } //doing this here means splitting up the grade related settings on the lesson settings page //$this->standard_grading_coursemodule_elements(); $mform->addElement('header', 'modstandardelshdr', get_string('modstandardels', 'form')); $mform->addElement('modvisible', 'visible', get_string('visible')); if (!empty($this->_cm)) { $context = context_module::instance($this->_cm->id); if (!has_capability('moodle/course:activityvisibility', $context)) { $mform->hardFreeze('visible'); } } if ($this->_features->idnumber) { $mform->addElement('text', 'cmidnumber', get_string('idnumbermod')); $mform->setType('cmidnumber', PARAM_RAW); $mform->addHelpButton('cmidnumber', 'idnumbermod'); } if ($this->_features->groups) { $options = array(NOGROUPS => get_string('groupsnone'), SEPARATEGROUPS => get_string('groupsseparate'), VISIBLEGROUPS => get_string('groupsvisible')); $mform->addElement('select', 'groupmode', get_string('groupmode', 'group'), $options, NOGROUPS); $mform->addHelpButton('groupmode', 'groupmode', 'group'); } if ($this->_features->groupings) { // Groupings selector - used to select grouping for groups in activity. $options = array(); if ($groupings = $DB->get_records('groupings', array('courseid' => $COURSE->id))) { foreach ($groupings as $grouping) { $options[$grouping->id] = format_string($grouping->name); } } core_collator::asort($options); $options = array(0 => get_string('none')) + $options; $mform->addElement('select', 'groupingid', get_string('grouping', 'group'), $options); $mform->addHelpButton('groupingid', 'grouping', 'group'); } if (!empty($CFG->enableavailability)) { // Add special button to end of previous section if groups/groupings // are enabled. if ($this->_features->groups || $this->_features->groupings) { $mform->addElement('static', 'restrictgroupbutton', '', html_writer::tag('button', get_string('restrictbygroup', 'availability'), array('id' => 'restrictbygroup', 'disabled' => 'disabled'))); } // Availability field. This is just a textarea; the user interface // interaction is all implemented in JavaScript. $mform->addElement('header', 'availabilityconditionsheader', get_string('restrictaccess', 'availability')); // Note: This field cannot be named 'availability' because that // conflicts with fields in existing modules (such as assign). // So it uses a long name that will not conflict. $mform->addElement('textarea', 'availabilityconditionsjson', get_string('accessrestrictions', 'availability')); // The _cm variable may not be a proper cm_info, so get one from modinfo. if ($this->_cm) { $modinfo = get_fast_modinfo($COURSE); $cm = $modinfo->get_cm($this->_cm->id); } else { $cm = null; } \core_availability\frontend::include_all_javascript($COURSE, $cm); } // Conditional activities: completion tracking section if (!isset($completion)) { $completion = new completion_info($COURSE); } if ($completion->is_enabled()) { $mform->addElement('header', 'activitycompletionheader', get_string('activitycompletion', 'completion')); // Unlock button for if people have completed it (will // be removed in definition_after_data if they haven't) $mform->addElement('submit', 'unlockcompletion', get_string('unlockcompletion', 'completion')); $mform->registerNoSubmitButton('unlockcompletion'); $mform->addElement('hidden', 'completionunlocked', 0); $mform->setType('completionunlocked', PARAM_INT); $trackingdefault = COMPLETION_TRACKING_NONE; // If system and activity default is on, set it. if ($CFG->completiondefault && $this->_features->defaultcompletion) { $trackingdefault = COMPLETION_TRACKING_MANUAL; } $mform->addElement('select', 'completion', get_string('completion', 'completion'), array(COMPLETION_TRACKING_NONE => get_string('completion_none', 'completion'), COMPLETION_TRACKING_MANUAL => get_string('completion_manual', 'completion'))); $mform->setDefault('completion', $trackingdefault); $mform->addHelpButton('completion', 'completion', 'completion'); // Automatic completion once you view it $gotcompletionoptions = false; if (plugin_supports('mod', $this->_modname, FEATURE_COMPLETION_TRACKS_VIEWS, false)) { $mform->addElement('checkbox', 'completionview', get_string('completionview', 'completion'), get_string('completionview_desc', 'completion')); $mform->disabledIf('completionview', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC); $gotcompletionoptions = true; } // Automatic completion once it's graded if (plugin_supports('mod', $this->_modname, FEATURE_GRADE_HAS_GRADE, false)) { $mform->addElement('checkbox', 'completionusegrade', get_string('completionusegrade', 'completion'), get_string('completionusegrade_desc', 'completion')); $mform->disabledIf('completionusegrade', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC); $mform->addHelpButton('completionusegrade', 'completionusegrade', 'completion'); $gotcompletionoptions = true; // If using the rating system, there is no grade unless ratings are enabled. if ($this->_features->rating) { $mform->disabledIf('completionusegrade', 'assessed', 'eq', 0); } } // Automatic completion according to module-specific rules $this->_customcompletionelements = $this->add_completion_rules(); foreach ($this->_customcompletionelements as $element) { $mform->disabledIf($element, 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC); } $gotcompletionoptions = $gotcompletionoptions || count($this->_customcompletionelements) > 0; // Automatic option only appears if possible if ($gotcompletionoptions) { $mform->getElement('completion')->addOption(get_string('completion_automatic', 'completion'), COMPLETION_TRACKING_AUTOMATIC); } // Completion expected at particular date? (For progress tracking) $mform->addElement('date_selector', 'completionexpected', get_string('completionexpected', 'completion'), array('optional' => true)); $mform->addHelpButton('completionexpected', 'completionexpected', 'completion'); $mform->disabledIf('completionexpected', 'completion', 'eq', COMPLETION_TRACKING_NONE); } $this->standard_hidden_coursemodule_elements(); }
/** * Clear a course out completely, deleting all content * but don't delete the course itself. * This function does not verify any permissions. * * Please note this function also deletes all user enrolments, * enrolment instances and role assignments by default. * * $options: * - 'keep_roles_and_enrolments' - false by default * - 'keep_groups_and_groupings' - false by default * * @param int $courseid The id of the course that is being deleted * @param bool $showfeedback Whether to display notifications of each action the function performs. * @param array $options extra options * @return bool true if all the removals succeeded. false if there were any failures. If this * method returns false, some of the removals will probably have succeeded, and others * failed, but you have no way of knowing which. */ function remove_course_contents($courseid, $showfeedback = true, array $options = null) { global $CFG, $DB, $OUTPUT; require_once $CFG->libdir . '/completionlib.php'; require_once $CFG->libdir . '/questionlib.php'; require_once $CFG->libdir . '/gradelib.php'; require_once $CFG->dirroot . '/group/lib.php'; require_once $CFG->dirroot . '/tag/coursetagslib.php'; require_once $CFG->dirroot . '/comment/lib.php'; require_once $CFG->dirroot . '/rating/lib.php'; // NOTE: these concatenated strings are suboptimal, but it is just extra info... $strdeleted = get_string('deleted') . ' - '; // Some crazy wishlist of stuff we should skip during purging of course content $options = (array) $options; $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST); $coursecontext = context_course::instance($courseid); $fs = get_file_storage(); // Delete course completion information, this has to be done before grades and enrols $cc = new completion_info($course); $cc->clear_criteria(); if ($showfeedback) { echo $OUTPUT->notification($strdeleted . get_string('completion', 'completion'), 'notifysuccess'); } // Remove all data from gradebook - this needs to be done before course modules // because while deleting this information, the system may need to reference // the course modules that own the grades. remove_course_grades($courseid, $showfeedback); remove_grade_letters($coursecontext, $showfeedback); // Delete course blocks in any all child contexts, // they may depend on modules so delete them first $childcontexts = $coursecontext->get_child_contexts(); // returns all subcontexts since 2.2 foreach ($childcontexts as $childcontext) { blocks_delete_all_for_context($childcontext->id); } unset($childcontexts); blocks_delete_all_for_context($coursecontext->id); if ($showfeedback) { echo $OUTPUT->notification($strdeleted . get_string('type_block_plural', 'plugin'), 'notifysuccess'); } // Delete every instance of every module, // this has to be done before deleting of course level stuff $locations = get_plugin_list('mod'); foreach ($locations as $modname => $moddir) { if ($modname === 'NEWMODULE') { continue; } if ($module = $DB->get_record('modules', array('name' => $modname))) { include_once "{$moddir}/lib.php"; // Shows php warning only if plugin defective $moddelete = $modname . '_delete_instance'; // Delete everything connected to an instance $moddeletecourse = $modname . '_delete_course'; // Delete other stray stuff (uncommon) if ($instances = $DB->get_records($modname, array('course' => $course->id))) { foreach ($instances as $instance) { if ($cm = get_coursemodule_from_instance($modname, $instance->id, $course->id)) { /// Delete activity context questions and question categories question_delete_activity($cm, $showfeedback); } if (function_exists($moddelete)) { // This purges all module data in related tables, extra user prefs, settings, etc. $moddelete($instance->id); } else { // NOTE: we should not allow installation of modules with missing delete support! debugging("Defective module '{$modname}' detected when deleting course contents: missing function {$moddelete}()!"); $DB->delete_records($modname, array('id' => $instance->id)); } if ($cm) { // Delete cm and its context - orphaned contexts are purged in cron in case of any race condition context_helper::delete_instance(CONTEXT_MODULE, $cm->id); $DB->delete_records('course_modules', array('id' => $cm->id)); } } } if (function_exists($moddeletecourse)) { // Execute ptional course cleanup callback $moddeletecourse($course, $showfeedback); } if ($instances and $showfeedback) { echo $OUTPUT->notification($strdeleted . get_string('pluginname', $modname), 'notifysuccess'); } } else { // Ooops, this module is not properly installed, force-delete it in the next block } } // We have tried to delete everything the nice way - now let's force-delete any remaining module data // Remove all data from availability and completion tables that is associated // with course-modules belonging to this course. Note this is done even if the // features are not enabled now, in case they were enabled previously. $DB->delete_records_select('course_modules_completion', 'coursemoduleid IN (SELECT id from {course_modules} WHERE course=?)', array($courseid)); $DB->delete_records_select('course_modules_availability', 'coursemoduleid IN (SELECT id from {course_modules} WHERE course=?)', array($courseid)); // Remove course-module data. $cms = $DB->get_records('course_modules', array('course' => $course->id)); foreach ($cms as $cm) { if ($module = $DB->get_record('modules', array('id' => $cm->module))) { try { $DB->delete_records($module->name, array('id' => $cm->instance)); } catch (Exception $e) { // Ignore weird or missing table problems } } context_helper::delete_instance(CONTEXT_MODULE, $cm->id); $DB->delete_records('course_modules', array('id' => $cm->id)); } if ($showfeedback) { echo $OUTPUT->notification($strdeleted . get_string('type_mod_plural', 'plugin'), 'notifysuccess'); } // Cleanup the rest of plugins $cleanuplugintypes = array('report', 'coursereport', 'format'); foreach ($cleanuplugintypes as $type) { $plugins = get_plugin_list_with_function($type, 'delete_course', 'lib.php'); foreach ($plugins as $plugin => $pluginfunction) { $pluginfunction($course->id, $showfeedback); } if ($showfeedback) { echo $OUTPUT->notification($strdeleted . get_string('type_' . $type . '_plural', 'plugin'), 'notifysuccess'); } } // Delete questions and question categories question_delete_course($course, $showfeedback); if ($showfeedback) { echo $OUTPUT->notification($strdeleted . get_string('questions', 'question'), 'notifysuccess'); } // Make sure there are no subcontexts left - all valid blocks and modules should be already gone $childcontexts = $coursecontext->get_child_contexts(); // returns all subcontexts since 2.2 foreach ($childcontexts as $childcontext) { $childcontext->delete(); } unset($childcontexts); // Remove all roles and enrolments by default if (empty($options['keep_roles_and_enrolments'])) { // this hack is used in restore when deleting contents of existing course role_unassign_all(array('contextid' => $coursecontext->id, 'component' => ''), true); enrol_course_delete($course); if ($showfeedback) { echo $OUTPUT->notification($strdeleted . get_string('type_enrol_plural', 'plugin'), 'notifysuccess'); } } // Delete any groups, removing members and grouping/course links first. if (empty($options['keep_groups_and_groupings'])) { groups_delete_groupings($course->id, $showfeedback); groups_delete_groups($course->id, $showfeedback); } // filters be gone! filter_delete_all_for_context($coursecontext->id); // die comments! comment::delete_comments($coursecontext->id); // ratings are history too $delopt = new stdclass(); $delopt->contextid = $coursecontext->id; $rm = new rating_manager(); $rm->delete_ratings($delopt); // Delete course tags coursetag_delete_course_tags($course->id, $showfeedback); // Delete calendar events $DB->delete_records('event', array('courseid' => $course->id)); $fs->delete_area_files($coursecontext->id, 'calendar'); // Delete all related records in other core tables that may have a courseid // This array stores the tables that need to be cleared, as // table_name => column_name that contains the course id. $tablestoclear = array('log' => 'course', 'backup_courses' => 'courseid', 'user_lastaccess' => 'courseid'); foreach ($tablestoclear as $table => $col) { $DB->delete_records($table, array($col => $course->id)); } // delete all course backup files $fs->delete_area_files($coursecontext->id, 'backup'); // cleanup course record - remove links to deleted stuff $oldcourse = new stdClass(); $oldcourse->id = $course->id; $oldcourse->summary = ''; $oldcourse->modinfo = NULL; $oldcourse->legacyfiles = 0; $oldcourse->enablecompletion = 0; if (!empty($options['keep_groups_and_groupings'])) { $oldcourse->defaultgroupingid = 0; } $DB->update_record('course', $oldcourse); // Delete course sections and availability options. $DB->delete_records_select('course_sections_availability', 'coursesectionid IN (SELECT id from {course_sections} WHERE course=?)', array($course->id)); $DB->delete_records('course_sections', array('course' => $course->id)); // delete legacy, section and any other course files $fs->delete_area_files($coursecontext->id, 'course'); // files from summary and section // Delete all remaining stuff linked to context such as files, comments, ratings, etc. if (empty($options['keep_roles_and_enrolments']) and empty($options['keep_groups_and_groupings'])) { // Easy, do not delete the context itself... $coursecontext->delete_content(); } else { // Hack alert!!!! // We can not drop all context stuff because it would bork enrolments and roles, // there might be also files used by enrol plugins... } // Delete legacy files - just in case some files are still left there after conversion to new file api, // also some non-standard unsupported plugins may try to store something there fulldelete($CFG->dataroot . '/' . $course->id); // Finally trigger the event $course->context = $coursecontext; // you can not access context in cron event later after course is deleted $course->options = $options; // not empty if we used any crazy hack events_trigger('course_content_removed', $course); return true; }
/** * Actual implementation of the reset course functionality, delete all the * data responses for course $data->courseid. * * @global object * @global object * @param object $data the data submitted from the reset course. * @return array status array */ function data_reset_userdata($data) { global $CFG, $DB; require_once($CFG->libdir.'/filelib.php'); require_once($CFG->dirroot.'/rating/lib.php'); $componentstr = get_string('modulenameplural', 'data'); $status = array(); $allrecordssql = "SELECT r.id FROM {data_records} r INNER JOIN {data} d ON r.dataid = d.id WHERE d.course = ?"; $alldatassql = "SELECT d.id FROM {data} d WHERE d.course=?"; $rm = new rating_manager(); $ratingdeloptions = new stdClass; $ratingdeloptions->component = 'mod_data'; $ratingdeloptions->ratingarea = 'entry'; // delete entries if requested if (!empty($data->reset_data)) { $DB->delete_records_select('comments', "itemid IN ($allrecordssql) AND commentarea='database_entry'", array($data->courseid)); $DB->delete_records_select('data_content', "recordid IN ($allrecordssql)", array($data->courseid)); $DB->delete_records_select('data_records', "dataid IN ($alldatassql)", array($data->courseid)); if ($datas = $DB->get_records_sql($alldatassql, array($data->courseid))) { foreach ($datas as $dataid=>$unused) { fulldelete("$CFG->dataroot/$data->courseid/moddata/data/$dataid"); if (!$cm = get_coursemodule_from_instance('data', $dataid)) { continue; } $datacontext = get_context_instance(CONTEXT_MODULE, $cm->id); $ratingdeloptions->contextid = $datacontext->id; $rm->delete_ratings($ratingdeloptions); } } if (empty($data->reset_gradebook_grades)) { // remove all grades from gradebook data_reset_gradebook($data->courseid); } $status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallentries', 'data'), 'error'=>false); } // remove entries by users not enrolled into course if (!empty($data->reset_data_notenrolled)) { $recordssql = "SELECT r.id, r.userid, r.dataid, u.id AS userexists, u.deleted AS userdeleted FROM {data_records} r JOIN {data} d ON r.dataid = d.id LEFT JOIN {user} u ON r.userid = u.id WHERE d.course = ? AND r.userid > 0"; $course_context = get_context_instance(CONTEXT_COURSE, $data->courseid); $notenrolled = array(); $fields = array(); $rs = $DB->get_recordset_sql($recordssql, array($data->courseid)); foreach ($rs as $record) { if (array_key_exists($record->userid, $notenrolled) or !$record->userexists or $record->userdeleted or !is_enrolled($course_context, $record->userid)) { //delete ratings if (!$cm = get_coursemodule_from_instance('data', $record->dataid)) { continue; } $datacontext = get_context_instance(CONTEXT_MODULE, $cm->id); $ratingdeloptions->contextid = $datacontext->id; $ratingdeloptions->itemid = $record->id; $rm->delete_ratings($ratingdeloptions); $DB->delete_records('comments', array('itemid'=>$record->id, 'commentarea'=>'database_entry')); $DB->delete_records('data_content', array('recordid'=>$record->id)); $DB->delete_records('data_records', array('id'=>$record->id)); // HACK: this is ugly - the recordid should be before the fieldid! if (!array_key_exists($record->dataid, $fields)) { if ($fs = $DB->get_records('data_fields', array('dataid'=>$record->dataid))) { $fields[$record->dataid] = array_keys($fs); } else { $fields[$record->dataid] = array(); } } foreach($fields[$record->dataid] as $fieldid) { fulldelete("$CFG->dataroot/$data->courseid/moddata/data/$record->dataid/$fieldid/$record->id"); } $notenrolled[$record->userid] = true; } } $rs->close(); $status[] = array('component'=>$componentstr, 'item'=>get_string('deletenotenrolled', 'data'), 'error'=>false); } // remove all ratings if (!empty($data->reset_data_ratings)) { if ($datas = $DB->get_records_sql($alldatassql, array($data->courseid))) { foreach ($datas as $dataid=>$unused) { if (!$cm = get_coursemodule_from_instance('data', $dataid)) { continue; } $datacontext = get_context_instance(CONTEXT_MODULE, $cm->id); $ratingdeloptions->contextid = $datacontext->id; $rm->delete_ratings($ratingdeloptions); } } if (empty($data->reset_gradebook_grades)) { // remove all grades from gradebook data_reset_gradebook($data->courseid); } $status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallratings'), 'error'=>false); } // remove all comments if (!empty($data->reset_data_comments)) { $DB->delete_records_select('comments', "itemid IN ($allrecordssql) AND commentarea='database_entry'", array($data->courseid)); $status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallcomments'), 'error'=>false); } // updating dates - shift may be negative too if ($data->timeshift) { shift_course_mod_dates('data', array('timeavailablefrom', 'timeavailableto', 'timeviewfrom', 'timeviewto'), $data->timeshift, $data->courseid); $status[] = array('component'=>$componentstr, 'item'=>get_string('datechanged'), 'error'=>false); } return $status; }
/** * Actual implementation of the reset course functionality, delete all the * glossary responses for course $data->courseid. * * @global object * @param $data the data submitted from the reset course. * @return array status array */ function glossary_reset_userdata($data) { global $CFG, $DB; require_once($CFG->dirroot.'/rating/lib.php'); $componentstr = get_string('modulenameplural', 'glossary'); $status = array(); $allentriessql = "SELECT e.id FROM {glossary_entries} e JOIN {glossary} g ON e.glossaryid = g.id WHERE g.course = ?"; $allglossariessql = "SELECT g.id FROM {glossary} g WHERE g.course = ?"; $params = array($data->courseid); $fs = get_file_storage(); $rm = new rating_manager(); $ratingdeloptions = new stdClass; $ratingdeloptions->component = 'mod_glossary'; $ratingdeloptions->ratingarea = 'entry'; // delete entries if requested if (!empty($data->reset_glossary_all) or (!empty($data->reset_glossary_types) and in_array('main', $data->reset_glossary_types) and in_array('secondary', $data->reset_glossary_types))) { $params[] = 'glossary_entry'; $DB->delete_records_select('comments', "itemid IN ($allentriessql) AND commentarea=?", $params); $DB->delete_records_select('glossary_alias', "entryid IN ($allentriessql)", $params); $DB->delete_records_select('glossary_entries', "glossaryid IN ($allglossariessql)", $params); // now get rid of all attachments if ($glossaries = $DB->get_records_sql($allglossariessql, $params)) { foreach ($glossaries as $glossaryid=>$unused) { if (!$cm = get_coursemodule_from_instance('glossary', $glossaryid)) { continue; } $context = get_context_instance(CONTEXT_MODULE, $cm->id); $fs->delete_area_files($context->id, 'mod_glossary', 'attachment'); //delete ratings $ratingdeloptions->contextid = $context->id; $rm->delete_ratings($ratingdeloptions); } } // remove all grades from gradebook if (empty($data->reset_gradebook_grades)) { glossary_reset_gradebook($data->courseid); } $status[] = array('component'=>$componentstr, 'item'=>get_string('resetglossariesall', 'glossary'), 'error'=>false); } else if (!empty($data->reset_glossary_types)) { $mainentriessql = "$allentries AND g.mainglossary=1"; $secondaryentriessql = "$allentries AND g.mainglossary=0"; $mainglossariessql = "$allglossariessql AND g.mainglossary=1"; $secondaryglossariessql = "$allglossariessql AND g.mainglossary=0"; if (in_array('main', $data->reset_glossary_types)) { $params[] = 'glossary_entry'; $DB->delete_records_select('comments', "itemid IN ($mainentriessql) AND commentarea=?", $params); $DB->delete_records_select('glossary_entries', "glossaryid IN ($mainglossariessql)", $params); if ($glossaries = $DB->get_records_sql($mainglossariessql, $params)) { foreach ($glossaries as $glossaryid=>$unused) { if (!$cm = get_coursemodule_from_instance('glossary', $glossaryid)) { continue; } $context = get_context_instance(CONTEXT_MODULE, $cm->id); $fs->delete_area_files($context->id, 'mod_glossary', 'attachment'); //delete ratings $ratingdeloptions->contextid = $context->id; $rm->delete_ratings($ratingdeloptions); } } // remove all grades from gradebook if (empty($data->reset_gradebook_grades)) { glossary_reset_gradebook($data->courseid, 'main'); } $status[] = array('component'=>$componentstr, 'item'=>get_string('resetglossaries', 'glossary'), 'error'=>false); } else if (in_array('secondary', $data->reset_glossary_types)) { $params[] = 'glossary_entry'; $DB->delete_records_select('comments', "itemid IN ($secondaryentriessql) AND commentarea=?", $params); $DB->delete_records_select('glossary_entries', "glossaryid IN ($secondaryglossariessql)", $params); // remove exported source flag from entries in main glossary $DB->execute("UPDATE {glossary_entries SET sourceglossaryid=0 WHERE glossaryid IN ($mainglossariessql)", $params); if ($glossaries = $DB->get_records_sql($secondaryglossariessql, $params)) { foreach ($glossaries as $glossaryid=>$unused) { if (!$cm = get_coursemodule_from_instance('glossary', $glossaryid)) { continue; } $context = get_context_instance(CONTEXT_MODULE, $cm->id); $fs->delete_area_files($context->id, 'mod_glossary', 'attachment'); //delete ratings $ratingdeloptions->contextid = $context->id; $rm->delete_ratings($ratingdeloptions); } } // remove all grades from gradebook if (empty($data->reset_gradebook_grades)) { glossary_reset_gradebook($data->courseid, 'secondary'); } $status[] = array('component'=>$componentstr, 'item'=>get_string('resetglossaries', 'glossary').': '.get_string('secondaryglossary', 'glossary'), 'error'=>false); } } // remove entries by users not enrolled into course if (!empty($data->reset_glossary_notenrolled)) { $entriessql = "SELECT e.id, e.userid, e.glossaryid, u.id AS userexists, u.deleted AS userdeleted FROM {glossary_entries} e JOIN {glossary} g ON e.glossaryid = g.id LEFT JOIN {user} u ON e.userid = u.id WHERE g.course = ? AND e.userid > 0"; $course_context = get_context_instance(CONTEXT_COURSE, $data->courseid); $notenrolled = array(); $rs = $DB->get_recordset_sql($entriessql, $params); if ($rs->valid()) { foreach ($rs as $entry) { if (array_key_exists($entry->userid, $notenrolled) or !$entry->userexists or $entry->userdeleted or !is_enrolled($course_context , $entry->userid)) { $DB->delete_records('comments', array('commentarea'=>'glossary_entry', 'itemid'=>$entry->id)); $DB->delete_records('glossary_entries', array('id'=>$entry->id)); if ($cm = get_coursemodule_from_instance('glossary', $entry->glossaryid)) { $context = get_context_instance(CONTEXT_MODULE, $cm->id); $fs->delete_area_files($context->id, 'mod_glossary', 'attachment', $entry->id); //delete ratings $ratingdeloptions->contextid = $context->id; $rm->delete_ratings($ratingdeloptions); } } } $status[] = array('component'=>$componentstr, 'item'=>get_string('deletenotenrolled', 'glossary'), 'error'=>false); } $rs->close(); } // remove all ratings if (!empty($data->reset_glossary_ratings)) { //remove ratings if ($glossaries = $DB->get_records_sql($allglossariessql, $params)) { foreach ($glossaries as $glossaryid=>$unused) { if (!$cm = get_coursemodule_from_instance('glossary', $glossaryid)) { continue; } $context = get_context_instance(CONTEXT_MODULE, $cm->id); //delete ratings $ratingdeloptions->contextid = $context->id; $rm->delete_ratings($ratingdeloptions); } } // remove all grades from gradebook if (empty($data->reset_gradebook_grades)) { glossary_reset_gradebook($data->courseid); } $status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallratings'), 'error'=>false); } // remove comments if (!empty($data->reset_glossary_comments)) { $params[] = 'glossary_entry'; $DB->delete_records_select('comments', "itemid IN ($allentriessql) AND commentarea= ? ", $params); $status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallcomments'), 'error'=>false); } /// updating dates - shift may be negative too if ($data->timeshift) { shift_course_mod_dates('glossary', array('assesstimestart', 'assesstimefinish'), $data->timeshift, $data->courseid); $status[] = array('component'=>$componentstr, 'item'=>get_string('datechanged'), 'error'=>false); } return $status; }
//attach ratings to data records require_once $CFG->dirroot . '/rating/lib.php'; if ($data->assessed != RATING_AGGREGATE_NONE) { $ratingoptions = new stdClass(); $ratingoptions->context = $context; $ratingoptions->component = 'mod_data'; $ratingoptions->ratingarea = 'entry'; $ratingoptions->items = $records; $ratingoptions->aggregate = $data->assessed; //the aggregation method $ratingoptions->scaleid = $data->scale; $ratingoptions->userid = $USER->id; $ratingoptions->returnurl = $CFG->wwwroot . '/mod/data/' . $baseurl; $ratingoptions->assesstimestart = $data->assesstimestart; $ratingoptions->assesstimefinish = $data->assesstimefinish; $rm = new rating_manager(); $records = $rm->get_ratings($ratingoptions); } data_print_template('singletemplate', $records, $data, $search, $page); echo $OUTPUT->paging_bar($totalcount, $page, $nowperpage, $baseurl); } else { // List template $baseurl = 'view.php?d=' . $data->id . '&'; //send the advanced flag through the URL so it is remembered while paging. $baseurl .= 'advanced=' . $advanced . '&'; if (!empty($search)) { $baseurl .= 'filter=1&'; } //pass variable to allow determining whether or not we are paging through results. $baseurl .= 'paging=' . $paging . '&'; echo $OUTPUT->paging_bar($totalcount, $page, $nowperpage, $baseurl);
//load ratings require_once $CFG->dirroot . '/rating/lib.php'; if ($glossary->assessed != RATING_AGGREGATE_NONE) { $ratingoptions = new stdClass(); $ratingoptions->context = $context; $ratingoptions->component = 'mod_glossary'; $ratingoptions->ratingarea = 'entry'; $ratingoptions->items = $allentries; $ratingoptions->aggregate = $glossary->assessed; //the aggregation method $ratingoptions->scaleid = $glossary->scale; $ratingoptions->userid = $USER->id; $ratingoptions->returnurl = $CFG->wwwroot . '/mod/glossary/view.php?id=' . $cm->id; $ratingoptions->assesstimestart = $glossary->assesstimestart; $ratingoptions->assesstimefinish = $glossary->assesstimefinish; $rm = new rating_manager(); $allentries = $rm->get_ratings($ratingoptions); } foreach ($allentries as $entry) { // Setting the pivot for the current entry $pivot = $entry->glossarypivot; $upperpivot = $textlib->strtoupper($pivot); $pivottoshow = $textlib->strtoupper(format_string($pivot, true, $fmtoptions)); // Reduce pivot to 1cc if necessary if (!$fullpivot) { $upperpivot = $textlib->substr($upperpivot, 0, 1); $pivottoshow = $textlib->substr($pivottoshow, 0, 1); } // if there's a group break if ($currentpivot != $upperpivot) { // print the group break if apply
/** * Delete all data linked to content, do not delete the context record itself */ public function delete_content() { global $CFG, $DB; blocks_delete_all_for_context($this->_id); filter_delete_all_for_context($this->_id); require_once $CFG->dirroot . '/comment/lib.php'; comment::delete_comments(array('contextid' => $this->_id)); require_once $CFG->dirroot . '/rating/lib.php'; $delopt = new stdclass(); $delopt->contextid = $this->_id; $rm = new rating_manager(); $rm->delete_ratings($delopt); // delete all files attached to this context $fs = get_file_storage(); $fs->delete_area_files($this->_id); // delete all advanced grading data attached to this context require_once $CFG->dirroot . '/grade/grading/lib.php'; grading_manager::delete_all_for_context($this->_id); // now delete stuff from role related tables, role_unassign_all // and unenrol should be called earlier to do proper cleanup $DB->delete_records('role_assignments', array('contextid' => $this->_id)); $DB->delete_records('role_capabilities', array('contextid' => $this->_id)); $DB->delete_records('role_names', array('contextid' => $this->_id)); }
/** * Adds a rating to an item * * @param string $contextlevel course, module, user... * @param int $instanceid the instance if for the context element * @param string $component the name of the component * @param string $ratingarea rating area * @param int $itemid the item id * @param int $scaleid the scale id * @param int $rating the user rating * @param int $rateduserid the rated user id * @param int $aggregation the aggregation method * @return array result and possible warnings * @throws moodle_exception * @since Moodle 3.2 */ public static function add_rating($contextlevel, $instanceid, $component, $ratingarea, $itemid, $scaleid, $rating, $rateduserid, $aggregation = RATING_AGGREGATE_NONE) { $warnings = array(); $params = array('contextlevel' => $contextlevel, 'instanceid' => $instanceid, 'component' => $component, 'ratingarea' => $ratingarea, 'itemid' => $itemid, 'scaleid' => $scaleid, 'rating' => $rating, 'rateduserid' => $rateduserid, 'aggregation' => $aggregation); // Validate and normalize parameters. $params = self::validate_parameters(self::add_rating_parameters(), $params); $context = self::get_context_from_params($params); self::validate_context($context); $cm = get_coursemodule_from_id(false, $context->instanceid, 0, false, MUST_EXIST); require_capability('moodle/rating:rate', $context); $rm = new rating_manager(); $result = $rm->add_rating($cm, $context, $params['component'], $params['ratingarea'], $params['itemid'], $params['scaleid'], $params['rating'], $params['rateduserid'], $params['aggregation']); if (!empty($result->error)) { throw new moodle_exception($result->error, 'rating'); } $returndata = array('success' => $result->success, 'warnings' => $warnings); if (isset($result->aggregate)) { $returndata['aggregate'] = $result->aggregate; $returndata['count'] = $result->count; $returndata['itemid'] = $result->itemid; } return $returndata; }