mirror of
https://github.com/moodle/moodle.git
synced 2025-08-08 18:36:42 +02:00
Merge remote-tracking branch 'moodle/master' into MDL-20636_master_new_question_engine
Conflicts: lib/db/upgrade.php mod/quiz/lib.php
This commit is contained in:
commit
54771d89d1
290 changed files with 4637 additions and 1419 deletions
|
@ -144,12 +144,13 @@ $string['noblogs'] = 'You have no blog entries to submit!';
|
|||
$string['nofiles'] = 'No files were submitted';
|
||||
$string['nofilesyet'] = 'No files submitted yet';
|
||||
$string['nomoresubmissions'] = 'No further submissions are allowed.';
|
||||
$string['nosubmitusers'] = 'No users were found with permissions to submit this assignment';
|
||||
$string['notavailableyet'] = 'Sorry, this assignment is not yet available.<br />Assignment instructions will be displayed here on the date given below.';
|
||||
$string['notes'] = 'Notes';
|
||||
$string['notesempty'] = 'No entry';
|
||||
$string['notesupdateerror'] = 'Error when updating notes';
|
||||
$string['notgradedyet'] = 'Not graded yet';
|
||||
$string['norequiregrading'] = 'There are no assignments that require grading';
|
||||
$string['nosubmisson'] = 'No assignments have been submit';
|
||||
$string['notsubmittedyet'] = 'Not submitted yet';
|
||||
$string['onceassignmentsent'] = 'Once the assignment is sent for marking, you will no longer be able to delete or attach file(s). Do you want to continue?';
|
||||
$string['operation'] = 'Operation';
|
||||
|
|
|
@ -1128,6 +1128,7 @@ class assignment_base {
|
|||
$course = $this->course;
|
||||
$assignment = $this->assignment;
|
||||
$cm = $this->cm;
|
||||
$hassubmission = false;
|
||||
|
||||
$tabindex = 1; //tabindex for quick grading tabbing; Not working for dropdowns yet
|
||||
add_to_log($course->id, 'assignment', 'view submission', 'submissions.php?id='.$this->cm->id, $this->assignment->id, $this->cm->id);
|
||||
|
@ -1264,16 +1265,7 @@ class assignment_base {
|
|||
// Start working -- this is necessary as soon as the niceties are over
|
||||
$table->setup();
|
||||
|
||||
if (empty($users)) {
|
||||
echo $OUTPUT->heading(get_string('nosubmitusers','assignment'));
|
||||
echo '</div>';
|
||||
return true;
|
||||
}
|
||||
if ($this->assignment->assignmenttype=='upload' || $this->assignment->assignmenttype=='online' || $this->assignment->assignmenttype=='uploadsingle') { //TODO: this is an ugly hack, where is the plugin spirit? (skodak)
|
||||
echo '<div style="text-align:right"><a href="submissions.php?id='.$this->cm->id.'&download=zip">'.get_string('downloadall', 'assignment').'</a></div>';
|
||||
}
|
||||
/// Construct the SQL
|
||||
|
||||
list($where, $params) = $table->get_sql_where();
|
||||
if ($where) {
|
||||
$where .= ' AND ';
|
||||
|
@ -1290,179 +1282,192 @@ class assignment_base {
|
|||
}
|
||||
|
||||
$ufields = user_picture::fields('u');
|
||||
if (!empty($users)) {
|
||||
$select = "SELECT $ufields,
|
||||
s.id AS submissionid, s.grade, s.submissioncomment,
|
||||
s.timemodified, s.timemarked,
|
||||
COALESCE(SIGN(SIGN(s.timemarked) + SIGN(s.timemarked - s.timemodified)), 0) AS status ";
|
||||
$sql = 'FROM {user} u '.
|
||||
'LEFT JOIN {assignment_submissions} s ON u.id = s.userid
|
||||
AND s.assignment = '.$this->assignment->id.' '.
|
||||
'WHERE '.$where.'u.id IN ('.implode(',',$users).') ';
|
||||
|
||||
$select = "SELECT $ufields,
|
||||
s.id AS submissionid, s.grade, s.submissioncomment,
|
||||
s.timemodified, s.timemarked,
|
||||
COALESCE(SIGN(SIGN(s.timemarked) + SIGN(s.timemarked - s.timemodified)), 0) AS status ";
|
||||
$sql = 'FROM {user} u '.
|
||||
'LEFT JOIN {assignment_submissions} s ON u.id = s.userid
|
||||
AND s.assignment = '.$this->assignment->id.' '.
|
||||
'WHERE '.$where.'u.id IN ('.implode(',',$users).') ';
|
||||
$ausers = $DB->get_records_sql($select.$sql.$sort, $params, $table->get_page_start(), $table->get_page_size());
|
||||
|
||||
$ausers = $DB->get_records_sql($select.$sql.$sort, $params, $table->get_page_start(), $table->get_page_size());
|
||||
$table->pagesize($perpage, count($users));
|
||||
|
||||
$table->pagesize($perpage, count($users));
|
||||
///offset used to calculate index of student in that particular query, needed for the pop up to know who's next
|
||||
$offset = $page * $perpage;
|
||||
$strupdate = get_string('update');
|
||||
$strgrade = get_string('grade');
|
||||
$grademenu = make_grades_menu($this->assignment->grade);
|
||||
|
||||
///offset used to calculate index of student in that particular query, needed for the pop up to know who's next
|
||||
$offset = $page * $perpage;
|
||||
$strupdate = get_string('update');
|
||||
$strgrade = get_string('grade');
|
||||
$grademenu = make_grades_menu($this->assignment->grade);
|
||||
if ($ausers !== false) {
|
||||
$grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id, array_keys($ausers));
|
||||
$endposition = $offset + $perpage;
|
||||
$currentposition = 0;
|
||||
foreach ($ausers as $auser) {
|
||||
if ($currentposition == $offset && $offset < $endposition) {
|
||||
$final_grade = $grading_info->items[0]->grades[$auser->id];
|
||||
$grademax = $grading_info->items[0]->grademax;
|
||||
$final_grade->formatted_grade = round($final_grade->grade,2) .' / ' . round($grademax,2);
|
||||
$locked_overridden = 'locked';
|
||||
if ($final_grade->overridden) {
|
||||
$locked_overridden = 'overridden';
|
||||
}
|
||||
|
||||
if ($ausers !== false) {
|
||||
$grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id, array_keys($ausers));
|
||||
$endposition = $offset + $perpage;
|
||||
$currentposition = 0;
|
||||
foreach ($ausers as $auser) {
|
||||
if ($currentposition == $offset && $offset < $endposition) {
|
||||
$final_grade = $grading_info->items[0]->grades[$auser->id];
|
||||
$grademax = $grading_info->items[0]->grademax;
|
||||
$final_grade->formatted_grade = round($final_grade->grade,2) .' / ' . round($grademax,2);
|
||||
$locked_overridden = 'locked';
|
||||
if ($final_grade->overridden) {
|
||||
$locked_overridden = 'overridden';
|
||||
}
|
||||
/// Calculate user status
|
||||
$auser->status = ($auser->timemarked > 0) && ($auser->timemarked >= $auser->timemodified);
|
||||
$picture = $OUTPUT->user_picture($auser);
|
||||
|
||||
/// Calculate user status
|
||||
$auser->status = ($auser->timemarked > 0) && ($auser->timemarked >= $auser->timemodified);
|
||||
$picture = $OUTPUT->user_picture($auser);
|
||||
if (empty($auser->submissionid)) {
|
||||
$auser->grade = -1; //no submission yet
|
||||
}
|
||||
|
||||
if (empty($auser->submissionid)) {
|
||||
$auser->grade = -1; //no submission yet
|
||||
}
|
||||
if (!empty($auser->submissionid)) {
|
||||
$hassubmission = true;
|
||||
///Prints student answer and student modified date
|
||||
///attach file or print link to student answer, depending on the type of the assignment.
|
||||
///Refer to print_student_answer in inherited classes.
|
||||
if ($auser->timemodified > 0) {
|
||||
$studentmodified = '<div id="ts'.$auser->id.'">'.$this->print_student_answer($auser->id)
|
||||
. userdate($auser->timemodified).'</div>';
|
||||
} else {
|
||||
$studentmodified = '<div id="ts'.$auser->id.'"> </div>';
|
||||
}
|
||||
///Print grade, dropdown or text
|
||||
if ($auser->timemarked > 0) {
|
||||
$teachermodified = '<div id="tt'.$auser->id.'">'.userdate($auser->timemarked).'</div>';
|
||||
|
||||
if (!empty($auser->submissionid)) {
|
||||
///Prints student answer and student modified date
|
||||
///attach file or print link to student answer, depending on the type of the assignment.
|
||||
///Refer to print_student_answer in inherited classes.
|
||||
if ($auser->timemodified > 0) {
|
||||
$studentmodified = '<div id="ts'.$auser->id.'">'.$this->print_student_answer($auser->id)
|
||||
. userdate($auser->timemodified).'</div>';
|
||||
if ($final_grade->locked or $final_grade->overridden) {
|
||||
$grade = '<div id="g'.$auser->id.'" class="'. $locked_overridden .'">'.$final_grade->formatted_grade.'</div>';
|
||||
} else if ($quickgrade) {
|
||||
$attributes = array();
|
||||
$attributes['tabindex'] = $tabindex++;
|
||||
$menu = html_writer::select(make_grades_menu($this->assignment->grade), 'menu['.$auser->id.']', $auser->grade, array(-1=>get_string('nograde')), $attributes);
|
||||
$grade = '<div id="g'.$auser->id.'">'. $menu .'</div>';
|
||||
} else {
|
||||
$grade = '<div id="g'.$auser->id.'">'.$this->display_grade($auser->grade).'</div>';
|
||||
}
|
||||
|
||||
} else {
|
||||
$teachermodified = '<div id="tt'.$auser->id.'"> </div>';
|
||||
if ($final_grade->locked or $final_grade->overridden) {
|
||||
$grade = '<div id="g'.$auser->id.'" class="'. $locked_overridden .'">'.$final_grade->formatted_grade.'</div>';
|
||||
} else if ($quickgrade) {
|
||||
$attributes = array();
|
||||
$attributes['tabindex'] = $tabindex++;
|
||||
$menu = html_writer::select(make_grades_menu($this->assignment->grade), 'menu['.$auser->id.']', $auser->grade, array(-1=>get_string('nograde')), $attributes);
|
||||
$grade = '<div id="g'.$auser->id.'">'.$menu.'</div>';
|
||||
} else {
|
||||
$grade = '<div id="g'.$auser->id.'">'.$this->display_grade($auser->grade).'</div>';
|
||||
}
|
||||
}
|
||||
///Print Comment
|
||||
if ($final_grade->locked or $final_grade->overridden) {
|
||||
$comment = '<div id="com'.$auser->id.'">'.shorten_text(strip_tags($final_grade->str_feedback),15).'</div>';
|
||||
|
||||
} else if ($quickgrade) {
|
||||
$comment = '<div id="com'.$auser->id.'">'
|
||||
. '<textarea tabindex="'.$tabindex++.'" name="submissioncomment['.$auser->id.']" id="submissioncomment'
|
||||
. $auser->id.'" rows="2" cols="20">'.($auser->submissioncomment).'</textarea></div>';
|
||||
} else {
|
||||
$comment = '<div id="com'.$auser->id.'">'.shorten_text(strip_tags($auser->submissioncomment),15).'</div>';
|
||||
}
|
||||
} else {
|
||||
$studentmodified = '<div id="ts'.$auser->id.'"> </div>';
|
||||
}
|
||||
///Print grade, dropdown or text
|
||||
if ($auser->timemarked > 0) {
|
||||
$teachermodified = '<div id="tt'.$auser->id.'">'.userdate($auser->timemarked).'</div>';
|
||||
|
||||
if ($final_grade->locked or $final_grade->overridden) {
|
||||
$grade = '<div id="g'.$auser->id.'" class="'. $locked_overridden .'">'.$final_grade->formatted_grade.'</div>';
|
||||
} else if ($quickgrade) {
|
||||
$attributes = array();
|
||||
$attributes['tabindex'] = $tabindex++;
|
||||
$menu = html_writer::select(make_grades_menu($this->assignment->grade), 'menu['.$auser->id.']', $auser->grade, array(-1=>get_string('nograde')), $attributes);
|
||||
$grade = '<div id="g'.$auser->id.'">'. $menu .'</div>';
|
||||
} else {
|
||||
$grade = '<div id="g'.$auser->id.'">'.$this->display_grade($auser->grade).'</div>';
|
||||
}
|
||||
|
||||
} else {
|
||||
$teachermodified = '<div id="tt'.$auser->id.'"> </div>';
|
||||
$status = '<div id="st'.$auser->id.'"> </div>';
|
||||
|
||||
if ($final_grade->locked or $final_grade->overridden) {
|
||||
$grade = '<div id="g'.$auser->id.'" class="'. $locked_overridden .'">'.$final_grade->formatted_grade.'</div>';
|
||||
} else if ($quickgrade) {
|
||||
$grade = '<div id="g'.$auser->id.'">'.$final_grade->formatted_grade . '</div>';
|
||||
$hassubmission = true;
|
||||
} else if ($quickgrade) { // allow editing
|
||||
$attributes = array();
|
||||
$attributes['tabindex'] = $tabindex++;
|
||||
$menu = html_writer::select(make_grades_menu($this->assignment->grade), 'menu['.$auser->id.']', $auser->grade, array(-1=>get_string('nograde')), $attributes);
|
||||
$grade = '<div id="g'.$auser->id.'">'.$menu.'</div>';
|
||||
$hassubmission = true;
|
||||
} else {
|
||||
$grade = '<div id="g'.$auser->id.'">'.$this->display_grade($auser->grade).'</div>';
|
||||
$grade = '<div id="g'.$auser->id.'">-</div>';
|
||||
}
|
||||
|
||||
if ($final_grade->locked or $final_grade->overridden) {
|
||||
$comment = '<div id="com'.$auser->id.'">'.$final_grade->str_feedback.'</div>';
|
||||
} else if ($quickgrade) {
|
||||
$comment = '<div id="com'.$auser->id.'">'
|
||||
. '<textarea tabindex="'.$tabindex++.'" name="submissioncomment['.$auser->id.']" id="submissioncomment'
|
||||
. $auser->id.'" rows="2" cols="20">'.($auser->submissioncomment).'</textarea></div>';
|
||||
} else {
|
||||
$comment = '<div id="com'.$auser->id.'"> </div>';
|
||||
}
|
||||
}
|
||||
///Print Comment
|
||||
if ($final_grade->locked or $final_grade->overridden) {
|
||||
$comment = '<div id="com'.$auser->id.'">'.shorten_text(strip_tags($final_grade->str_feedback),15).'</div>';
|
||||
|
||||
} else if ($quickgrade) {
|
||||
$comment = '<div id="com'.$auser->id.'">'
|
||||
. '<textarea tabindex="'.$tabindex++.'" name="submissioncomment['.$auser->id.']" id="submissioncomment'
|
||||
. $auser->id.'" rows="2" cols="20">'.($auser->submissioncomment).'</textarea></div>';
|
||||
if (empty($auser->status)) { /// Confirm we have exclusively 0 or 1
|
||||
$auser->status = 0;
|
||||
} else {
|
||||
$comment = '<div id="com'.$auser->id.'">'.shorten_text(strip_tags($auser->submissioncomment),15).'</div>';
|
||||
}
|
||||
} else {
|
||||
$studentmodified = '<div id="ts'.$auser->id.'"> </div>';
|
||||
$teachermodified = '<div id="tt'.$auser->id.'"> </div>';
|
||||
$status = '<div id="st'.$auser->id.'"> </div>';
|
||||
|
||||
if ($final_grade->locked or $final_grade->overridden) {
|
||||
$grade = '<div id="g'.$auser->id.'">'.$final_grade->formatted_grade . '</div>';
|
||||
} else if ($quickgrade) { // allow editing
|
||||
$attributes = array();
|
||||
$attributes['tabindex'] = $tabindex++;
|
||||
$menu = html_writer::select(make_grades_menu($this->assignment->grade), 'menu['.$auser->id.']', $auser->grade, array(-1=>get_string('nograde')), $attributes);
|
||||
$grade = '<div id="g'.$auser->id.'">'.$menu.'</div>';
|
||||
} else {
|
||||
$grade = '<div id="g'.$auser->id.'">-</div>';
|
||||
$auser->status = 1;
|
||||
}
|
||||
|
||||
if ($final_grade->locked or $final_grade->overridden) {
|
||||
$comment = '<div id="com'.$auser->id.'">'.$final_grade->str_feedback.'</div>';
|
||||
} else if ($quickgrade) {
|
||||
$comment = '<div id="com'.$auser->id.'">'
|
||||
. '<textarea tabindex="'.$tabindex++.'" name="submissioncomment['.$auser->id.']" id="submissioncomment'
|
||||
. $auser->id.'" rows="2" cols="20">'.($auser->submissioncomment).'</textarea></div>';
|
||||
} else {
|
||||
$comment = '<div id="com'.$auser->id.'"> </div>';
|
||||
}
|
||||
}
|
||||
$buttontext = ($auser->status == 1) ? $strupdate : $strgrade;
|
||||
|
||||
if (empty($auser->status)) { /// Confirm we have exclusively 0 or 1
|
||||
$auser->status = 0;
|
||||
} else {
|
||||
$auser->status = 1;
|
||||
}
|
||||
///No more buttons, we use popups ;-).
|
||||
$popup_url = '/mod/assignment/submissions.php?id='.$this->cm->id
|
||||
. '&userid='.$auser->id.'&mode=single'.'&filter='.$filter.'&offset='.$offset++;
|
||||
|
||||
$buttontext = ($auser->status == 1) ? $strupdate : $strgrade;
|
||||
$button = $OUTPUT->action_link($popup_url, $buttontext);
|
||||
|
||||
///No more buttons, we use popups ;-).
|
||||
$popup_url = '/mod/assignment/submissions.php?id='.$this->cm->id
|
||||
. '&userid='.$auser->id.'&mode=single'.'&filter='.$filter.'&offset='.$offset++;
|
||||
$status = '<div id="up'.$auser->id.'" class="s'.$auser->status.'">'.$button.'</div>';
|
||||
|
||||
$button = $OUTPUT->action_link($popup_url, $buttontext);
|
||||
$finalgrade = '<span id="finalgrade_'.$auser->id.'">'.$final_grade->str_grade.'</span>';
|
||||
|
||||
$status = '<div id="up'.$auser->id.'" class="s'.$auser->status.'">'.$button.'</div>';
|
||||
$outcomes = '';
|
||||
|
||||
$finalgrade = '<span id="finalgrade_'.$auser->id.'">'.$final_grade->str_grade.'</span>';
|
||||
if ($uses_outcomes) {
|
||||
|
||||
$outcomes = '';
|
||||
foreach($grading_info->outcomes as $n=>$outcome) {
|
||||
$outcomes .= '<div class="outcome"><label>'.$outcome->name.'</label>';
|
||||
$options = make_grades_menu(-$outcome->scaleid);
|
||||
|
||||
if ($uses_outcomes) {
|
||||
|
||||
foreach($grading_info->outcomes as $n=>$outcome) {
|
||||
$outcomes .= '<div class="outcome"><label>'.$outcome->name.'</label>';
|
||||
$options = make_grades_menu(-$outcome->scaleid);
|
||||
|
||||
if ($outcome->grades[$auser->id]->locked or !$quickgrade) {
|
||||
$options[0] = get_string('nooutcome', 'grades');
|
||||
$outcomes .= ': <span id="outcome_'.$n.'_'.$auser->id.'">'.$options[$outcome->grades[$auser->id]->grade].'</span>';
|
||||
} else {
|
||||
$attributes = array();
|
||||
$attributes['tabindex'] = $tabindex++;
|
||||
$attributes['id'] = 'outcome_'.$n.'_'.$auser->id;
|
||||
$outcomes .= ' '.html_writer::select($options, 'outcome_'.$n.'['.$auser->id.']', $outcome->grades[$auser->id]->grade, array(0=>get_string('nooutcome', 'grades')), $attributes);
|
||||
if ($outcome->grades[$auser->id]->locked or !$quickgrade) {
|
||||
$options[0] = get_string('nooutcome', 'grades');
|
||||
$outcomes .= ': <span id="outcome_'.$n.'_'.$auser->id.'">'.$options[$outcome->grades[$auser->id]->grade].'</span>';
|
||||
} else {
|
||||
$attributes = array();
|
||||
$attributes['tabindex'] = $tabindex++;
|
||||
$attributes['id'] = 'outcome_'.$n.'_'.$auser->id;
|
||||
$outcomes .= ' '.html_writer::select($options, 'outcome_'.$n.'['.$auser->id.']', $outcome->grades[$auser->id]->grade, array(0=>get_string('nooutcome', 'grades')), $attributes);
|
||||
}
|
||||
$outcomes .= '</div>';
|
||||
}
|
||||
$outcomes .= '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
$userlink = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $auser->id . '&course=' . $course->id . '">' . fullname($auser, has_capability('moodle/site:viewfullnames', $this->context)) . '</a>';
|
||||
$row = array($picture, $userlink, $grade, $comment, $studentmodified, $teachermodified, $status, $finalgrade);
|
||||
if ($uses_outcomes) {
|
||||
$row[] = $outcomes;
|
||||
$userlink = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $auser->id . '&course=' . $course->id . '">' . fullname($auser, has_capability('moodle/site:viewfullnames', $this->context)) . '</a>';
|
||||
$row = array($picture, $userlink, $grade, $comment, $studentmodified, $teachermodified, $status, $finalgrade);
|
||||
if ($uses_outcomes) {
|
||||
$row[] = $outcomes;
|
||||
}
|
||||
$table->add_data($row);
|
||||
}
|
||||
|
||||
$table->add_data($row);
|
||||
$currentposition++;
|
||||
}
|
||||
$currentposition++;
|
||||
}
|
||||
if ($hassubmission && ($this->assignment->assignmenttype=='upload' || $this->assignment->assignmenttype=='online' || $this->assignment->assignmenttype=='uploadsingle')) { //TODO: this is an ugly hack, where is the plugin spirit? (skodak)
|
||||
echo html_writer::start_tag('div', array('class' => 'mod-assignment-download-link'));
|
||||
echo html_writer::link(new moodle_url('/mod/assignment/submissions.php', array('id' => $this->cm->id, 'download' => 'zip')), get_string('downloadall', 'assignment'));
|
||||
echo html_writer::end_tag('div');
|
||||
}
|
||||
$table->print_html(); /// Print the whole table
|
||||
} else {
|
||||
if ($filter == self::FILTER_SUBMITTED) {
|
||||
echo html_writer::tag('div', get_string('nosubmisson', 'assignment'), array('class'=>'nosubmisson'));
|
||||
} else if ($filter == self::FILTER_REQUIRE_GRADING) {
|
||||
echo html_writer::tag('div', get_string('norequiregrading', 'assignment'), array('class'=>'norequiregrading'));
|
||||
}
|
||||
}
|
||||
|
||||
$table->print_html(); /// Print the whole table
|
||||
|
||||
/// Print quickgrade form around the table
|
||||
if ($quickgrade && $table->started_output){
|
||||
if ($quickgrade && $table->started_output && !empty($users)){
|
||||
$mailinfopref = false;
|
||||
if (get_user_preferences('assignment_mailinfo', 1)) {
|
||||
$mailinfopref = true;
|
||||
|
@ -2767,6 +2772,8 @@ function assignment_grade_item_delete($assignment) {
|
|||
/**
|
||||
* Returns the users with data in one assignment (students and teachers)
|
||||
*
|
||||
* @todo: deprecated - to be deleted in 2.2
|
||||
*
|
||||
* @param $assignmentid int
|
||||
* @return array of user objects
|
||||
*/
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#page-mod-assignment-submissions .submissions .grade,
|
||||
#page-mod-assignment-submissions .submissions .outcome,
|
||||
#page-mod-assignment-submissions .submissions .finalgrade {text-align: right;}
|
||||
#page-mod-assignment-submissions .submissions .header.noheader {display:none;}
|
||||
#page-mod-assignment-submissions .qgprefs #optiontable {text-align:right;margin-left:auto;}
|
||||
|
||||
/** Styles for view.php **/
|
||||
|
@ -42,4 +43,6 @@
|
|||
#page-mod-assignment-submissions.dir-rtl .timemodified,
|
||||
#page-mod-assignment-submissions.dir-rtl .timemarked {text-align:right;}
|
||||
#page-mod-assignment-submissions.dir-rtl .mform.optionspref .fitem .fitemtitle {text-align:left;}
|
||||
#page-mod-assignment-type-uploadsingle-upload.dir-rtl .mdl-left {text-align:right;}
|
||||
#page-mod-assignment-type-uploadsingle-upload.dir-rtl .mdl-left {text-align:right;}
|
||||
|
||||
.mod-assignment-download-link {text-align:right;}
|
|
@ -430,7 +430,8 @@ function chat_cron () {
|
|||
* Returns the users with data in one chat
|
||||
* (users with records in chat_messages, students)
|
||||
*
|
||||
* @global object
|
||||
* @todo: deprecated - to be deleted in 2.2
|
||||
*
|
||||
* @param int $chatid
|
||||
* @param int $groupid
|
||||
* @return array
|
||||
|
|
|
@ -39,7 +39,7 @@ class backup_choice_activity_structure_step extends backup_activity_structure_st
|
|||
// Define each element separated
|
||||
$choice = new backup_nested_element('choice', array('id'), array(
|
||||
'name', 'intro', 'introformat', 'publish',
|
||||
'showresults', 'display', 'allowupdate', 'allowunanswered',
|
||||
'showresults', 'display', 'allowupdate', 'showunanswered',
|
||||
'limitanswers', 'timeopen', 'timeclose', 'timemodified',
|
||||
'completionsubmit'));
|
||||
|
||||
|
|
|
@ -591,6 +591,8 @@ function choice_delete_instance($id) {
|
|||
* Returns the users with data in one choice
|
||||
* (users with records in choice_responses, students)
|
||||
*
|
||||
* @todo: deprecated - to be deleted in 2.2
|
||||
*
|
||||
* @param int $choiceid
|
||||
* @return array
|
||||
*/
|
||||
|
|
|
@ -40,7 +40,7 @@ class mod_choice_renderer extends plugin_renderer_base {
|
|||
$layoutclass = 'vertical';
|
||||
}
|
||||
$target = new moodle_url('/mod/choice/view.php');
|
||||
$attributes = array('method'=>'POST', 'target'=>$target, 'class'=> $layoutclass);
|
||||
$attributes = array('method'=>'POST', 'action'=>$target, 'class'=> $layoutclass);
|
||||
|
||||
$html = html_writer::start_tag('form', $attributes);
|
||||
$html .= html_writer::start_tag('ul', array('class'=>'choices' ));
|
||||
|
|
|
@ -69,7 +69,7 @@ class backup_data_activity_structure_step extends backup_activity_structure_step
|
|||
$ratings = new backup_nested_element('ratings');
|
||||
|
||||
$rating = new backup_nested_element('rating', array('id'), array(
|
||||
'scaleid', 'value', 'userid', 'timecreated', 'timemodified'));
|
||||
'component', 'ratingarea', 'scaleid', 'value', 'userid', 'timecreated', 'timemodified'));
|
||||
|
||||
// Build the tree
|
||||
$data->add_child($fields);
|
||||
|
@ -99,8 +99,10 @@ class backup_data_activity_structure_step extends backup_activity_structure_step
|
|||
|
||||
$content->set_source_table('data_content', array('recordid' => backup::VAR_PARENTID));
|
||||
|
||||
$rating->set_source_table('rating', array('contextid' => backup::VAR_CONTEXTID,
|
||||
'itemid' => backup::VAR_PARENTID));
|
||||
$rating->set_source_table('rating', array('contextid' => backup::VAR_CONTEXTID,
|
||||
'itemid' => backup::VAR_PARENTID,
|
||||
'component' => 'mod_data',
|
||||
'ratingarea' => 'entry'));
|
||||
$rating->set_source_alias('rating', 'value');
|
||||
}
|
||||
|
||||
|
|
|
@ -138,6 +138,14 @@ class restore_data_activity_structure_step extends restore_activity_structure_st
|
|||
$data->timecreated = $this->apply_date_offset($data->timecreated);
|
||||
$data->timemodified = $this->apply_date_offset($data->timemodified);
|
||||
|
||||
// We need to check that component and ratingarea are both set here.
|
||||
if (empty($data->component)) {
|
||||
$data->component = 'mod_data';
|
||||
}
|
||||
if (empty($data->ratingarea)) {
|
||||
$data->ratingarea = 'entry';
|
||||
}
|
||||
|
||||
$newitemid = $DB->insert_record('rating', $data);
|
||||
}
|
||||
|
||||
|
|
|
@ -315,6 +315,29 @@ function xmldb_data_upgrade($oldversion) {
|
|||
upgrade_mod_savepoint(true, 2010100101, 'data');
|
||||
}
|
||||
|
||||
if ($oldversion < 2011052300) {
|
||||
// rating.component and rating.ratingarea have now been added as mandatory fields.
|
||||
// Presently you can only rate data entries so component = 'mod_data' and ratingarea = 'entry'
|
||||
// for all ratings with a data context.
|
||||
// We want to update all ratings that belong to a data context and don't already have a
|
||||
// component set.
|
||||
// This could take a while reset upgrade timeout to 5 min
|
||||
upgrade_set_timeout(60 * 20);
|
||||
$sql = "UPDATE {rating}
|
||||
SET component = 'mod_data', ratingarea = 'entry'
|
||||
WHERE contextid IN (
|
||||
SELECT ctx.id
|
||||
FROM {context} ctx
|
||||
JOIN {course_modules} cm ON cm.id = ctx.instanceid
|
||||
JOIN {modules} m ON m.id = cm.module
|
||||
WHERE ctx.contextlevel = 70 AND
|
||||
m.name = 'data'
|
||||
) AND component = 'unknown'";
|
||||
$DB->execute($sql);
|
||||
|
||||
upgrade_mod_savepoint(true, 2011052300, 'data');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
163
mod/data/lib.php
163
mod/data/lib.php
|
@ -527,10 +527,10 @@ function data_generate_default_template(&$data, $template, $recordid=0, $form=fa
|
|||
$cell->attributes['class'] = 'controls';
|
||||
$table->data[] = new html_table_row(array($cell));
|
||||
} else if ($template == 'asearchtemplate') {
|
||||
$row = new html_table_row(get_string('authorfirstname', 'data').': ', '##firstname##');
|
||||
$row = new html_table_row(array(get_string('authorfirstname', 'data').': ', '##firstname##'));
|
||||
$row->attributes['class'] = 'searchcontrols';
|
||||
$table->data[] = $row;
|
||||
$row = new html_table_row(get_string('authorlastname', 'data').': ', '##lastname##');
|
||||
$row = new html_table_row(array(get_string('authorlastname', 'data').': ', '##lastname##'));
|
||||
$row->attributes['class'] = 'searchcontrols';
|
||||
$table->data[] = $row;
|
||||
}
|
||||
|
@ -962,7 +962,16 @@ function data_user_outline($course, $user, $mod, $data) {
|
|||
} else if ($grade) {
|
||||
$result = new stdClass();
|
||||
$result->info = get_string('grade') . ': ' . $grade->str_long_grade;
|
||||
$result->time = $grade->dategraded;
|
||||
|
||||
//datesubmitted == time created. dategraded == time modified or time overridden
|
||||
//if grade was last modified by the user themselves use date graded. Otherwise use date submitted
|
||||
//TODO: move this copied & pasted code somewhere in the grades API. See MDL-26704
|
||||
if ($grade->usermodified == $user->id || empty($grade->datesubmitted)) {
|
||||
$result->time = $grade->dategraded;
|
||||
} else {
|
||||
$result->time = $grade->datesubmitted;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -1007,9 +1016,10 @@ function data_get_user_grades($data, $userid=0) {
|
|||
global $CFG;
|
||||
|
||||
require_once($CFG->dirroot.'/rating/lib.php');
|
||||
$rm = new rating_manager();
|
||||
|
||||
$ratingoptions = new stdclass();
|
||||
$ratingoptions = new stdClass;
|
||||
$ratingoptions->component = 'mod_data';
|
||||
$ratingoptions->ratingarea = 'entry';
|
||||
$ratingoptions->modulename = 'data';
|
||||
$ratingoptions->moduleid = $data->id;
|
||||
|
||||
|
@ -1019,6 +1029,7 @@ function data_get_user_grades($data, $userid=0) {
|
|||
$ratingoptions->itemtable = 'data_records';
|
||||
$ratingoptions->itemtableusercolumn = 'userid';
|
||||
|
||||
$rm = new rating_manager();
|
||||
return $rm->get_user_grades($ratingoptions);
|
||||
}
|
||||
|
||||
|
@ -1135,25 +1146,46 @@ function data_grade_item_delete($data) {
|
|||
/**
|
||||
* returns a list of participants of this database
|
||||
*
|
||||
* @global object
|
||||
* Returns the users with data in one data
|
||||
* (users with records in data_records, data_comments and ratings)
|
||||
*
|
||||
* @todo: deprecated - to be deleted in 2.2
|
||||
*
|
||||
* @param int $dataid
|
||||
* @return array
|
||||
*/
|
||||
function data_get_participants($dataid) {
|
||||
// Returns the users with data in one data
|
||||
// (users with records in data_records, data_comments and ratings)
|
||||
global $DB;
|
||||
|
||||
$records = $DB->get_records_sql("SELECT DISTINCT u.id, u.id
|
||||
FROM {user} u, {data_records} r
|
||||
WHERE r.dataid = ? AND u.id = r.userid", array($dataid));
|
||||
$params = array('dataid' => $dataid);
|
||||
|
||||
$comments = $DB->get_records_sql("SELECT DISTINCT u.id, u.id
|
||||
FROM {user} u, {data_records} r, {comments} c
|
||||
WHERE r.dataid = ? AND u.id = r.userid AND r.id = c.itemid AND c.commentarea='database_entry'", array($dataid));
|
||||
$sql = "SELECT DISTINCT u.id, u.id
|
||||
FROM {user} u,
|
||||
{data_records} r
|
||||
WHERE r.dataid = :dataid AND
|
||||
u.id = r.userid";
|
||||
$records = $DB->get_records_sql($sql, $params);
|
||||
|
||||
$ratings = $DB->get_records_sql("SELECT DISTINCT u.id, u.id
|
||||
FROM {user} u, {data_records} r, {ratings} a
|
||||
WHERE r.dataid = ? AND u.id = r.userid AND r.id = a.itemid", array($dataid));
|
||||
$sql = "SELECT DISTINCT u.id, u.id
|
||||
FROM {user} u,
|
||||
{data_records} r,
|
||||
{comments} c
|
||||
WHERE r.dataid = ? AND
|
||||
u.id = r.userid AND
|
||||
r.id = c.itemid AND
|
||||
c.commentarea = 'database_entry'";
|
||||
$comments = $DB->get_records_sql($sql, $params);
|
||||
|
||||
$sql = "SELECT DISTINCT u.id, u.id
|
||||
FROM {user} u,
|
||||
{data_records} r,
|
||||
{ratings} a
|
||||
WHERE r.dataid = ? AND
|
||||
u.id = r.userid AND
|
||||
r.id = a.itemid AND
|
||||
a.component = 'mod_data' AND
|
||||
a.ratingarea = 'entry'";
|
||||
$ratings = $DB->get_records_sql($sql, $params);
|
||||
|
||||
$participants = array();
|
||||
|
||||
|
@ -1348,20 +1380,23 @@ function data_print_template($template, $records, $data, $search='', $page=0, $r
|
|||
|
||||
/**
|
||||
* Return rating related permissions
|
||||
* @param string $options the context id
|
||||
*
|
||||
* @param string $contextid the context id
|
||||
* @param string $component the component to get rating permissions for
|
||||
* @param string $ratingarea the rating area to get permissions for
|
||||
* @return array an associative array of the user's rating permissions
|
||||
*/
|
||||
function data_rating_permissions($options) {
|
||||
$contextid = $options;
|
||||
$context = get_context_instance_by_id($contextid);
|
||||
|
||||
if (!$context) {
|
||||
print_error('invalidcontext');
|
||||
function data_rating_permissions($contextid, $component, $ratingarea) {
|
||||
$context = get_context_instance_by_id($contextid, MUST_EXIST);
|
||||
if ($component != 'mod_data' || $ratingarea != 'entry') {
|
||||
return null;
|
||||
} else {
|
||||
$ret = new stdclass();
|
||||
return array('view'=>has_capability('mod/data:viewrating',$context), 'viewany'=>has_capability('mod/data:viewanyrating',$context), 'viewall'=>has_capability('mod/data:viewallratings',$context), 'rate'=>has_capability('mod/data:rate',$context));
|
||||
}
|
||||
return array(
|
||||
'view' => has_capability('mod/data:viewrating',$context),
|
||||
'viewany' => has_capability('mod/data:viewanyrating',$context),
|
||||
'viewall' => has_capability('mod/data:viewallratings',$context),
|
||||
'rate' => has_capability('mod/data:rate',$context)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1378,11 +1413,22 @@ function data_rating_permissions($options) {
|
|||
function data_rating_validate($params) {
|
||||
global $DB, $USER;
|
||||
|
||||
if (!array_key_exists('itemid', $params) || !array_key_exists('context', $params) || !array_key_exists('rateduserid', $params)) {
|
||||
throw new rating_exception('missingparameter');
|
||||
// Check the component is mod_data
|
||||
if ($params['component'] != 'mod_data') {
|
||||
throw new rating_exception('invalidcomponent');
|
||||
}
|
||||
|
||||
$datasql = "SELECT d.id as did, d.course, r.userid as userid, d.approval, r.approved, r.timecreated, d.assesstimestart, d.assesstimefinish, r.groupid
|
||||
// Check the ratingarea is entry (the only rating area in data module)
|
||||
if ($params['ratingarea'] != 'entry') {
|
||||
throw new rating_exception('invalidratingarea');
|
||||
}
|
||||
|
||||
// Check the rateduserid is not the current user .. you can't rate your own entries
|
||||
if ($params['rateduserid'] == $USER->id) {
|
||||
throw new rating_exception('nopermissiontorate');
|
||||
}
|
||||
|
||||
$datasql = "SELECT d.id as dataid, d.scale, d.course, r.userid as userid, d.approval, r.approved, r.timecreated, d.assesstimestart, d.assesstimefinish, r.groupid
|
||||
FROM {data_records} r
|
||||
JOIN {data} d ON r.dataid = d.id
|
||||
WHERE r.id = :itemid";
|
||||
|
@ -1392,14 +1438,33 @@ function data_rating_validate($params) {
|
|||
throw new rating_exception('invaliditemid');
|
||||
}
|
||||
|
||||
if ($info->userid == $USER->id) {
|
||||
//user is attempting to rate their own glossary entry
|
||||
throw new rating_exception('nopermissiontorate');
|
||||
if ($info->scale != $params['scaleid']) {
|
||||
//the scale being submitted doesnt match the one in the database
|
||||
throw new rating_exception('invalidscaleid');
|
||||
}
|
||||
|
||||
if ($params['rateduserid'] != $info->userid) {
|
||||
//supplied user ID doesnt match the user ID from the database
|
||||
throw new rating_exception('invaliduserid');
|
||||
//check that the submitted rating is valid for the scale
|
||||
|
||||
// lower limit
|
||||
if ($params['rating'] < 0 && $params['rating'] != RATING_UNSET_RATING) {
|
||||
throw new rating_exception('invalidnum');
|
||||
}
|
||||
|
||||
// upper limit
|
||||
if ($info->scale < 0) {
|
||||
//its a custom scale
|
||||
$scalerecord = $DB->get_record('scale', array('id' => -$info->scale));
|
||||
if ($scalerecord) {
|
||||
$scalearray = explode(',', $scalerecord->scale);
|
||||
if ($params['rating'] > count($scalearray)) {
|
||||
throw new rating_exception('invalidnum');
|
||||
}
|
||||
} else {
|
||||
throw new rating_exception('invalidscaleid');
|
||||
}
|
||||
} else if ($params['rating'] > $info->scale) {
|
||||
//if its numeric and submitted rating is above maximum
|
||||
throw new rating_exception('invalidnum');
|
||||
}
|
||||
|
||||
if ($info->approval && !$info->approved) {
|
||||
|
@ -1407,30 +1472,24 @@ function data_rating_validate($params) {
|
|||
throw new rating_exception('nopermissiontorate');
|
||||
}
|
||||
|
||||
//check the item we're rating was created in the assessable time window
|
||||
// check the item we're rating was created in the assessable time window
|
||||
if (!empty($info->assesstimestart) && !empty($info->assesstimefinish)) {
|
||||
if ($info->timecreated < $info->assesstimestart || $info->timecreated > $info->assesstimefinish) {
|
||||
throw new rating_exception('notavailable');
|
||||
}
|
||||
}
|
||||
|
||||
$dataid = $info->did;
|
||||
$groupid = $info->groupid;
|
||||
$courseid = $info->course;
|
||||
$course = $DB->get_record('course', array('id'=>$info->course), '*', MUST_EXIST);
|
||||
$cm = get_coursemodule_from_instance('data', $info->dataid, $course->id, false, MUST_EXIST);
|
||||
$context = get_context_instance(CONTEXT_MODULE, $cm->id, MUST_EXIST);
|
||||
|
||||
$cm = get_coursemodule_from_instance('data', $dataid);
|
||||
if (empty($cm)) {
|
||||
throw new rating_exception('unknowncontext');
|
||||
}
|
||||
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
|
||||
|
||||
//if the supplied context doesnt match the item's context
|
||||
if (empty($context) || $context->id != $params['context']->id) {
|
||||
// if the supplied context doesnt match the item's context
|
||||
if ($context->id != $params['context']->id) {
|
||||
throw new rating_exception('invalidcontext');
|
||||
}
|
||||
|
||||
// Make sure groups allow this user to see the item they're rating
|
||||
$course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
|
||||
$groupid = $info->groupid;
|
||||
if ($groupid > 0 and $groupmode = groups_get_activity_groupmode($cm, $course)) { // Groups are being used
|
||||
if (!groups_group_exists($groupid)) { // Can't find group
|
||||
throw new rating_exception('cannotfindgroup');//something is wrong
|
||||
|
@ -1640,7 +1699,7 @@ function data_print_preference_form($data, $perpage, $search, $sort='', $order='
|
|||
*/
|
||||
function data_print_ratings($data, $record) {
|
||||
global $OUTPUT;
|
||||
if( !empty($record->rating) ){
|
||||
if (!empty($record->rating)){
|
||||
echo $OUTPUT->render($record->rating);
|
||||
}
|
||||
}
|
||||
|
@ -2487,7 +2546,9 @@ function data_reset_userdata($data) {
|
|||
WHERE d.course=?";
|
||||
|
||||
$rm = new rating_manager();
|
||||
$ratingdeloptions = new stdclass();
|
||||
$ratingdeloptions = new stdClass;
|
||||
$ratingdeloptions->component = 'mod_data';
|
||||
$ratingdeloptions->ratingarea = 'entry';
|
||||
|
||||
// delete entries if requested
|
||||
if (!empty($data->reset_data)) {
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
// This fragment is called by /admin/index.php
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$module->version = 2010100101;
|
||||
$module->requires = 2010080300; // Requires this Moodle version
|
||||
$module->version = 2011052300;
|
||||
$module->requires = 2011052300; // Requires this Moodle version
|
||||
$module->cron = 60;
|
||||
|
||||
|
||||
|
|
|
@ -668,10 +668,11 @@ if ($showactivity) {
|
|||
//data_print_template() only adds ratings for singletemplate which is why we're attaching them here
|
||||
//attach ratings to data records
|
||||
require_once($CFG->dirroot.'/rating/lib.php');
|
||||
if ($data->assessed!=RATING_AGGREGATE_NONE) {
|
||||
$ratingoptions = new stdclass();
|
||||
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;
|
||||
|
|
|
@ -27,6 +27,9 @@ $messageproviders = array (
|
|||
|
||||
/// Submitting a feedback
|
||||
'submission' => array (
|
||||
),
|
||||
/// Message to nonrespondents
|
||||
'message' => array (
|
||||
)
|
||||
|
||||
);
|
||||
|
|
|
@ -467,6 +467,7 @@ function feedback_cron () {
|
|||
}
|
||||
|
||||
/**
|
||||
* @todo: deprecated - to be deleted in 2.2
|
||||
* @return bool false
|
||||
*/
|
||||
function feedback_get_participants($feedbackid) {
|
||||
|
|
|
@ -75,8 +75,8 @@
|
|||
foreach ($messageuser as $userid) {
|
||||
$senduser = $DB->get_record('user', array('id'=>$userid));
|
||||
$eventdata = new stdClass();
|
||||
$eventdata->name = 'feedback';
|
||||
$eventdata->component = 'mod';
|
||||
$eventdata->name = 'message';
|
||||
$eventdata->component = 'mod_feedback';
|
||||
$eventdata->userfrom = $USER;
|
||||
$eventdata->userto = $senduser;
|
||||
$eventdata->subject = $subject;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
|
||||
|
||||
$module->version = 2010112302; // The current module version (Date: YYYYMMDDXX)
|
||||
$module->version = 2011051600; // The current module version (Date: YYYYMMDDXX)
|
||||
$module->requires = 2010080300; // Requires this Moodle version
|
||||
$feedback_version_intern = 1; //this version is used for restore older backups
|
||||
$module->cron = 0; // Period for cron to check this module (secs)
|
||||
|
|
|
@ -205,6 +205,8 @@ function folder_user_complete($course, $user, $mod, $folder) {
|
|||
/**
|
||||
* Returns the users with data in one folder
|
||||
*
|
||||
* @todo: deprecated - to be deleted in 2.2
|
||||
*
|
||||
* @param int $folderid
|
||||
* @return bool false
|
||||
*/
|
||||
|
|
|
@ -63,7 +63,7 @@ class backup_forum_activity_structure_step extends backup_activity_structure_ste
|
|||
$ratings = new backup_nested_element('ratings');
|
||||
|
||||
$rating = new backup_nested_element('rating', array('id'), array(
|
||||
'scaleid', 'value', 'userid', 'timecreated', 'timemodified'));
|
||||
'component', 'ratingarea', 'scaleid', 'value', 'userid', 'timecreated', 'timemodified'));
|
||||
|
||||
$subscriptions = new backup_nested_element('subscriptions');
|
||||
|
||||
|
@ -125,8 +125,10 @@ class backup_forum_activity_structure_step extends backup_activity_structure_ste
|
|||
|
||||
$track->set_source_table('forum_track_prefs', array('forumid' => backup::VAR_PARENTID));
|
||||
|
||||
$rating->set_source_table('rating', array('contextid' => backup::VAR_CONTEXTID,
|
||||
'itemid' => backup::VAR_PARENTID));
|
||||
$rating->set_source_table('rating', array('contextid' => backup::VAR_CONTEXTID,
|
||||
'component' => 'mod_forum',
|
||||
'ratingarea' => 'post',
|
||||
'itemid' => backup::VAR_PARENTID));
|
||||
$rating->set_source_alias('rating', 'value');
|
||||
}
|
||||
|
||||
|
|
|
@ -126,6 +126,14 @@ class restore_forum_activity_structure_step extends restore_activity_structure_s
|
|||
$data->timecreated = $this->apply_date_offset($data->timecreated);
|
||||
$data->timemodified = $this->apply_date_offset($data->timemodified);
|
||||
|
||||
// We need to check that component and ratingarea are both set here.
|
||||
if (empty($data->component)) {
|
||||
$data->component = 'mod_forum';
|
||||
}
|
||||
if (empty($data->ratingarea)) {
|
||||
$data->ratingarea = 'post';
|
||||
}
|
||||
|
||||
$newitemid = $DB->insert_record('rating', $data);
|
||||
}
|
||||
|
||||
|
|
|
@ -315,6 +315,28 @@ function xmldb_forum_upgrade($oldversion) {
|
|||
upgrade_mod_savepoint(true, 2010091900, 'forum');
|
||||
}
|
||||
|
||||
if ($oldversion < 2011052300) {
|
||||
// rating.component and rating.ratingarea have now been added as mandatory fields.
|
||||
// Presently you can only rate forum posts so component = 'mod_forum' and ratingarea = 'post'
|
||||
// for all ratings with a forum context.
|
||||
// We want to update all ratings that belong to a forum context and don't already have a
|
||||
// component set.
|
||||
// This could take a while reset upgrade timeout to 5 min
|
||||
upgrade_set_timeout(60 * 20);
|
||||
$sql = "UPDATE {rating}
|
||||
SET component = 'mod_forum', ratingarea = 'post'
|
||||
WHERE contextid IN (
|
||||
SELECT ctx.id
|
||||
FROM {context} ctx
|
||||
JOIN {course_modules} cm ON cm.id = ctx.instanceid
|
||||
JOIN {modules} m ON m.id = cm.module
|
||||
WHERE ctx.contextlevel = 70 AND
|
||||
m.name = 'forum'
|
||||
) AND component = 'unknown'";
|
||||
$DB->execute($sql);
|
||||
|
||||
upgrade_mod_savepoint(true, 2011052300, 'forum');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1131,7 +1131,16 @@ function forum_user_outline($course, $user, $mod, $forum) {
|
|||
} else if ($grade) {
|
||||
$result = new stdClass();
|
||||
$result->info = get_string('grade') . ': ' . $grade->str_long_grade;
|
||||
$result->time = $grade->dategraded;
|
||||
|
||||
//datesubmitted == time created. dategraded == time modified or time overridden
|
||||
//if grade was last modified by the user themselves use date graded. Otherwise use date submitted
|
||||
//TODO: move this copied & pasted code somewhere in the grades API. See MDL-26704
|
||||
if ($grade->usermodified == $user->id || empty($grade->datesubmitted)) {
|
||||
$result->time = $grade->dategraded;
|
||||
} else {
|
||||
$result->time = $grade->datesubmitted;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -1436,25 +1445,25 @@ function forum_print_recent_activity($course, $viewfullnames, $timestart) {
|
|||
* @param int $userid optional user id, 0 means all users
|
||||
* @return array array of grades, false if none
|
||||
*/
|
||||
function forum_get_user_grades($forum, $userid=0) {
|
||||
function forum_get_user_grades($forum, $userid = 0) {
|
||||
global $CFG;
|
||||
|
||||
require_once($CFG->dirroot.'/rating/lib.php');
|
||||
$rm = new rating_manager();
|
||||
|
||||
$ratingoptions = new stdclass();
|
||||
$ratingoptions = new stdClass;
|
||||
$ratingoptions->component = 'mod_forum';
|
||||
$ratingoptions->ratingarea = 'post';
|
||||
|
||||
//need these to work backwards to get a context id. Is there a better way to get contextid from a module instance?
|
||||
$ratingoptions->modulename = 'forum';
|
||||
$ratingoptions->moduleid = $forum->id;
|
||||
//$ratingoptions->cmidnumber = $forum->cmidnumber;
|
||||
|
||||
$ratingoptions->userid = $userid;
|
||||
$ratingoptions->aggregationmethod = $forum->assessed;
|
||||
$ratingoptions->scaleid = $forum->scale;
|
||||
$ratingoptions->itemtable = 'forum_posts';
|
||||
$ratingoptions->itemtableusercolumn = 'userid';
|
||||
|
||||
$rm = new rating_manager();
|
||||
return $rm->get_user_grades($ratingoptions);
|
||||
}
|
||||
|
||||
|
@ -1577,8 +1586,8 @@ function forum_grade_item_delete($forum) {
|
|||
* Returns the users with data in one forum
|
||||
* (users with records in forum_subscriptions, forum_posts, students)
|
||||
*
|
||||
* @global object
|
||||
* @global object
|
||||
* @todo: deprecated - to be deleted in 2.2
|
||||
*
|
||||
* @param int $forumid
|
||||
* @return mixed array or false if none
|
||||
*/
|
||||
|
@ -1586,31 +1595,35 @@ function forum_get_participants($forumid) {
|
|||
|
||||
global $CFG, $DB;
|
||||
|
||||
$params = array('forumid' => $forumid);
|
||||
|
||||
//Get students from forum_subscriptions
|
||||
$st_subscriptions = $DB->get_records_sql("SELECT DISTINCT u.id, u.id
|
||||
FROM {user} u,
|
||||
{forum_subscriptions} s
|
||||
WHERE s.forum = ? AND
|
||||
u.id = s.userid", array($forumid));
|
||||
$sql = "SELECT DISTINCT u.id, u.id
|
||||
FROM {user} u,
|
||||
{forum_subscriptions} s
|
||||
WHERE s.forum = :forumid AND
|
||||
u.id = s.userid";
|
||||
$st_subscriptions = $DB->get_records_sql($sql, $params);
|
||||
|
||||
//Get students from forum_posts
|
||||
$st_posts = $DB->get_records_sql("SELECT DISTINCT u.id, u.id
|
||||
FROM {user} u,
|
||||
{forum_discussions} d,
|
||||
{forum_posts} p
|
||||
WHERE d.forum = ? AND
|
||||
p.discussion = d.id AND
|
||||
u.id = p.userid", array($forumid));
|
||||
$sql = "SELECT DISTINCT u.id, u.id
|
||||
FROM {user} u,
|
||||
{forum_discussions} d,
|
||||
{forum_posts} p
|
||||
WHERE d.forum = :forumid AND
|
||||
p.discussion = d.id AND
|
||||
u.id = p.userid";
|
||||
$st_posts = $DB->get_records_sql($sql, $params);
|
||||
|
||||
//Get students from the ratings table
|
||||
$st_ratings = $DB->get_records_sql("SELECT DISTINCT u.id, u.id
|
||||
FROM {user} u,
|
||||
{forum_discussions} d,
|
||||
{forum_posts} p,
|
||||
{ratings} r
|
||||
WHERE d.forum = ? AND
|
||||
p.discussion = d.id AND
|
||||
r.post = p.id AND
|
||||
u.id = r.userid", array($forumid));
|
||||
$sql = "SELECT DISTINCT r.userid, r.userid AS id
|
||||
FROM {forum_discussions} d
|
||||
JOIN {forum_posts} p ON p.discussion = d.id
|
||||
JOIN {rating} r on r.itemid = p.id
|
||||
WHERE d.forum = :forumid AND
|
||||
r.component = 'mod_forum' AND
|
||||
r.ratingarea = 'post'";
|
||||
$st_ratings = $DB->get_records_sql($sql, $params);
|
||||
|
||||
//Add st_posts to st_subscriptions
|
||||
if ($st_posts) {
|
||||
|
@ -2041,29 +2054,29 @@ function forum_search_posts($searchterms, $courseid=0, $limitfrom=0, $limitnum=5
|
|||
/**
|
||||
* Returns a list of ratings for a particular post - sorted.
|
||||
*
|
||||
* @global object
|
||||
* @global object
|
||||
* TODO: Check if this function is actually used anywhere.
|
||||
* Up until the fix for MDL-27471 this function wasn't even returning.
|
||||
*
|
||||
* @param stdClass $context
|
||||
* @param int $postid
|
||||
* @param string $sort
|
||||
* @return array Array of ratings or false
|
||||
*/
|
||||
function forum_get_ratings($context, $postid, $sort="u.firstname ASC") {
|
||||
global $PAGE;
|
||||
|
||||
$options = new stdclass();
|
||||
$options->context = $PAGE->context;
|
||||
function forum_get_ratings($context, $postid, $sort = "u.firstname ASC") {
|
||||
$options = new stdClass;
|
||||
$options->context = $context;
|
||||
$options->component = 'mod_forum';
|
||||
$options->ratingarea = 'post';
|
||||
$options->itemid = $postid;
|
||||
$options->sort = "ORDER BY $sort";
|
||||
|
||||
$rm = new rating_manager();
|
||||
$rm->get_all_ratings_for_item($options);
|
||||
return $rm->get_all_ratings_for_item($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all new posts that have not been mailed yet
|
||||
*
|
||||
* @global object
|
||||
* @global object
|
||||
* @param int $starttime posts created after this time
|
||||
* @param int $endtime posts created before this
|
||||
* @param int $now used for timed discussions only
|
||||
|
@ -2447,29 +2460,35 @@ function forum_count_discussions($forum, $cm, $course) {
|
|||
/**
|
||||
* How many posts by other users are unrated by a given user in the given discussion?
|
||||
*
|
||||
* @global object
|
||||
* @global object
|
||||
* TODO: Is this function still used anywhere?
|
||||
*
|
||||
* @param int $discussionid
|
||||
* @param int $userid
|
||||
* @return mixed
|
||||
*/
|
||||
function forum_count_unrated_posts($discussionid, $userid) {
|
||||
global $CFG, $DB;
|
||||
if ($posts = $DB->get_record_sql("SELECT count(*) as num
|
||||
FROM {forum_posts}
|
||||
WHERE parent > 0
|
||||
AND discussion = ?
|
||||
AND userid <> ? ", array($discussionid, $userid))) {
|
||||
|
||||
if ($rated = $DB->get_record_sql("SELECT count(*) as num
|
||||
FROM {forum_posts} p,
|
||||
{rating} r
|
||||
WHERE p.discussion = ?
|
||||
AND p.id = r.itemid
|
||||
AND r.userid = ?", array($discussionid, $userid))) {
|
||||
$difference = $posts->num - $rated->num;
|
||||
if ($difference > 0) {
|
||||
return $difference;
|
||||
$sql = "SELECT COUNT(*) as num
|
||||
FROM {forum_posts}
|
||||
WHERE parent > 0
|
||||
AND discussion = :discussionid
|
||||
AND userid <> :userid";
|
||||
$params = array('discussionid' => $discussionid, 'userid' => $userid);
|
||||
$posts = $DB->get_record_sql($sql, $params);
|
||||
if ($posts) {
|
||||
$sql = "SELECT count(*) as num
|
||||
FROM {forum_posts} p,
|
||||
{rating} r
|
||||
WHERE p.discussion = :discussionid AND
|
||||
p.id = r.itemid AND
|
||||
r.userid = userid AND
|
||||
r.component = 'mod_forum' AND
|
||||
r.ratingarea = 'post'";
|
||||
$rated = $DB->get_record_sql($sql, $params);
|
||||
if ($rated) {
|
||||
if ($posts->num > $rated->num) {
|
||||
return $posts->num - $rated->num;
|
||||
} else {
|
||||
return 0; // Just in case there was a counting error
|
||||
}
|
||||
|
@ -3442,24 +3461,31 @@ function forum_print_post($post, $discussion, $forum, &$cm, $course, $ownpost=fa
|
|||
|
||||
/**
|
||||
* Return rating related permissions
|
||||
*
|
||||
* @param string $options the context id
|
||||
* @return array an associative array of the user's rating permissions
|
||||
*/
|
||||
function forum_rating_permissions($contextid) {
|
||||
$context = get_context_instance_by_id($contextid);
|
||||
|
||||
if (!$context) {
|
||||
print_error('invalidcontext');
|
||||
function forum_rating_permissions($contextid, $component, $ratingarea) {
|
||||
$context = get_context_instance_by_id($contextid, MUST_EXIST);
|
||||
if ($component != 'mod_forum' || $ratingarea != 'post') {
|
||||
// We don't know about this component/ratingarea so just return null to get the
|
||||
// default restrictive permissions.
|
||||
return null;
|
||||
} else {
|
||||
return array('view'=>has_capability('mod/forum:viewrating',$context), 'viewany'=>has_capability('mod/forum:viewanyrating',$context), 'viewall'=>has_capability('mod/forum:viewallratings',$context), 'rate'=>has_capability('mod/forum:rate',$context));
|
||||
}
|
||||
return array(
|
||||
'view' => has_capability('mod/forum:viewrating', $context),
|
||||
'viewany' => has_capability('mod/forum:viewanyrating', $context),
|
||||
'viewall' => has_capability('mod/forum:viewallratings', $context),
|
||||
'rate' => has_capability('mod/forum:rate', $context)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a submitted rating
|
||||
* @param array $params submitted data
|
||||
* context => object the context in which the rated items exists [required]
|
||||
* component => The component for this module - should always be mod_forum [required]
|
||||
* ratingarea => object the context in which the rated items exists [required]
|
||||
* itemid => int the ID of the object being rated [required]
|
||||
* scaleid => int the scale from which the user can select a rating. Used for bounds checking. [required]
|
||||
* rating => int the submitted rating [required]
|
||||
|
@ -3470,81 +3496,84 @@ function forum_rating_permissions($contextid) {
|
|||
function forum_rating_validate($params) {
|
||||
global $DB, $USER;
|
||||
|
||||
if (!array_key_exists('itemid', $params) || !array_key_exists('context', $params) || !array_key_exists('rateduserid', $params)) {
|
||||
throw new rating_exception('missingparameter');
|
||||
// Check the component is mod_forum
|
||||
if ($params['component'] != 'mod_forum') {
|
||||
throw new rating_exception('invalidcomponent');
|
||||
}
|
||||
|
||||
$forumsql = "SELECT f.id as fid, f.course, d.id as did, p.userid as userid, p.created, f.assesstimestart, f.assesstimefinish, d.groupid
|
||||
FROM {forum_posts} p
|
||||
JOIN {forum_discussions} d ON p.discussion = d.id
|
||||
JOIN {forum} f ON d.forum = f.id
|
||||
WHERE p.id = :itemid";
|
||||
$forumparams = array('itemid'=>$params['itemid']);
|
||||
if (!$info = $DB->get_record_sql($forumsql, $forumparams)) {
|
||||
//item doesn't exist
|
||||
throw new rating_exception('invaliditemid');
|
||||
// Check the ratingarea is post (the only rating area in forum)
|
||||
if ($params['ratingarea'] != 'post') {
|
||||
throw new rating_exception('invalidratingarea');
|
||||
}
|
||||
|
||||
if ($info->userid == $USER->id) {
|
||||
//user is attempting to rate their own post
|
||||
// Check the rateduserid is not the current user .. you can't rate your own posts
|
||||
if ($params['rateduserid'] == $USER->id) {
|
||||
throw new rating_exception('nopermissiontorate');
|
||||
}
|
||||
|
||||
if ($params['rateduserid'] != $info->userid) {
|
||||
//supplied user ID doesnt match the user ID from the database
|
||||
throw new rating_exception('invaliduserid');
|
||||
// Fetch all the related records ... we need to do this anyway to call forum_user_can_see_post
|
||||
$post = $DB->get_record('forum_posts', array('id' => $params['itemid'], 'userid' => $params['rateduserid']), '*', MUST_EXIST);
|
||||
$discussion = $DB->get_record('forum_discussions', array('id' => $post->discussion), '*', MUST_EXIST);
|
||||
$forum = $DB->get_record('forum', array('id' => $discussion->forum), '*', MUST_EXIST);
|
||||
$course = $DB->get_record('course', array('id' => $forum->course), '*', MUST_EXIST);
|
||||
$cm = get_coursemodule_from_instance('forum', $forum->id, $course->id , false, MUST_EXIST);
|
||||
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
|
||||
|
||||
// Make sure the context provided is the context of the forum
|
||||
if ($context->id != $params['context']->id) {
|
||||
throw new rating_exception('invalidcontext');
|
||||
}
|
||||
|
||||
//check the item we're rating was created in the assessable time window
|
||||
if (!empty($info->assesstimestart) && !empty($info->assesstimefinish)) {
|
||||
if ($info->timecreated < $info->assesstimestart || $info->timecreated > $info->assesstimefinish) {
|
||||
if ($forum->scale != $params['scaleid']) {
|
||||
//the scale being submitted doesnt match the one in the database
|
||||
throw new rating_exception('invalidscaleid');
|
||||
}
|
||||
|
||||
// check the item we're rating was created in the assessable time window
|
||||
if (!empty($forum->assesstimestart) && !empty($forum->assesstimefinish)) {
|
||||
if ($post->created < $forum->assesstimestart || $post->created > $forum->assesstimefinish) {
|
||||
throw new rating_exception('notavailable');
|
||||
}
|
||||
}
|
||||
|
||||
$forumid = $info->fid;
|
||||
$discussionid = $info->did;
|
||||
$groupid = $info->groupid;
|
||||
$courseid = $info->course;
|
||||
//check that the submitted rating is valid for the scale
|
||||
|
||||
$cm = get_coursemodule_from_instance('forum', $forumid);
|
||||
if (empty($cm)) {
|
||||
throw new rating_exception('unknowncontext');
|
||||
// lower limit
|
||||
if ($params['rating'] < 0 && $params['rating'] != RATING_UNSET_RATING) {
|
||||
throw new rating_exception('invalidnum');
|
||||
}
|
||||
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
|
||||
|
||||
//if the supplied context doesnt match the item's context
|
||||
if (empty($context) || $context->id != $params['context']->id) {
|
||||
throw new rating_exception('invalidcontext');
|
||||
// upper limit
|
||||
if ($forum->scale < 0) {
|
||||
//its a custom scale
|
||||
$scalerecord = $DB->get_record('scale', array('id' => -$forum->scale));
|
||||
if ($scalerecord) {
|
||||
$scalearray = explode(',', $scalerecord->scale);
|
||||
if ($params['rating'] > count($scalearray)) {
|
||||
throw new rating_exception('invalidnum');
|
||||
}
|
||||
} else {
|
||||
throw new rating_exception('invalidscaleid');
|
||||
}
|
||||
} else if ($params['rating'] > $forum->scale) {
|
||||
//if its numeric and submitted rating is above maximum
|
||||
throw new rating_exception('invalidnum');
|
||||
}
|
||||
|
||||
// Make sure groups allow this user to see the item they're rating
|
||||
$course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
|
||||
if ($groupid > 0 and $groupmode = groups_get_activity_groupmode($cm, $course)) { // Groups are being used
|
||||
if (!groups_group_exists($groupid)) { // Can't find group
|
||||
if ($discussion->groupid > 0 and $groupmode = groups_get_activity_groupmode($cm, $course)) { // Groups are being used
|
||||
if (!groups_group_exists($discussion->groupid)) { // Can't find group
|
||||
throw new rating_exception('cannotfindgroup');//something is wrong
|
||||
}
|
||||
|
||||
if (!groups_is_member($groupid) and !has_capability('moodle/site:accessallgroups', $context)) {
|
||||
if (!groups_is_member($discussion->groupid) and !has_capability('moodle/site:accessallgroups', $context)) {
|
||||
// do not allow rating of posts from other groups when in SEPARATEGROUPS or VISIBLEGROUPS
|
||||
throw new rating_exception('notmemberofgroup');
|
||||
}
|
||||
}
|
||||
|
||||
//need to load the full objects here as ajax scripts don't like
|
||||
//the debugging messages produced by forum_user_can_see_post() if you just supply IDs
|
||||
if (!$forum = $DB->get_record('forum',array('id'=>$forumid))) {
|
||||
throw new rating_exception('invalidrecordunknown');
|
||||
}
|
||||
if (!$post = $DB->get_record('forum_posts',array('id'=>$params['itemid']))) {
|
||||
throw new rating_exception('invalidrecordunknown');
|
||||
}
|
||||
if (!$discussion = $DB->get_record('forum_discussions',array('id'=>$discussionid))) {
|
||||
throw new rating_exception('invalidrecordunknown');
|
||||
}
|
||||
|
||||
//perform some final capability checks
|
||||
if( !forum_user_can_see_post($forum, $discussion, $post, $USER, $cm)) {
|
||||
// perform some final capability checks
|
||||
if (!forum_user_can_see_post($forum, $discussion, $post, $USER, $cm)) {
|
||||
throw new rating_exception('nopermissiontorate');
|
||||
}
|
||||
|
||||
|
@ -4314,8 +4343,10 @@ function forum_delete_post($post, $children, $course, $cm, $forum, $skipcompleti
|
|||
|
||||
//delete ratings
|
||||
require_once($CFG->dirroot.'/rating/lib.php');
|
||||
$delopt = new stdclass();
|
||||
$delopt = new stdClass;
|
||||
$delopt->contextid = $context->id;
|
||||
$delopt->component = 'mod_forum';
|
||||
$delopt->ratingarea = 'post';
|
||||
$delopt->itemid = $post->id;
|
||||
$rm = new rating_manager();
|
||||
$rm->delete_ratings($delopt);
|
||||
|
@ -5350,32 +5381,29 @@ function forum_print_latest_discussions($course, $forum, $maxdiscussions=-1, $di
|
|||
|
||||
|
||||
/**
|
||||
* @global object
|
||||
* @global object
|
||||
* Prints a forum discussion
|
||||
*
|
||||
* @uses CONTEXT_MODULE
|
||||
* @uses FORUM_MODE_FLATNEWEST
|
||||
* @uses FORUM_MODE_FLATOLDEST
|
||||
* @uses FORUM_MODE_THREADED
|
||||
* @uses FORUM_MODE_NESTED
|
||||
* @param object $course
|
||||
* @param object $cm
|
||||
* @param object $forum
|
||||
* @param object $discussion
|
||||
* @param object $post
|
||||
* @param object $mode
|
||||
* @param stdClass $course
|
||||
* @param stdClass $cm
|
||||
* @param stdClass $forum
|
||||
* @param stdClass $discussion
|
||||
* @param stdClass $post
|
||||
* @param int $mode
|
||||
* @param mixed $canreply
|
||||
* @param bool $cancreate
|
||||
* @param bool $canrate
|
||||
*/
|
||||
function forum_print_discussion($course, $cm, $forum, $discussion, $post, $mode, $canreply=NULL, $canrate=false) {
|
||||
global $USER, $CFG;
|
||||
|
||||
global $USER, $CFG, $DB, $PAGE, $OUTPUT;
|
||||
require_once($CFG->dirroot.'/rating/lib.php');
|
||||
|
||||
if (isloggedin()) {
|
||||
$ownpost = ($USER->id == $post->userid);
|
||||
} else {
|
||||
$ownpost = false;
|
||||
}
|
||||
$ownpost = (isloggedin() && $USER->id == $post->userid);
|
||||
|
||||
$modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
|
||||
if ($canreply === NULL) {
|
||||
$reply = forum_user_can_post($forum, $discussion, $USER, $cm, $course, $modcontext);
|
||||
|
@ -5384,7 +5412,7 @@ function forum_print_discussion($course, $cm, $forum, $discussion, $post, $mode,
|
|||
}
|
||||
|
||||
// $cm holds general cache for forum functions
|
||||
$cm->cache = new stdClass();
|
||||
$cm->cache = new stdClass;
|
||||
$cm->cache->groups = groups_get_all_groups($course->id, 0, $cm->groupingid);
|
||||
$cm->cache->usersgroups = array();
|
||||
|
||||
|
@ -5417,10 +5445,11 @@ function forum_print_discussion($course, $cm, $forum, $discussion, $post, $mode,
|
|||
}
|
||||
|
||||
//load ratings
|
||||
if ($forum->assessed!=RATING_AGGREGATE_NONE) {
|
||||
$ratingoptions = new stdclass();
|
||||
if ($forum->assessed != RATING_AGGREGATE_NONE) {
|
||||
$ratingoptions = new stdClass;
|
||||
$ratingoptions->context = $modcontext;
|
||||
$ratingoptions->component = 'mod_forum';
|
||||
$ratingoptions->ratingarea = 'post';
|
||||
$ratingoptions->items = $posts;
|
||||
$ratingoptions->aggregate = $forum->assessed;//the aggregation method
|
||||
$ratingoptions->scaleid = $forum->scale;
|
||||
|
@ -7094,10 +7123,14 @@ function forum_reset_userdata($data) {
|
|||
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();
|
||||
$rm = new rating_manager();;
|
||||
$ratingdeloptions = new stdClass;
|
||||
$ratingdeloptions->component = 'mod_forum';
|
||||
$ratingdeloptions->ratingarea = 'post';
|
||||
}
|
||||
|
||||
if ($removeposts) {
|
||||
|
@ -7106,7 +7139,6 @@ function forum_reset_userdata($data) {
|
|||
|
||||
// now get rid of all attachments
|
||||
$fs = get_file_storage();
|
||||
$ratingdeloptions = new stdclass();
|
||||
if ($forums) {
|
||||
foreach ($forums as $forumid=>$unused) {
|
||||
if (!$cm = get_coursemodule_from_instance('forum', $forumid)) {
|
||||
|
@ -7154,8 +7186,6 @@ function forum_reset_userdata($data) {
|
|||
|
||||
// remove all ratings in this course's forums
|
||||
if (!empty($data->reset_forum_ratings)) {
|
||||
$ratingdeloptions = new stdclass();
|
||||
|
||||
if ($forums) {
|
||||
foreach ($forums as $forumid=>$unused) {
|
||||
if (!$cm = get_coursemodule_from_instance('forum', $forumid)) {
|
||||
|
|
|
@ -118,7 +118,8 @@ if ($course->id == SITEID) {
|
|||
}
|
||||
|
||||
// Get the posts.
|
||||
if ($posts = forum_search_posts($searchterms, $searchcourse, $page*$perpage, $perpage, $totalcount, $extrasql)) {
|
||||
$posts = forum_search_posts($searchterms, $searchcourse, $page*$perpage, $perpage, $totalcount, $extrasql);
|
||||
if ($posts) {
|
||||
|
||||
require_once($CFG->dirroot.'/rating/lib.php');
|
||||
|
||||
|
@ -127,15 +128,14 @@ if ($posts = forum_search_posts($searchterms, $searchcourse, $page*$perpage, $pe
|
|||
|
||||
$discussions = array();
|
||||
$forums = array();
|
||||
$cms = array();
|
||||
|
||||
//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->plugintype = 'mod';
|
||||
$ratingoptions->pluginname = 'forum';
|
||||
$ratingoptions = new stdClass;
|
||||
$ratingoptions->component = 'mod_forum';
|
||||
$ratingoptions->ratingarea = 'post';
|
||||
|
||||
foreach ($posts as $post) {
|
||||
|
||||
|
@ -149,66 +149,57 @@ if ($posts = forum_search_posts($searchterms, $searchcourse, $page*$perpage, $pe
|
|||
}
|
||||
|
||||
if (!isset($forums[$discussion->forum])) {
|
||||
if (! $forum = $DB->get_record('forum', array('id' => $discussion->forum))) {
|
||||
print_error('invalidforumid', 'forum');
|
||||
}
|
||||
//hold onto forum cm and context for when we load ratings
|
||||
if ($forumcm = get_coursemodule_from_instance('forum', $forum->id)) {
|
||||
$forum->cm = $forumcm;
|
||||
$forumcontext = get_context_instance(CONTEXT_MODULE, $forum->cm->id);
|
||||
$forum->context = $forumcontext;
|
||||
}
|
||||
$forum = $DB->get_record('forum', array('id' => $discussion->forum), '*', MUST_EXIST);
|
||||
$forum->cm = get_coursemodule_from_instance('forum', $forum->id, 0, false, MUST_EXIST);
|
||||
$forum->context = get_context_instance(CONTEXT_MODULE, $forum->cm->id);
|
||||
$forums[$discussion->forum] = $forum;
|
||||
} else {
|
||||
$forum = $forums[$discussion->forum];
|
||||
}
|
||||
|
||||
//load ratings
|
||||
if ($forum->assessed!=RATING_AGGREGATE_NONE) {
|
||||
$forumurl = new moodle_url('/mod/forum/view.php', array('id' => $forum->cm->id));
|
||||
$discussionurl = new moodle_url('/mod/forum/discuss.php', array('d' => $discussion->id));
|
||||
|
||||
// load ratings
|
||||
if ($forum->assessed != RATING_AGGREGATE_NONE) {
|
||||
$ratingoptions->context = $forum->context;
|
||||
$ratingoptions->component = 'mod_forum';
|
||||
$ratingoptions->items = array($post);
|
||||
$ratingoptions->aggregate = $forum->assessed;//the aggregation method
|
||||
$ratingoptions->scaleid = $forum->scale;
|
||||
$ratingoptions->userid = $user->id;
|
||||
if ($forum->type == 'single' or !$discussion->id) {
|
||||
$ratingoptions->returnurl = "$CFG->wwwroot/mod/forum/view.php?id={$forum->cm->id}";
|
||||
} else {
|
||||
$ratingoptions->returnurl = "$CFG->wwwroot/mod/forum/discuss.php?d=$discussion->id";
|
||||
}
|
||||
$ratingoptions->assesstimestart = $forum->assesstimestart;
|
||||
$ratingoptions->assesstimefinish = $forum->assesstimefinish;
|
||||
if ($forum->type == 'single' or !$discussion->id) {
|
||||
$ratingoptions->returnurl = $forumurl;
|
||||
} else {
|
||||
$ratingoptions->returnurl = $discussionurl;
|
||||
}
|
||||
|
||||
$updatedpost = $rm->get_ratings($ratingoptions);
|
||||
//updating the array this way because we're iterating over a collection and updating them one by one
|
||||
$posts[$updatedpost[0]->id] = $updatedpost[0];
|
||||
}
|
||||
|
||||
if (!isset($cms[$forum->id])) {
|
||||
$cm = get_coursemodule_from_instance('forum', $forum->id, 0, false, MUST_EXIST);
|
||||
$cms[$forum->id] = $cm;
|
||||
unset($cm); // do not use cm directly, it would break caching
|
||||
$fullsubjects = array();
|
||||
if ($course->id == SITEID && has_capability('moodle/site:config', $syscontext)) {
|
||||
$postcoursename = $DB->get_field('course', 'shortname', array('id'=>$forum->course));
|
||||
$courseurl = new moodle_url('/course/view.php', array('id' => $forum->course));
|
||||
$fullsubjects[] = html_writer::link($courseurl, $postcoursename);
|
||||
}
|
||||
|
||||
$fullsubject = "<a href=\"view.php?f=$forum->id\">".format_string($forum->name,true)."</a>";
|
||||
$fullsubjects[] = html_writer::link($forumurl, format_string($forum->name, true));
|
||||
if ($forum->type != 'single') {
|
||||
$fullsubject .= " -> <a href=\"discuss.php?d=$discussion->id\">".format_string($discussion->name,true)."</a>";
|
||||
$fullsubjects[] .= html_writer::link($discussionurl, format_string($discussion->name, true));
|
||||
if ($post->parent != 0) {
|
||||
$fullsubject .= " -> <a href=\"discuss.php?d=$post->discussion&parent=$post->id\">".format_string($post->subject,true)."</a>";
|
||||
$parenturl = new moodle_url('/mod/forum/discuss.php', array('d' => $post->discussion, 'parent' => $post->id));
|
||||
$fullsubjects[] .= html_writer::link($parenturl, format_string($post->subject, true));
|
||||
}
|
||||
}
|
||||
|
||||
if ($course->id == SITEID && has_capability('moodle/site:config', $syscontext)) {
|
||||
$postcoursename = $DB->get_field('course', 'shortname', array('id'=>$forum->course));
|
||||
$fullsubject = '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$forum->course.'">'.$postcoursename.'</a> -> '. $fullsubject;
|
||||
}
|
||||
$post->subject = join(' -> ', $fullsubjects);
|
||||
$discussionurl->set_anchor('p'.$post->id);
|
||||
$fulllink = html_writer::link($discussionurl, get_string("postincontext", "forum"));
|
||||
|
||||
$post->subject = $fullsubject;
|
||||
|
||||
$fulllink = "<a href=\"discuss.php?d=$post->discussion#p$post->id\">".
|
||||
get_string("postincontext", "forum")."</a>";
|
||||
|
||||
forum_print_post($post, $discussion, $forum, $cms[$forum->id], $course, false, false, false, $fulllink);
|
||||
forum_print_post($post, $discussion, $forum, $forum->cm, $course, false, false, false, $fulllink);
|
||||
echo "<br />";
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$module->version = 2010111500;
|
||||
$module->requires = 2010111002; // Requires this Moodle version
|
||||
$module->cron = 60;
|
||||
|
||||
|
||||
$module->version = 2011052300;
|
||||
$module->requires = 2011052300; // Requires this Moodle version
|
||||
$module->cron = 60;
|
|
@ -102,10 +102,6 @@
|
|||
$completion->set_module_viewed($cm);
|
||||
|
||||
/// Print header.
|
||||
/// Add ajax-related libs for ratings if required MDL-20119
|
||||
$PAGE->requires->yui2_lib('event');
|
||||
$PAGE->requires->yui2_lib('connection');
|
||||
$PAGE->requires->yui2_lib('json');
|
||||
|
||||
$PAGE->set_title(format_string($forum->name));
|
||||
$PAGE->add_body_class('forumtype-'.$forum->type);
|
||||
|
|
|
@ -61,7 +61,7 @@ class backup_glossary_activity_structure_step extends backup_activity_structure_
|
|||
$ratings = new backup_nested_element('ratings');
|
||||
|
||||
$rating = new backup_nested_element('rating', array('id'), array(
|
||||
'scaleid', 'value', 'userid', 'timecreated', 'timemodified'));
|
||||
'component', 'ratingarea', 'scaleid', 'value', 'userid', 'timecreated', 'timemodified'));
|
||||
|
||||
$categories = new backup_nested_element('categories');
|
||||
|
||||
|
@ -101,8 +101,10 @@ class backup_glossary_activity_structure_step extends backup_activity_structure_
|
|||
$alias->set_source_table('glossary_alias', array('entryid' => backup::VAR_PARENTID));
|
||||
$alias->set_source_alias('alias', 'alias_text');
|
||||
|
||||
$rating->set_source_table('rating', array('contextid' => backup::VAR_CONTEXTID,
|
||||
'itemid' => backup::VAR_PARENTID));
|
||||
$rating->set_source_table('rating', array('contextid' => backup::VAR_CONTEXTID,
|
||||
'itemid' => backup::VAR_PARENTID,
|
||||
'component' => 'mod_glossary',
|
||||
'ratingarea' => 'entry'));
|
||||
$rating->set_source_alias('rating', 'value');
|
||||
|
||||
$categoryentry->set_source_table('glossary_entries_categories', array('categoryid' => backup::VAR_PARENTID));
|
||||
|
|
|
@ -117,6 +117,15 @@ class restore_glossary_activity_structure_step extends restore_activity_structur
|
|||
$data->timecreated = $this->apply_date_offset($data->timecreated);
|
||||
$data->timemodified = $this->apply_date_offset($data->timemodified);
|
||||
|
||||
// Make sure that we have both component and ratingarea set. These were added in 2.1.
|
||||
// Prior to that all ratings were for entries so we know what to set them too.
|
||||
if (empty($data->component)) {
|
||||
$data->component = 'mod_glossary';
|
||||
}
|
||||
if (empty($data->ratingarea)) {
|
||||
$data->ratingarea = 'entry';
|
||||
}
|
||||
|
||||
$newitemid = $DB->insert_record('rating', $data);
|
||||
}
|
||||
|
||||
|
|
|
@ -326,6 +326,29 @@ function xmldb_glossary_upgrade($oldversion) {
|
|||
upgrade_mod_savepoint(true, 2010111501, 'glossary');
|
||||
}
|
||||
|
||||
if ($oldversion < 2011052300) {
|
||||
// rating.component and rating.ratingarea have now been added as mandatory fields.
|
||||
// Presently you can only rate data entries so component = 'mod_glossary' and ratingarea = 'entry'
|
||||
// for all ratings with a glossary context.
|
||||
// We want to update all ratings that belong to a glossary context and don't already have a
|
||||
// component set.
|
||||
// This could take a while reset upgrade timeout to 5 min
|
||||
upgrade_set_timeout(60 * 20);
|
||||
$sql = "UPDATE {rating}
|
||||
SET component = 'mod_glossary', ratingarea = 'entry'
|
||||
WHERE contextid IN (
|
||||
SELECT ctx.id
|
||||
FROM {context} ctx
|
||||
JOIN {course_modules} cm ON cm.id = ctx.instanceid
|
||||
JOIN {modules} m ON m.id = cm.module
|
||||
WHERE ctx.contextlevel = 70 AND
|
||||
m.name = 'glossary'
|
||||
) AND component = 'unknown'";
|
||||
$DB->execute($sql);
|
||||
|
||||
upgrade_mod_savepoint(true, 2011052300, 'glossary');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -104,8 +104,10 @@ if ($confirm and confirm_sesskey()) { // the operation was confirmed.
|
|||
|
||||
//delete glossary entry ratings
|
||||
require_once($CFG->dirroot.'/rating/lib.php');
|
||||
$delopt = new stdclass();
|
||||
$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);
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
require_once($CFG->dirroot . '/rating/lib.php');
|
||||
require_once($CFG->libdir . '/completionlib.php');
|
||||
|
||||
define("GLOSSARY_SHOW_ALL_CATEGORIES", 0);
|
||||
|
@ -243,7 +242,16 @@ function glossary_user_outline($course, $user, $mod, $glossary) {
|
|||
} else if ($grade) {
|
||||
$result = new stdClass();
|
||||
$result->info = get_string('grade') . ': ' . $grade->str_long_grade;
|
||||
$result->time = $grade->dategraded;
|
||||
|
||||
//datesubmitted == time created. dategraded == time modified or time overridden
|
||||
//if grade was last modified by the user themselves use date graded. Otherwise use date submitted
|
||||
//TODO: move this copied & pasted code somewhere in the grades API. See MDL-26704
|
||||
if ($grade->usermodified == $user->id || empty($grade->datesubmitted)) {
|
||||
$result->time = $grade->dategraded;
|
||||
} else {
|
||||
$result->time = $grade->datesubmitted;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -436,13 +444,14 @@ function glossary_get_user_grades($glossary, $userid=0) {
|
|||
global $CFG;
|
||||
|
||||
require_once($CFG->dirroot.'/rating/lib.php');
|
||||
$rm = new rating_manager();
|
||||
|
||||
$ratingoptions = new stdclass();
|
||||
$ratingoptions = new stdClass;
|
||||
|
||||
//need these to work backwards to get a context id. Is there a better way to get contextid from a module instance?
|
||||
$ratingoptions->modulename = 'glossary';
|
||||
$ratingoptions->moduleid = $glossary->id;
|
||||
$ratingoptions->component = 'mod_glossary';
|
||||
$ratingoptions->ratingarea = 'entry';
|
||||
|
||||
$ratingoptions->userid = $userid;
|
||||
$ratingoptions->aggregationmethod = $glossary->assessed;
|
||||
|
@ -450,31 +459,40 @@ function glossary_get_user_grades($glossary, $userid=0) {
|
|||
$ratingoptions->itemtable = 'glossary_entries';
|
||||
$ratingoptions->itemtableusercolumn = 'userid';
|
||||
|
||||
$rm = new rating_manager();
|
||||
return $rm->get_user_grades($ratingoptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return rating related permissions
|
||||
* @param string $options the context id
|
||||
*
|
||||
* @param int $contextid the context id
|
||||
* @param string $component The component we want to get permissions for
|
||||
* @param string $ratingarea The ratingarea that we want to get permissions for
|
||||
* @return array an associative array of the user's rating permissions
|
||||
*/
|
||||
function glossary_rating_permissions($options) {
|
||||
$contextid = $options;
|
||||
$context = get_context_instance_by_id($contextid);
|
||||
|
||||
if (!$context) {
|
||||
print_error('invalidcontext');
|
||||
function glossary_rating_permissions($contextid, $component, $ratingarea) {
|
||||
if ($component != 'mod_glossary' || $ratingarea != 'entry') {
|
||||
// We don't know about this component/ratingarea so just return null to get the
|
||||
// default restrictive permissions.
|
||||
return null;
|
||||
} else {
|
||||
return array('view'=>has_capability('mod/glossary:viewrating',$context), 'viewany'=>has_capability('mod/glossary:viewanyrating',$context), 'viewall'=>has_capability('mod/glossary:viewallratings',$context), 'rate'=>has_capability('mod/glossary:rate',$context));
|
||||
}
|
||||
$context = get_context_instance_by_id($contextid);
|
||||
return array(
|
||||
'view' => has_capability('mod/glossary:viewrating', $context),
|
||||
'viewany' => has_capability('mod/glossary:viewanyrating', $context),
|
||||
'viewall' => has_capability('mod/glossary:viewallratings', $context),
|
||||
'rate' => has_capability('mod/glossary:rate', $context)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a submitted rating
|
||||
* @param array $params submitted data
|
||||
* context => object the context in which the rated items exists [required]
|
||||
* itemid => int the ID of the object being rated
|
||||
* component => The component for this module - should always be mod_forum [required]
|
||||
* ratingarea => object the context in which the rated items exists [required]
|
||||
* itemid => int the ID of the object being rated [required]
|
||||
* scaleid => int the scale from which the user can select a rating. Used for bounds checking. [required]
|
||||
* rating => int the submitted rating
|
||||
* rateduserid => int the id of the user whose items have been rated. NOT the user who submitted the ratings. 0 to update all. [required]
|
||||
|
@ -484,28 +502,59 @@ function glossary_rating_permissions($options) {
|
|||
function glossary_rating_validate($params) {
|
||||
global $DB, $USER;
|
||||
|
||||
if (!array_key_exists('itemid', $params) || !array_key_exists('context', $params) || !array_key_exists('rateduserid', $params)) {
|
||||
throw new rating_exception('missingparameter');
|
||||
// Check the component is mod_forum
|
||||
if ($params['component'] != 'mod_glossary') {
|
||||
throw new rating_exception('invalidcomponent');
|
||||
}
|
||||
|
||||
$glossarysql = "SELECT g.id as gid, e.userid as userid, e.approved, e.timecreated, g.assesstimestart, g.assesstimefinish
|
||||
// Check the ratingarea is post (the only rating area in forum)
|
||||
if ($params['ratingarea'] != 'entry') {
|
||||
throw new rating_exception('invalidratingarea');
|
||||
}
|
||||
|
||||
// Check the rateduserid is not the current user .. you can't rate your own posts
|
||||
if ($params['rateduserid'] == $USER->id) {
|
||||
throw new rating_exception('nopermissiontorate');
|
||||
}
|
||||
|
||||
$glossarysql = "SELECT g.id as glossaryid, g.scale, g.course, e.userid as userid, e.approved, e.timecreated, g.assesstimestart, g.assesstimefinish
|
||||
FROM {glossary_entries} e
|
||||
JOIN {glossary} g ON e.glossaryid = g.id
|
||||
WHERE e.id = :itemid";
|
||||
$glossaryparams = array('itemid'=>$params['itemid']);
|
||||
if (!$info = $DB->get_record_sql($glossarysql, $glossaryparams)) {
|
||||
$glossaryparams = array('itemid' => $params['itemid']);
|
||||
$info = $DB->get_record_sql($glossarysql, $glossaryparams);
|
||||
if (!$info) {
|
||||
//item doesn't exist
|
||||
throw new rating_exception('invaliditemid');
|
||||
}
|
||||
|
||||
if ($info->userid == $USER->id) {
|
||||
//user is attempting to rate their own glossary entry
|
||||
throw new rating_exception('nopermissiontorate');
|
||||
if ($info->scale != $params['scaleid']) {
|
||||
//the scale being submitted doesnt match the one in the database
|
||||
throw new rating_exception('invalidscaleid');
|
||||
}
|
||||
|
||||
if ($params['rateduserid'] != $info->userid) {
|
||||
//supplied user ID doesnt match the user ID from the database
|
||||
throw new rating_exception('invaliduserid');
|
||||
//check that the submitted rating is valid for the scale
|
||||
|
||||
// lower limit
|
||||
if ($params['rating'] < 0 && $params['rating'] != RATING_UNSET_RATING) {
|
||||
throw new rating_exception('invalidnum');
|
||||
}
|
||||
|
||||
// upper limit
|
||||
if ($info->scale < 0) {
|
||||
//its a custom scale
|
||||
$scalerecord = $DB->get_record('scale', array('id' => -$info->scale));
|
||||
if ($scalerecord) {
|
||||
$scalearray = explode(',', $scalerecord->scale);
|
||||
if ($params['rating'] > count($scalearray)) {
|
||||
throw new rating_exception('invalidnum');
|
||||
}
|
||||
} else {
|
||||
throw new rating_exception('invalidscaleid');
|
||||
}
|
||||
} else if ($params['rating'] > $info->scale) {
|
||||
//if its numeric and submitted rating is above maximum
|
||||
throw new rating_exception('invalidnum');
|
||||
}
|
||||
|
||||
if (!$info->approved) {
|
||||
|
@ -520,16 +569,11 @@ function glossary_rating_validate($params) {
|
|||
}
|
||||
}
|
||||
|
||||
$glossaryid = $info->gid;
|
||||
$cm = get_coursemodule_from_instance('glossary', $info->glossaryid, $info->course, false, MUST_EXIST);
|
||||
$context = get_context_instance(CONTEXT_MODULE, $cm->id, MUST_EXIST);
|
||||
|
||||
$cm = get_coursemodule_from_instance('glossary', $glossaryid);
|
||||
if (empty($cm)) {
|
||||
throw new rating_exception('unknowncontext');
|
||||
}
|
||||
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
|
||||
|
||||
//if the supplied context doesnt match the item's context
|
||||
if (empty($context) || $context->id != $params['context']->id) {
|
||||
// if the supplied context doesnt match the item's context
|
||||
if ($context->id != $params['context']->id) {
|
||||
throw new rating_exception('invalidcontext');
|
||||
}
|
||||
|
||||
|
@ -647,7 +691,8 @@ function glossary_grade_item_delete($glossary) {
|
|||
* Returns the users with data in one glossary
|
||||
* (users with records in glossary_entries, students)
|
||||
*
|
||||
* @global object
|
||||
* @todo: deprecated - to be deleted in 2.2
|
||||
*
|
||||
* @param int $glossaryid
|
||||
* @return array
|
||||
*/
|
||||
|
@ -2154,31 +2199,49 @@ function glossary_full_tag($tag,$level=0,$endline=true,$content) {
|
|||
/**
|
||||
* How many unrated entries are in the given glossary for a given user?
|
||||
*
|
||||
* @global object
|
||||
* @global moodle_database $DB
|
||||
* @param int $glossaryid
|
||||
* @param int $userid
|
||||
* @return int
|
||||
*/
|
||||
function glossary_count_unrated_entries($glossaryid, $userid) {
|
||||
global $DB;
|
||||
if ($entries = $DB->get_record_sql("SELECT count('x') as num
|
||||
FROM {glossary_entries}
|
||||
WHERE glossaryid = ? AND userid <> ?", array($glossaryid, $userid))) {
|
||||
|
||||
if (!$cm = get_coursemodule_from_instance('glossary', $glossaryid)) {
|
||||
return 0;
|
||||
}
|
||||
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
|
||||
$sql = "SELECT COUNT('x') as num
|
||||
FROM {glossary_entries}
|
||||
WHERE glossaryid = :glossaryid AND
|
||||
userid <> :userid";
|
||||
$params = array('glossaryid' => $glossaryid, 'userid' => $userid);
|
||||
$entries = $DB->count_records_sql($sql, $params);
|
||||
|
||||
if ($rated = $DB->get_record_sql("SELECT count(*) as num
|
||||
FROM {glossary_entries} e, {ratings} r
|
||||
WHERE e.glossaryid = :glossaryid AND e.id = r.itemid
|
||||
AND r.userid = :userid and r.contextid = :contextid",
|
||||
array('glossaryid'=>$glossaryid, 'userid'=>$userid, 'contextid'=>$context->id))) {
|
||||
if ($entries) {
|
||||
// We need to get the contextid for the glossaryid we have been given.
|
||||
$sql = "SELECT ctx.id
|
||||
FROM {context} ctx
|
||||
JOIN {course_modules} cm ON cm.id = ctx.instanceid
|
||||
JOIN {modules} m ON m.id = cm.module
|
||||
JOIN {glossary} g ON g.id = cm.instance
|
||||
WHERE ctx.contextlevel = :contextlevel AND
|
||||
m.name = 'glossary' AND
|
||||
g.id = :glossaryid";
|
||||
$contextid = $DB->get_field_sql($sql, array('glossaryid' => $glossaryid, 'contextlevel' => CONTEXT_MODULE));
|
||||
|
||||
$difference = $entries->num - $rated->num;
|
||||
if ($difference > 0) {
|
||||
return $difference;
|
||||
// Now we need to count the ratings that this user has made
|
||||
$sql = "SELECT COUNT('x') AS num
|
||||
FROM {glossary_entries} e
|
||||
JOIN {ratings} r ON r.itemid = e.id
|
||||
WHERE e.glossaryid = :glossaryid AND
|
||||
r.userid = :userid AND
|
||||
r.component = 'mod_glossary' AND
|
||||
r.ratingarea = 'entry' AND
|
||||
r.contextid = :contextid";
|
||||
$params = array('glossaryid' => $glossaryid, 'userid' => $userid, 'contextid' => $context->id);
|
||||
$rated = $DB->count_records_sql($sql, $params);
|
||||
if ($rated) {
|
||||
// The number or enties minus the number or rated entries equals the number of unrated
|
||||
// entries
|
||||
if ($entries->num > $rated->num) {
|
||||
return $entries->num - $rated->num;
|
||||
} else {
|
||||
return 0; // Just in case there was a counting error
|
||||
}
|
||||
|
@ -2430,7 +2493,9 @@ function glossary_reset_userdata($data) {
|
|||
$fs = get_file_storage();
|
||||
|
||||
$rm = new rating_manager();
|
||||
$ratingdeloptions = new stdclass();
|
||||
$ratingdeloptions = new stdClass;
|
||||
$ratingdeloptions->component = 'mod_glossary';
|
||||
$ratingdeloptions->ratingarea = 'entry';
|
||||
|
||||
// delete entries if requested
|
||||
if (!empty($data->reset_glossary_all)
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
/// This fragment is called by moodle_needs_upgrading() and /admin/index.php
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$module->version = 2010111501;
|
||||
$module->requires = 2010080300; // Requires this Moodle version
|
||||
$module->version = 2011052300;
|
||||
$module->requires = 2011052300; // Requires this Moodle version
|
||||
$module->cron = 0; // Period for cron to check this module (secs)
|
||||
|
||||
|
||||
|
|
|
@ -394,13 +394,13 @@ if ($allentries) {
|
|||
echo $paging;
|
||||
echo '</div>';
|
||||
|
||||
|
||||
//load ratings
|
||||
require_once($CFG->dirroot.'/rating/lib.php');
|
||||
if ($glossary->assessed!=RATING_AGGREGATE_NONE) {
|
||||
$ratingoptions = new stdclass();
|
||||
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;
|
||||
|
|
|
@ -249,6 +249,8 @@ function imscp_user_complete($course, $user, $mod, $imscp) {
|
|||
/**
|
||||
* Returns the users with data in one imscp
|
||||
*
|
||||
* @todo: deprecated - to be deleted in 2.2
|
||||
*
|
||||
* @param int $imscpid
|
||||
* @return bool false
|
||||
*/
|
||||
|
|
|
@ -116,6 +116,8 @@ function label_delete_instance($id) {
|
|||
* Returns the users with data in one resource
|
||||
* (NONE, but must exist on EVERY mod !!)
|
||||
*
|
||||
* @todo: deprecated - to be deleted in 2.2
|
||||
*
|
||||
* @param int $labelid
|
||||
*/
|
||||
function label_get_participants($labelid) {
|
||||
|
|
|
@ -46,41 +46,59 @@ if ($mode !== 'display') {
|
|||
}
|
||||
$PAGE->set_url($url);
|
||||
|
||||
$attempt = new stdClass();
|
||||
$user = new stdClass();
|
||||
$attemptid = optional_param('attemptid', 0, PARAM_INT);
|
||||
|
||||
if ($attemptid > 0) {
|
||||
$attempt = $DB->get_record('lesson_attempts', array('id' => $attemptid));
|
||||
$answer = $DB->get_record('lesson_answers', array('lessonid' => $lesson->id, 'pageid' => $attempt->pageid));
|
||||
$user = $DB->get_record('user', array('id' => $attempt->userid));
|
||||
$scoreoptions = array();
|
||||
if ($lesson->custom) {
|
||||
$i = $answer->score;
|
||||
while ($i >= 0) {
|
||||
$scoreoptions[$i] = (string)$i;
|
||||
$i--;
|
||||
}
|
||||
} else {
|
||||
$scoreoptions[0] = get_string('nocredit', 'lesson');
|
||||
$scoreoptions[1] = get_string('credit', 'lesson');
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle any preprocessing before header is printed - based on $mode
|
||||
switch ($mode) {
|
||||
case 'grade':
|
||||
// Grading form - get the necessary data
|
||||
require_sesskey();
|
||||
|
||||
$attemptid = required_param('attemptid', PARAM_INT);
|
||||
|
||||
if (!$attempt = $DB->get_record('lesson_attempts', array('id' => $attemptid))) {
|
||||
if (empty($attempt)) {
|
||||
print_error('cannotfindattempt', 'lesson');
|
||||
}
|
||||
$page = $lesson->load_page($attempt->pageid);
|
||||
if (!$user = $DB->get_record('user', array('id' => $attempt->userid))) {
|
||||
if (empty($user)) {
|
||||
print_error('cannotfinduser', 'lesson');
|
||||
}
|
||||
if (!$answer = $DB->get_record('lesson_answers', array('lessonid' => $lesson->id, 'pageid' => $page->id))) {
|
||||
if (empty($answer)) {
|
||||
print_error('cannotfindanswer', 'lesson');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
require_sesskey();
|
||||
$mform = new essay_grading_form();
|
||||
|
||||
if (empty($attempt)) {
|
||||
print_error('cannotfindattempt', 'lesson');
|
||||
}
|
||||
if (empty($user)) {
|
||||
print_error('cannotfinduser', 'lesson');
|
||||
}
|
||||
|
||||
$mform = new essay_grading_form(null, array('scoreoptions'=>$scoreoptions, 'user'=>$user));
|
||||
if ($mform->is_cancelled()) {
|
||||
redirect("$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id");
|
||||
}
|
||||
if ($form = $mform->get_data()) {
|
||||
|
||||
if (optional_param('cancel', false, PARAM_RAW)) {
|
||||
redirect("$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id");
|
||||
}
|
||||
|
||||
$attemptid = required_param('attemptid', PARAM_INT);
|
||||
$score = optional_param('score', 0, PARAM_INT);
|
||||
|
||||
if (!$attempt = $DB->get_record('lesson_attempts', array('id' => $attemptid))) {
|
||||
print_error('cannotfindattempt', 'lesson');
|
||||
}
|
||||
if (!$grades = $DB->get_records('lesson_grades', array("lessonid"=>$lesson->id, "userid"=>$attempt->userid), 'completed', '*', $attempt->retry, 1)) {
|
||||
print_error('cannotfindgrade', 'lesson');
|
||||
}
|
||||
|
@ -89,7 +107,7 @@ switch ($mode) {
|
|||
$essayinfo = unserialize($attempt->useranswer);
|
||||
|
||||
$essayinfo->graded = 1;
|
||||
$essayinfo->score = $score;
|
||||
$essayinfo->score = $form->score;
|
||||
$essayinfo->response = clean_param($form->response, PARAM_RAW);
|
||||
$essayinfo->sent = 0;
|
||||
if (!$lesson->custom && $essayinfo->score == 1) {
|
||||
|
@ -368,22 +386,9 @@ switch ($mode) {
|
|||
case 'grade':
|
||||
// Grading form
|
||||
// Expects the following to be set: $attemptid, $answer, $user, $page, $attempt
|
||||
|
||||
|
||||
$essayinfo = unserialize($attempt->useranswer);
|
||||
$options = array();
|
||||
if ($lesson->custom) {
|
||||
$i = $answer->score;
|
||||
while ($i >= 0) {
|
||||
$options[$i] = (string)$i;
|
||||
$i--;
|
||||
}
|
||||
} else {
|
||||
$options[0] = get_string('nocredit', 'lesson');
|
||||
$options[1] = get_string('credit', 'lesson');
|
||||
}
|
||||
$mform = new essay_grading_form(null, array('scoreoptions'=>$options, 'user'=>$user));
|
||||
|
||||
$mform = new essay_grading_form(null, array('scoreoptions'=>$scoreoptions, 'user'=>$user));
|
||||
$data = new stdClass;
|
||||
$data->id = $cm->id;
|
||||
$data->attemptid = $attemptid;
|
||||
|
|
|
@ -166,8 +166,15 @@ function lesson_user_outline($course, $user, $mod, $lesson) {
|
|||
} else {
|
||||
$grade = reset($grades->items[0]->grades);
|
||||
$return->info = get_string("grade") . ': ' . $grade->str_long_grade;
|
||||
$return->time = $grade->dategraded;
|
||||
$return->info = get_string("no")." ".get_string("attempts", "lesson");
|
||||
|
||||
//datesubmitted == time created. dategraded == time modified or time overridden
|
||||
//if grade was last modified by the user themselves use date graded. Otherwise use date submitted
|
||||
//TODO: move this copied & pasted code somewhere in the grades API. See MDL-26704
|
||||
if ($grade->usermodified == $user->id || empty($grade->datesubmitted)) {
|
||||
$result->time = $grade->dategraded;
|
||||
} else {
|
||||
$result->time = $grade->datesubmitted;
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
@ -521,8 +528,8 @@ function lesson_grade_item_delete($lesson) {
|
|||
* for a given instance of lesson. Must include every user involved
|
||||
* in the instance, independent of his role (student, teacher, admin...)
|
||||
*
|
||||
* @global stdClass
|
||||
* @global object
|
||||
* @todo: deprecated - to be deleted in 2.2
|
||||
*
|
||||
* @param int $lessonid
|
||||
* @return array
|
||||
*/
|
||||
|
|
|
@ -231,6 +231,8 @@ function page_user_complete($course, $user, $mod, $page) {
|
|||
/**
|
||||
* Returns the users with data in one page
|
||||
*
|
||||
* @todo: deprecated - to be deleted in 2.2
|
||||
*
|
||||
* @param int $pageid
|
||||
* @return bool false
|
||||
*/
|
||||
|
|
|
@ -366,7 +366,16 @@ function quiz_user_outline($course, $user, $mod, $quiz) {
|
|||
|
||||
$result = new stdClass();
|
||||
$result->info = get_string('grade') . ': ' . $grade->str_long_grade;
|
||||
$result->time = $grade->dategraded;
|
||||
|
||||
//datesubmitted == time created. dategraded == time modified or time overridden
|
||||
//if grade was last modified by the user themselves use date graded. Otherwise use date submitted
|
||||
//TODO: move this copied & pasted code somewhere in the grades API. See MDL-26704
|
||||
if ($grade->usermodified == $user->id || empty($grade->datesubmitted)) {
|
||||
$result->time = $grade->dategraded;
|
||||
} else {
|
||||
$result->time = $grade->datesubmitted;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
|
|
@ -210,6 +210,8 @@ function resource_user_complete($course, $user, $mod, $resource) {
|
|||
/**
|
||||
* Returns the users with data in one resource
|
||||
*
|
||||
* @todo: deprecated - to be deleted in 2.2
|
||||
*
|
||||
* @param int $resourceid
|
||||
* @return bool false
|
||||
*/
|
||||
|
|
|
@ -294,7 +294,16 @@ function scorm_user_outline($course, $user, $mod, $scorm) {
|
|||
$grade = reset($grades->items[0]->grades);
|
||||
$result = new stdClass();
|
||||
$result->info = get_string('grade') . ': '. $grade->str_long_grade;
|
||||
$result->time = $grade->dategraded;
|
||||
|
||||
//datesubmitted == time created. dategraded == time modified or time overridden
|
||||
//if grade was last modified by the user themselves use date graded. Otherwise use date submitted
|
||||
//TODO: move this copied & pasted code somewhere in the grades API. See MDL-26704
|
||||
if ($grade->usermodified == $user->id || empty($grade->datesubmitted)) {
|
||||
$result->time = $grade->dategraded;
|
||||
} else {
|
||||
$result->time = $grade->datesubmitted;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -271,7 +271,8 @@ function survey_print_recent_activity($course, $viewfullnames, $timestart) {
|
|||
* Returns the users with data in one survey
|
||||
* (users with records in survey_analysis and survey_answers, students)
|
||||
*
|
||||
* @global object
|
||||
* @todo: deprecated - to be deleted in 2.2
|
||||
*
|
||||
* @param int $surveyid
|
||||
* @return array
|
||||
*/
|
||||
|
|
|
@ -237,6 +237,8 @@ function url_user_complete($course, $user, $mod, $url) {
|
|||
/**
|
||||
* Returns the users with data in one url
|
||||
*
|
||||
* @todo: deprecated - to be deleted in 2.2
|
||||
*
|
||||
* @param int $urlid
|
||||
* @return bool false
|
||||
*/
|
||||
|
|
|
@ -382,6 +382,8 @@ function wiki_grades($wikiid) {
|
|||
* in the instance, independient of his role (student, teacher, admin...)
|
||||
* See other modules as example.
|
||||
*
|
||||
* @todo: deprecated - to be deleted in 2.2
|
||||
*
|
||||
* @param int $wikiid ID of an instance of this module
|
||||
* @return mixed boolean/array of students
|
||||
**/
|
||||
|
|
|
@ -898,6 +898,8 @@ function workshop_cron () {
|
|||
* are not returned as the example submission is considered non-user
|
||||
* data for the purpose of workshop backup.
|
||||
*
|
||||
* @todo: deprecated - to be deleted in 2.2
|
||||
*
|
||||
* @param int $workshopid ID of an instance of this module
|
||||
* @return array of user ids, empty if there are no participants
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue