Commit 97d71cbc authored by Marina Glancy's avatar Marina Glancy
Browse files

MDL-53638 mod_feedback: convert to moodleforms

parent ffee513e
......@@ -36,16 +36,15 @@ list($course, $cm) = get_course_and_cm_from_cmid($id, 'feedback');
require_course_login($course, true, $cm);
$feedback = $PAGE->activityrecord;
$feedbackstructure = new mod_feedback_structure($feedback, $cm);
$context = context_module::instance($cm->id);
if (!feedback_can_view_analysis($feedback, $context)) {
if (!$feedbackstructure->can_view_analysis()) {
print_error('error');
}
/// Print the page header
$strfeedbacks = get_string("modulenameplural", "feedback");
$strfeedback = get_string("modulename", "feedback");
$PAGE->set_heading($course->fullname);
$PAGE->set_title($feedback->name);
......@@ -57,9 +56,8 @@ require('tabs.php');
//get the groupid
$myurl = $CFG->wwwroot.'/mod/feedback/analysis.php?id='.$cm->id.'&do_show=analysis';
$mygroupid = groups_get_activity_group($cm, true);
groups_print_activity_menu($cm, $myurl);
groups_print_activity_menu($cm, $url);
if ( has_capability('mod/feedback:viewreports', $context) ) {
//button "export to excel"
......@@ -69,17 +67,15 @@ if ( has_capability('mod/feedback:viewreports', $context) ) {
echo $OUTPUT->container_end();
}
//get completed feedbacks
$completedscount = feedback_get_completeds_group_count($feedback, $mygroupid);
// Get completed feedbacks.
$completedcount = $feedbackstructure->count_completed_responses($mygroupid);
echo '<div class="analysis_header">';
// Show the submissions count.
echo '<b>'.get_string('completed_feedbacks', 'feedback').': '.$completedscount. '</b><br />';
// get the items of the feedback
$items = $DB->get_records('feedback_item',
array('feedback'=>$feedback->id, 'hasvalue'=>1),
'position');
// Get the items of the feedback.
$items = $feedbackstructure->get_items(true);
// Show the items count.
if (is_array($items)) {
echo '<b>'.get_string('questions', 'feedback').': ' .count($items). ' </b><hr />';
......@@ -90,30 +86,18 @@ echo '</div>';
$check_anonymously = true;
if ($mygroupid > 0 AND $feedback->anonymous == FEEDBACK_ANONYMOUS_YES) {
if ($completedscount < FEEDBACK_MIN_ANONYMOUS_COUNT_IN_GROUP) {
if ($completedcount < FEEDBACK_MIN_ANONYMOUS_COUNT_IN_GROUP) {
$check_anonymously = false;
}
}
echo '<div>';
if ($check_anonymously) {
$itemnr = 0;
//print the items in an analysed form
// Print the items in an analysed form.
foreach ($items as $item) {
if ($item->hasvalue == 0) {
continue;
}
echo '<table width="100%" class="generalbox">';
//get the class of item-typ
echo '<table class="analysis">';
$itemobj = feedback_get_item_class($item->typ);
$itemnr++;
if ($feedback->autonumbering) {
$printnr = $itemnr.'.';
} else {
$printnr = '';
}
$printnr = ($feedback->autonumbering && $item->itemnr) ? ($item->itemnr . '.') : '';
$itemobj->print_analysed($item, $printnr, $mygroupid);
echo '</table>';
}
......
......@@ -49,26 +49,19 @@ if ($searchcourse !== '') {
}
$PAGE->set_url($url);
if (! $cm = get_coursemodule_from_id('feedback', $id)) {
print_error('invalidcoursemodule');
}
if (! $course = $DB->get_record("course", array("id"=>$cm->course))) {
print_error('coursemisconf');
}
if (! $feedback = $DB->get_record("feedback", array("id"=>$cm->instance))) {
print_error('invalidcoursemodule');
}
list($course, $cm) = get_course_and_cm_from_cmid($id, 'feedback');
$context = context_module::instance($cm->id);
require_login($course, true, $cm);
require_course_login($course, true, $cm);
$feedback = $PAGE->activityrecord;
if (!($feedback->publish_stats OR has_capability('mod/feedback:viewreports', $context))) {
print_error('error');
}
$feedbackstructure = new mod_feedback_structure($feedback, $PAGE->cm, $courseid);
/// Print the page header
$strfeedbacks = get_string("modulenameplural", "feedback");
$strfeedback = get_string("modulename", "feedback");
......@@ -96,14 +89,13 @@ if (has_capability('mod/feedback:viewreports', $context)) {
//lstgroupid is the choosen id
$mygroupid = false;
//get completed feedbacks
$completedscount = feedback_get_completeds_group_count($feedback, $mygroupid, $courseid);
$completedcount = $feedbackstructure->count_completed_responses();
//show the count
echo '<b>'.get_string('completed_feedbacks', 'feedback').': '.$completedscount. '</b><br />';
// get the items of the feedback
$params = array('feedback' => $feedback->id, 'hasvalue' => 1);
$items = $DB->get_records('feedback_item', $params, 'position');
// Get the items of the feedback.
$items = $feedbackstructure->get_items(true);
//show the count
if (is_array($items)) {
echo '<b>'.get_string('questions', 'feedback').': ' .count($items). ' </b><hr />';
......@@ -123,8 +115,6 @@ if ($courseitemfilter > 0) {
echo '<div class="clearfix">';
echo '<table>';
echo '<tr><th>Course</th><th>Average</th></tr>';
$sep_dec = get_string('separator_decimal', 'feedback');
$sep_thous = get_string('separator_thousand', 'feedback');
foreach ($courses as $c) {
$coursecontext = context_course::instance($c->course_id);
......@@ -133,7 +123,7 @@ if ($courseitemfilter > 0) {
echo '<tr>';
echo '<td>'.$shortname.'</td>';
echo '<td align="right">';
echo number_format(($c->sumvalue / $c->countvalue), 2, $sep_dec, $sep_thous);
echo format_float(($c->sumvalue / $c->countvalue), 2);
echo '</td>';
echo '</tr>';
}
......@@ -182,23 +172,14 @@ if ($courseitemfilter > 0) {
echo '</form>';
echo '</div>';
echo '<hr />';
$itemnr = 0;
//print the items in an analysed form
// Print the items in an analysed form.
foreach ($items as $item) {
if ($item->hasvalue == 0) {
continue;
}
echo '<table>';
//get the class from item-typ
echo '<table class="analysis">';
echo "<tr><td colspan=\"2\" class=\"analysis_separator\"><hr></td></tr>";
$itemobj = feedback_get_item_class($item->typ);
$itemnr++;
if ($feedback->autonumbering) {
$printnr = $itemnr.'.';
} else {
$printnr = '';
}
$itemobj->print_analysed($item, $printnr, $mygroupid, $courseid);
$printnr = ($feedback->autonumbering && $item->itemnr) ? ($item->itemnr . '.') : '';
$itemobj->print_analysed($item, $printnr, $mygroupid, $feedbackstructure->get_courseid());
if (preg_match('/rated$/i', $item->typ)) {
$url = new moodle_url('/mod/feedback/analysis_course.php', array('id' => $id,
'courseitemfilter' => $item->id, 'courseitemfiltertyp' => $item->typ));
......
......@@ -54,6 +54,7 @@ if (! $feedback = $DB->get_record("feedback", array("id"=>$cm->instance))) {
$context = context_module::instance($cm->id);
require_login($course, true, $cm);
$feedbackstructure = new mod_feedback_structure($feedback, $PAGE->cm, $coursefilter);
require_capability('mod/feedback:viewreports', $context);
......@@ -78,8 +79,8 @@ $fstring->anonymous_user = get_string('anonymous_user', 'feedback');
ob_end_clean();
//get the questions (item-names)
$params = array('feedback' => $feedback->id, 'hasvalue' => 1);
if (!$items = $DB->get_records('feedback_item', $params, 'position')) {
$items = $feedbackstructure->get_items(true);
if (!$items) {
print_error('no_items_available_yet',
'feedback',
$CFG->wwwroot.'/mod/feedback/view.php?id='.$id);
......@@ -139,7 +140,7 @@ $worksheet1->write_string($row_offset1, 0, userdate(time()), $xls_formats->head1
//print the analysed sheet
////////////////////////////////////////////////////////////////////////
//get the completeds
$completedscount = feedback_get_completeds_group_count($feedback, $mygroupid, $coursefilter);
$completedscount = $feedbackstructure->count_completed_responses($mygroupid);
if ($completedscount > 0) {
//write the count of completeds
$row_offset1++;
......
This diff is collapsed.
This diff is collapsed.
......@@ -50,6 +50,29 @@ class course_module_viewed extends \core\event\course_module_viewed {
$this->data['objecttable'] = 'feedback';
}
/**
* Creates an instance from feedback record
*
* @param stdClass $feedback
* @param cm_info|stdClass $cm
* @param stdClass $course
* @return course_module_viewed
*/
public static function create_from_record($feedback, $cm, $course) {
$event = self::create(array(
'objectid' => $feedback->id,
'context' => \context_module::instance($cm->id),
'anonymous' => ($feedback->anonymous == FEEDBACK_ANONYMOUS_YES),
'other' => array(
'anonymous' => $feedback->anonymous // Deprecated.
)
));
$event->add_record_snapshot('course_modules', $cm);
$event->add_record_snapshot('course', $course);
$event->add_record_snapshot('feedback', $feedback);
return $event;
}
/**
* Define whether a user can view the event or not. Make sure no one except admin can see details of an anonymous response.
*
......
......@@ -54,6 +54,32 @@ class response_deleted extends \core\event\base {
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
}
/**
* Creates an instance from the record from db table feedback_completed
*
* @param stdClass $completed
* @param stdClass|cm_info $cm
* @param stdClass $feedback
* @return self
*/
public static function create_from_record($completed, $cm, $feedback) {
$event = self::create(array(
'relateduserid' => $completed->userid,
'objectid' => $completed->id,
'courseid' => $cm->course,
'context' => \context_module::instance($cm->id),
'anonymous' => ($completed->anonymous_response == FEEDBACK_ANONYMOUS_YES),
'other' => array(
'cmid' => $cm->id,
'instanceid' => $feedback->id,
'anonymous' => $completed->anonymous_response) // Deprecated.
));
$event->add_record_snapshot('feedback_completed', $completed);
$event->add_record_snapshot('feedback', $feedback);
return $event;
}
/**
* Returns localised general event name.
*
......
......@@ -57,6 +57,29 @@ class response_submitted extends \core\event\base {
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
}
/**
* Creates an instance from the record from db table feedback_completed
*
* @param stdClass $completed
* @param stdClass|cm_info $cm
* @return self
*/
public static function create_from_record($completed, $cm) {
$event = self::create(array(
'relateduserid' => $completed->userid,
'objectid' => $completed->id,
'context' => \context_module::instance($cm->id),
'anonymous' => ($completed->anonymous_response == FEEDBACK_ANONYMOUS_YES),
'other' => array(
'cmid' => $cm->id,
'instanceid' => $completed->feedback,
'anonymous' => $completed->anonymous_response // Deprecated.
)
));
$event->add_record_snapshot('feedback_completed', $completed);
return $event;
}
/**
* Returns localised general event name.
*
......
......@@ -206,6 +206,19 @@ class mod_feedback_responses_table extends table_sql {
return $this->grandtotal;
}
/**
* Defines columns
* @param array $columns an array of identifying names for columns. If
* columns are sorted then column names must correspond to a field in sql.
*/
function define_columns($columns) {
parent::define_columns($columns);
foreach ($this->columns as $column => $column) {
// Automatically assign classes to columns.
$this->column_class[$column] = ' ' . $column;
}
}
/**
* Displays the table
*/
......
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Contains class mod_feedback_structure
*
* @package mod_feedback
* @copyright 2016 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Stores and manipulates the structure of the feedback or template (items, pages, etc.)
*
* @package mod_feedback
* @copyright 2016 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mod_feedback_structure {
/** @var stdClass */
protected $feedback;
/** @var cm_info */
protected $cm;
/** @var int */
protected $courseid = 0;
/** @var int */
protected $templateid;
/** @var array */
protected $allitems;
/** @var array */
protected $allcourses;
/**
* Constructor
*
* @param stdClass $feedback feedback object, in case of the template
* this is the current feedback the template is accessed from
* @param cm_info $cm course module object corresponding to the $feedback
* @param int $courseid current course (for site feedbacks only)
* @param int $templateid template id if this class represents the template structure
*/
public function __construct($feedback, $cm, $courseid = 0, $templateid = null) {
$this->feedback = $feedback;
$this->cm = $cm;
$this->courseid = ($feedback->course == SITEID) ? $courseid : 0;
$this->templateid = $templateid;
}
/**
* Current feedback
* @return stdClass
*/
public function get_feedback() {
return $this->feedback;
}
/**
* Current course module
* @return stdClass
*/
public function get_cm() {
return $this->cm;
}
/**
* Id of the current course (for site feedbacks only)
* @return stdClass
*/
public function get_courseid() {
return $this->courseid;
}
/**
* Template id
* @return int
*/
public function get_templateid() {
return $this->templateid;
}
/**
* Is this feedback open (check timeopen and timeclose)
* @return bool
*/
public function is_open() {
$checktime = time();
return (!$this->feedback->timeopen || $this->feedback->timeopen <= $checktime) &&
(!$this->feedback->timeclose || $this->feedback->timeclose >= $checktime);
}
/**
* Get all items in this feedback or this template
* @param bool $hasvalueonly only count items with a value.
* @return array of objects from feedback_item with an additional attribute 'itemnr'
*/
public function get_items($hasvalueonly = false) {
global $DB;
if ($this->allitems === null) {
if ($this->templateid) {
$this->allitems = $DB->get_records('feedback_item', ['template' => $this->templateid], 'position');
} else {
$this->allitems = $DB->get_records('feedback_item', ['feedback' => $this->feedback->id], 'position');
}
$idx = 1;
foreach ($this->allitems as $id => $item) {
$this->allitems[$id]->itemnr = $item->hasvalue ? ($idx++) : null;
}
}
if ($hasvalueonly && $this->allitems) {
return array_filter($this->allitems, function($item) {
return $item->hasvalue;
});
}
return $this->allitems;
}
/**
* Is the items list empty?
* @return bool
*/
public function is_empty() {
$items = $this->get_items();
$displayeditems = array_filter($items, function($item) {
return $item->typ !== 'pagebreak';
});
return !$displayeditems;
}
/**
* Is this feedback anonymous?
* @return bool
*/
public function is_anonymous() {
return $this->feedback->anonymous == FEEDBACK_ANONYMOUS_YES;
}
/**
* Returns the formatted text of the page after submit or null if it is not set
*
* @return string|null
*/
public function page_after_submit() {
global $CFG;
require_once($CFG->libdir . '/filelib.php');
$pageaftersubmit = $this->get_feedback()->page_after_submit;
if (empty($pageaftersubmit)) {
return null;
}
$pageaftersubmitformat = $this->get_feedback()->page_after_submitformat;
$context = context_module::instance($this->get_cm()->id);
$output = file_rewrite_pluginfile_urls($pageaftersubmit,
'pluginfile.php', $context->id, 'mod_feedback', 'page_after_submit', 0);
return format_text($output, $pageaftersubmitformat, array('overflowdiv' => true));
}
/**
* Checks if current user is able to view feedback on this course.
*
* @return bool
*/
public function can_view_analysis() {
$context = context_module::instance($this->cm->id);
if (has_capability('mod/feedback:viewreports', $context)) {
return true;
}
if (intval($this->feedback->publish_stats) != 1 ||
!has_capability('mod/feedback:viewanalysepage', $context)) {
return false;
}
if (!isloggedin() || isguestuser()) {
// There is no tracking for the guests, assume that they can view analysis if condition above is satisfied.
return $this->feedback->course == SITEID;
}
return $this->is_already_submitted(true);
}
/**
* check for multiple_submit = false.
* if the feedback is global so the courseid must be given
*
* @param bool $anycourseid if true checks if this feedback was submitted in any course, otherwise checks $this->courseid .
* Applicable to frontpage feedbacks only
* @return bool true if the feedback already is submitted otherwise false
*/
public function is_already_submitted($anycourseid = false) {
global $USER, $DB;
if (!isloggedin() || isguestuser()) {
return false;
}
$params = array('userid' => $USER->id, 'feedback' => $this->feedback->id);
if (!$anycourseid && $this->courseid) {
$params['courseid'] = $this->courseid;
}
return $DB->record_exists('feedback_completed', $params);
}
/**
* Check whether the feedback is mapped to the given courseid.
*/
public function check_course_is_mapped() {
global $DB;
if ($this->feedback->course != SITEID) {
return true;
}
if ($DB->get_records('feedback_sitecourse_map', array('feedbackid' => $this->feedback->id))) {
$params = array('feedbackid' => $this->feedback->id, 'courseid' => $this->courseid);
if (!$DB->get_record('feedback_sitecourse_map', $params)) {
return false;
}
}
// No mapping means any course is mapped.
return true;
}
/**
* If there are any new responses to the anonymous feedback, re-shuffle all
* responses and assign response number to each of them.
*/
public function shuffle_anonym_responses() {
global $DB;
$params = array('feedback' => $this->feedback->id,
'random_response' => 0,
'anonymous_response' => FEEDBACK_ANONYMOUS_YES);
if ($DB->count_records('feedback_completed', $params, 'random_response')) {
// Get all of the anonymous records, go through them and assign a response id.
unset($params['random_response']);
$feedbackcompleteds = $DB->get_records('feedback_completed', $params, 'id');
shuffle($feedbackcompleteds);
$num = 1;
foreach ($feedbackcompleteds as $compl) {
$compl->random_response = $num++;
$DB->update_record('feedback_completed', $compl);
}
}
}
/**
* Counts records from {feedback_completed} table for a given feedback
*
* If $groupid or $this->courseid is set, the records are filtered by the group/course
*
* @param int $groupid
* @return mixed array of found completeds otherwise false
*/
public function count_completed_responses($groupid = 0) {
global $DB;
if (intval($groupid) > 0) {
$query = "SELECT COUNT(DISTINCT fbc.id)
FROM {feedback_completed} fbc, {groups_members} gm
WHERE fbc.feedback = :feedback
AND gm.groupid = :groupid
AND fbc.userid = gm.userid";
} else if ($this->courseid) {
$query = "SELECT COUNT(fbc.id)