Пример #1
0
$showlastaccess = true;
$hiddenfields = explode(',', $CFG->hiddenuserfields);
if (array_search('lastaccess', $hiddenfields) !== false and !has_capability('moodle/user:viewhiddendetails', $context)) {
    $showlastaccess = false;
}
$stractivityreport = get_string('pluginname', 'report_outline');
$stractivity = get_string('activity');
$strlast = get_string('lastaccess');
$strreports = get_string('reports');
$strviews = get_string('views');
$strrelatedblogentries = get_string('relatedblogentries', 'blog');
$PAGE->set_title($course->shortname . ': ' . $stractivityreport);
$PAGE->set_heading($course->fullname);
echo $OUTPUT->header();
echo $OUTPUT->heading(format_string($course->fullname));
list($uselegacyreader, $useinternalreader, $minloginternalreader, $logtable) = report_outline_get_common_log_variables();
// If no legacy and no internal log then don't proceed.
if (!$uselegacyreader && !$useinternalreader) {
    echo $OUTPUT->box_start('generalbox', 'notice');
    echo $OUTPUT->notification(get_string('nologreaderenabled', 'report_outline'));
    echo $OUTPUT->box_end();
    echo $OUTPUT->footer();
    die;
}
// We want to display the time we are beginning to get logs from in the heading.
// If we are using the legacy reader check the minimum time in that log table.
if ($uselegacyreader) {
    $minlog = $DB->get_field_sql('SELECT min(time) FROM {log}');
}
// If we are using the internal reader check the minimum time in that table.
if ($useinternalreader) {
Пример #2
0
/**
 * Display the most commonly used user complete information.
 *
 * @param int $userid the id of the user
 * @param int $cmid the course module id
 * @param string $module the name of the module (eg. 'book')
 * @param int $instanceid (eg. the 'id' in the 'book' table)
 * @return string
 */
function report_outline_user_complete($userid, $cmid, $module, $instanceid)
{
    global $DB;
    list($uselegacyreader, $useinternalreader, $minloginternalreader, $logtable) = report_outline_get_common_log_variables();
    // If using legacy log then get users from old table.
    if ($uselegacyreader) {
        // Create the params for the query.
        $params = array('userid' => $userid, 'module' => $module, 'action' => 'view', 'info' => $instanceid);
        // If we are going to use the internal (not legacy) log table, we should only get records
        // from the legacy table that exist before we started adding logs to the new table.
        $limittime = '';
        if (!empty($minloginternalreader)) {
            $limittime = ' AND time < :timeto ';
            $params['timeto'] = $minloginternalreader;
        }
        $select = "SELECT COUNT(id) ";
        $from = "FROM {log} ";
        $where = "WHERE userid = :userid\n                    AND module = :module\n                    AND action = :action\n                    AND info = :info ";
        if ($legacylogcount = $DB->count_records_sql($select . $from . $where . $limittime, $params)) {
            $numviews = $legacylogcount;
            // Get the time for the last log.
            $select = "SELECT MAX(time) ";
            $lastlogtime = $DB->get_field_sql($select . $from . $where, $params);
            $strnumviews = get_string('numviews', '', $numviews);
        }
    }
    // Get record from sql_internal_table_reader and combine with the number of views from the legacy log table (if needed).
    if ($useinternalreader) {
        $params = array('userid' => $userid, 'contextlevel' => CONTEXT_MODULE, 'contextinstanceid' => $cmid, 'crud' => 'r', 'edulevel1' => core\event\base::LEVEL_PARTICIPATING, 'edulevel2' => core\event\base::LEVEL_TEACHING, 'edulevel3' => core\event\base::LEVEL_OTHER, 'anonymous' => 0);
        $select = "SELECT COUNT(*) as count ";
        $from = "FROM {" . $logtable . "} ";
        $where = "WHERE userid = :userid\n                    AND contextlevel = :contextlevel\n                    AND contextinstanceid = :contextinstanceid\n                    AND crud = :crud\n                    AND edulevel IN (:edulevel1, :edulevel2, :edulevel3)\n                    AND anonymous = :anonymous";
        if ($internalreadercount = $DB->count_records_sql($select . $from . $where, $params)) {
            if (!empty($numviews)) {
                $numviews = $numviews + $internalreadercount;
            } else {
                $numviews = $internalreadercount;
            }
            // Get the time for the last log.
            $select = "SELECT MAX(timecreated) ";
            $lastlogtime = $DB->get_field_sql($select . $from . $where, $params);
            $strnumviews = get_string('numviews', '', $numviews);
        }
    }
    if (!empty($strnumviews) && !empty($lastlogtime)) {
        return $strnumviews . ' - ' . get_string('mostrecently') . ' ' . userdate($lastlogtime);
    } else {
        return get_string('neverseen', 'report_outline');
    }
}
 /**
  * Automatic student evaluation
  *
  * This function automatically avaluates the student according to enrichment criteria
  * which are cross referenced with the data obtained through Learning Analytics data mining procedures.
  *
  * For the new logging system from Moodle 2.6 onwards, Learning Analytics will only be obtained from
  * Legacy log Table a.k.a. {log} or New Internal Log Table a.k.a {logstore_standard_log}.
  *
  * External logstores can't be used because their data structure and logging data are custom
  * and can not be predicted. Only a log store creator would be able to change the data queries bellow
  * according to his log store specifications.
  *
  *
  * @param array $criterion data about the rubric design
  * @param array $options enriched rubric options
  */
 protected function evaluate_enrichment(&$criterion, $options)
 {
     global $DB;
     global $PAGE;
     global $CFG;
     $moduletypename = null;
     $benchmarkstudent = null;
     $benchmarkstudents = null;
     $benchmarkcriterion = null;
     $untiltime = null;
     $fromtime = null;
     $selectallstudents = null;
     $participatingstudents = null;
     $iterations = 0;
     $sql = null;
     // Get the current assignment data.
     $curmoduleid = (int) $PAGE->cm->module;
     $curmodulename = $PAGE->cm->modname;
     $curcmid = $PAGE->cm->id;
     $gradingmoduleid = $PAGE->cm->instance;
     $courseid = $PAGE->cm->course;
     //**** For Moodle 2.6 onwards new logging system  ***//
     /* If the Legacy Log is used, we work with it. If not, we use the new Internal Log (Standard). The old log is more efficient for the queries used bellow.
      *  If en External Logstore is used and both Legacy and new Internal logs are deactivated, do nothing, as we can't know in advance how the new
      *  external logs are stored and how the store's log tables are structured.
      *
      */
     // Set the necessary variables
     $uselegacyreader = true;
     $useinternalreader = null;
     $minloginternalreader = null;
     $logtable = null;
     $moodle_2_6_0_version = '2013111800';
     // Get the necessary variables if needed
     if ($CFG->version >= $moodle_2_6_0_version) {
         require_once $CFG->dirroot . '/report/outline/locallib.php';
         list($uselegacyreader, $useinternalreader, $minloginternalreader, $logtable) = report_outline_get_common_log_variables();
     }
     //**** For moodle 2.2 versions assignment modules ****//
     $studentid = optional_param('userid', '', PARAM_INT);
     //**** For moodle 2.3 onwards assignment module ****//
     if (!$studentid) {
         require_once $CFG->dirroot . '/mod/assign/locallib.php';
         $context = context_module::instance($PAGE->cm->id);
         $assignment = new assign($context, $PAGE->cm, $PAGE->cm->course);
         $useridlist = array_keys($assignment->list_participants(0, true));
         sort($useridlist);
         // The users list containing the IDs of students evaluated.
         $rownum = $_REQUEST['rownum'];
         // Check if next or previous buttons are pressed in the avaluation form.
         if (array_key_exists('saveandshownext', $_REQUEST) || array_key_exists('nosaveandnext', $_REQUEST)) {
             $rownum++;
         }
         if (array_key_exists('nosaveandprevious', $_REQUEST)) {
             $rownum--;
         }
         $studentid = $useridlist[$rownum];
     }
     // SQL for including all course enroled students.
     $selectindividual = "= {$studentid}";
     $selectallstudents = "IN (SELECT u.id\n                                    FROM {role_assignments} ra\n                                        JOIN {context} c ON ra.contextid = c.id AND c.contextlevel = 50\n                                        JOIN {user} u ON u.id = ra.userid\n                                        JOIN {course} crse ON c.instanceid = crse.id\n                                    WHERE ra.roleid = 5\n                                        AND crse.id = {$courseid})";
     // Timestamp enrichment calculations according to assignment module (old or new type assignments).
     // In case of old type assignment...
     if ($curmoduleid == $this->oldassignmoduleid) {
         // Get potential enrichment due date.
         if ($options['timestampenrichmentend']) {
             $sql = 'SELECT asmnt.timedue AS duedate FROM {assignment} asmnt WHERE asmnt.id = ' . $gradingmoduleid;
             $untiltime = $DB->get_field_sql($sql, null);
         }
         // Get potential availability start time.
         if ($options['timestampenrichmentstart']) {
             $sql = 'SELECT asmnt.timeavailable AS startdate FROM {assignment} asmnt WHERE asmnt.id = ' . $gradingmoduleid;
             $fromtime = $DB->get_field_sql($sql, null);
         }
         // In case of new type assignment...
     } else {
         if ($curmoduleid == $this->newassignmoduleid) {
             // Get potential enrichment due date.
             if ($options['timestampenrichmentend']) {
                 $sql = 'SELECT asmnt.duedate AS duedate FROM {assign} asmnt WHERE asmnt.id = ' . $gradingmoduleid;
                 $untiltime = $DB->get_field_sql($sql, null);
             }
             // Get potential availability start time.
             if ($options['timestampenrichmentstart']) {
                 $sql = 'SELECT asmnt.allowsubmissionsfromdate AS startdate FROM {assign} asmnt WHERE asmnt.id = ' . $gradingmoduleid;
                 $fromtime = $DB->get_field_sql($sql, null);
             }
         }
     }
     // Retrieve Learning Analytics data according to criterion type (collaboration - study - grade).
     switch ($criterion['criteriontype']) {
         // In case of checking student studying, perform data mining from study logs of selected course modules (resources).
         case gradingform_erubric_controller::INTERACTION_TYPE_STUDY:
             $moduletypename = 'resource';
             foreach ($criterion['coursemodules'][$moduletypename][0] as $mdlinstance) {
                 // Iterate through course modules.
                 $tempinstance = explode('->', $mdlinstance);
                 $moduleid = $tempinstance[0];
                 $instanceid = $tempinstance[1];
                 $timefield = 'time';
                 // Get log files according to curent log store
                 if ($uselegacyreader) {
                     // Old log
                     $sql = "SELECT COUNT(lg.id) AS TOTALS\n                                FROM {log} lg\n                                    INNER JOIN {course_modules} cm ON (lg.cmid = cm.id)\n                                WHERE   lg.userid {$selectindividual}\n                                    AND lg.action = 'view'\n                                    AND cm.course = {$courseid}\n                                    AND cm.module = {$moduleid}\n                                    AND cm.instance = {$instanceid} ";
                 } elseif ($useinternalreader) {
                     // New log
                     $sql = "SELECT COUNT(lg.id) AS TOTALS\n                                FROM {" . $logtable . "} lg\n                                    INNER JOIN {modules} mdls ON (lg.objecttable = mdls.name)\n                                WHERE   lg.userid {$selectindividual}\n                                    AND lg.action = 'viewed'\n                                    AND lg.courseid = {$courseid}\n                                    AND mdls.id = {$moduleid}\n                                    AND lg.objectid = {$instanceid} ";
                     $timefield = 'timecreated';
                 }
                 $this->get_value_from_learning_analytics($benchmarkstudent, $sql, 'lg', $timefield, $fromtime, $untiltime, 1);
                 // If the criterion has a global reference according to all students participating.
                 if ($criterion['referencetype'] == gradingform_erubric_controller::REFERENCE_STUDENTS) {
                     $sql = "SELECT COUNT(crse.id) AS Totals\n                                FROM {role_assignments} ra\n                                    JOIN {context} c ON ra.contextid = c.id AND c.contextlevel = 50\n                                    JOIN {user} u ON u.id = ra.userid\n                                    JOIN {course} crse ON c.instanceid = crse.id\n                                WHERE ra.roleid = 5\n                                    AND crse.id = {$courseid} ";
                     $count = $DB->get_field_sql($sql, null);
                     if ($count && $count > 0) {
                         // If there is at least one student.
                         $iterations++;
                         // Get log files according to curent log store
                         if ($uselegacyreader) {
                             // Old log
                             $sql = "SELECT COUNT(lg.id) AS TOTALS\n                                        FROM {log} lg\n                                            INNER JOIN {course_modules} cm ON (lg.cmid = cm.id)\n                                        WHERE   lg.userid {$selectallstudents}\n                                            AND lg.action = 'view'\n                                            AND cm.course = {$courseid}\n                                            AND cm.module = {$moduleid}\n                                            AND cm.instance = {$instanceid} ";
                         } elseif ($useinternalreader) {
                             // New log
                             $sql = "SELECT COUNT(lg.id) AS TOTALS\n                                        FROM {" . $logtable . "} lg\n                                            INNER JOIN {modules} mdls ON (lg.objecttable = mdls.name)\n                                        WHERE   lg.userid {$selectallstudents}\n                                            AND lg.action = 'viewed'\n                                            AND lg.courseid = {$courseid}\n                                            AND mdls.id = {$moduleid}\n                                            AND lg.objectid = {$instanceid} ";
                             $timefield = 'timecreated';
                         }
                         $this->get_value_from_learning_analytics($benchmarkstudents, $sql, 'lg', $timefield, $fromtime, $untiltime, $count);
                     }
                 }
             }
             break;
             // In case of checking student grades, perform data mining from grade logs of selected course modules (assignments).
         // In case of checking student grades, perform data mining from grade logs of selected course modules (assignments).
         case gradingform_erubric_controller::INTERACTION_TYPE_GRADE:
             $moduletypename = 'assignment';
             foreach ($criterion['coursemodules'][$moduletypename][0] as $mdlinstance) {
                 // Iterate through course modules.
                 $tempinstance = explode('->', $mdlinstance);
                 $moduleid = $tempinstance[0];
                 $instanceid = $tempinstance[1];
                 $tempstudentcurrgrade = null;
                 $sql = "SELECT gr.finalgrade AS Grade\n                            FROM {grade_grades} gr\n                                INNER JOIN {grade_items} gi ON (gi.id = gr.itemid)\n                                INNER JOIN {modules} md ON (md.name = gi.itemmodule)\n                            WHERE   gr.userid {$selectindividual}\n                                AND gi.courseid = {$courseid}\n                                AND md.id = {$moduleid}\n                                AND gi.iteminstance = {$instanceid} ";
                 $this->get_value_from_learning_analytics($tempstudentcurrgrade, $sql, null, null, null, null, 1);
                 // If the student has not been graded for this course assignment,
                 // there is no point on calculating his or the others benchmark.
                 if (!is_null($tempstudentcurrgrade)) {
                     $iterations++;
                     // Get maximum grade score for current assignment module in order to define student performance according to 100 scale.
                     $sql = "SELECT assmnt.grade AS maxgrade ";
                     if ($moduleid == $this->newassignmoduleid) {
                         $sql .= "FROM {assign} assmnt ";
                         // New type assignment modules (Moodle 2.3+)
                     } else {
                         $sql .= "FROM {assignment} assmnt ";
                         // Old type assignment modules (Moodle 2.2)
                     }
                     $sql .= "WHERE   assmnt.id = {$instanceid}";
                     $tempassignmax = (double) $DB->get_field_sql($sql, null);
                     $benchmarkstudent += (double) round($tempstudentcurrgrade / $tempassignmax * 100, 2);
                     // If the criterion has a global reference according to all students grades.
                     if ($criterion['referencetype'] == gradingform_erubric_controller::REFERENCE_STUDENTS) {
                         $sql = "SELECT AVG(gr.finalgrade) AS AvgGrades\n                                FROM {grade_grades} gr\n                                    INNER JOIN {grade_items} gi ON (gi.id = gr.itemid)\n                                    INNER JOIN {modules} md ON (md.name = gi.itemmodule)\n                                WHERE   gr.userid {$selectallstudents}\n                                    AND gi.courseid = {$courseid}\n                                    AND md.id = {$moduleid}\n                                    AND gi.iteminstance = {$instanceid} ";
                         $tempstudentsgrade = $DB->get_field_sql($sql, null);
                         if (!is_null($tempstudentsgrade)) {
                             // If the value is valid.
                             $benchmarkstudents += (double) round($tempstudentsgrade / $tempassignmax * 100, 2);
                         }
                     }
                 }
             }
             break;
             // In case of checking student collaboration, perform data mining according to collaboration type:
             // - Entries, for simple log occurences in selected course modules,
             // - File Adds, for summing number of file adds (not number of files!), from course modules of type forum.
             // - Replies, for summing number of replied posts, from course modules of type forum.
             // - Interactions, for total number of students the evaluated student interacted during using the selected course modules.
         // In case of checking student collaboration, perform data mining according to collaboration type:
         // - Entries, for simple log occurences in selected course modules,
         // - File Adds, for summing number of file adds (not number of files!), from course modules of type forum.
         // - Replies, for summing number of replied posts, from course modules of type forum.
         // - Interactions, for total number of students the evaluated student interacted during using the selected course modules.
         case gradingform_erubric_controller::INTERACTION_TYPE_COLLABORATION:
             $moduletypename = 'activity';
             // In case of students interactions, benchmarks will be calculated after all modules have been processed.
             if ($criterion['collaborationtype'] == gradingform_erubric_controller::COLLABORATION_TYPE_INTERACTIONS) {
                 $distinctUsersFound = array();
             }
             // In case of students file submissions, benchmarks will be initialised with zero values.
             if ($criterion['collaborationtype'] == gradingform_erubric_controller::COLLABORATION_TYPE_FILE_ADDS) {
                 $benchmarkstudent = 0;
                 if ($criterion['referencetype'] == gradingform_erubric_controller::REFERENCE_STUDENTS) {
                     $benchmarkstudents = 0;
                 }
             }
             foreach ($criterion['coursemodules'][$moduletypename][0] as $mdlinstance) {
                 // Iterate through course modules.
                 $tempinstance = explode('->', $mdlinstance);
                 $moduleid = $tempinstance[0];
                 $instanceid = $tempinstance[1];
                 $logtablename = 'log';
                 $timefield = 'time';
                 switch ($criterion['collaborationtype']) {
                     // In case of checking simple entries in forums and chats,
                     // just check for 'add post' or 'talk' actions inside moodle log.
                     case gradingform_erubric_controller::COLLABORATION_TYPE_ENTRIES:
                         // Get log files according to curent log store
                         if ($uselegacyreader) {
                             // Old log
                             $sql = "SELECT COUNT(lg.id) AS TOTALS\n                                        FROM {log} lg\n                                            INNER JOIN {course_modules} cm ON (lg.cmid = cm.id)\n                                        WHERE   lg.userid {$selectindividual}\n                                            AND (lg.action = 'add post' OR lg.action = 'talk')\n                                            AND cm.course = {$courseid}\n                                            AND cm.module = {$moduleid}\n                                            AND cm.instance = {$instanceid} ";
                         } elseif ($useinternalreader) {
                             // New log
                             // There is no direct way to get both posts and talks from the new log
                             // according to the module id (forum or chat) and instance id (forum id or chat id),
                             // so we must seperate the original log query with two different queries that don't have to refer to the new log anymore.
                             // Bye bye new log... Bummer :(
                             // If this is a forum course module
                             if ($moduleid == $this->forummoduleid) {
                                 $sql = "SELECT COUNT(fp.id) AS TOTALS\n                                            FROM {forum_posts} fp\n                                                INNER JOIN {forum_discussions} fdcs ON (fp.discussion = fdcs.id)\n                                            WHERE   fp.userid {$selectindividual}\n                                                AND fdcs.course = {$courseid}\n                                                AND fdcs.forum = {$instanceid} ";
                                 $logtablename = 'fp';
                                 $timefield = 'created';
                                 // Else only if this is a chat course module
                             } elseif ($moduleid == $this->chatmoduleid) {
                                 $sql = "SELECT COUNT(chms.id) AS TOTALS\n                                            FROM {chat_messages} chms\n                                            WHERE   chms.userid {$selectindividual}\n                                                AND chms.system = 0\n                                                AND chms.chatid = {$instanceid} ";
                                 $logtablename = 'chms';
                                 $timefield = 'timestamp';
                             }
                         }
                         $this->get_value_from_learning_analytics($benchmarkstudent, $sql, $logtablename, $timefield, $fromtime, $untiltime, 1);
                         // If the criterion has a global reference according to all students' collaborations,
                         // we hold accountable only participating students. If a student is absent (no log entries), he is not accounted for.
                         if ($criterion['referencetype'] == gradingform_erubric_controller::REFERENCE_STUDENTS) {
                             $count = 0;
                             // Get log files according to curent log store
                             if ($uselegacyreader) {
                                 // Old log
                                 $sql = "SELECT DISTINCT (lg.userid) AS userids\n                                            FROM {log} lg\n                                                INNER JOIN {course_modules} cm ON (lg.cmid = cm.id)\n                                            WHERE   lg.userid {$selectallstudents}\n                                                AND (lg.action = 'add post' OR lg.action = 'talk')\n                                                AND cm.course = {$courseid}\n                                                AND cm.module = {$moduleid}\n                                                AND cm.instance = {$instanceid} ";
                                 // Count participating students and return the sql query to count their entries next
                                 $participatingstudents = $this->timestamp_and_count_active_studends_involved($count, $sql, 'lg', 'time', $fromtime, $untiltime);
                                 if ($count > 0) {
                                     // If there is at least one student.
                                     $iterations++;
                                     $sql = "SELECT COUNT(lg.id) AS TOTALS\n                                                FROM {log} lg\n                                                    INNER JOIN {course_modules} cm ON (lg.cmid = cm.id)\n                                                WHERE   lg.userid IN ({$participatingstudents})\n                                                    AND (lg.action = 'add post' OR lg.action = 'talk')\n                                                    AND cm.course = {$courseid}\n                                                    AND cm.module = {$moduleid}\n                                                    AND cm.instance = {$instanceid} ";
                                     $this->get_value_from_learning_analytics($benchmarkstudents, $sql, 'lg', 'time', $fromtime, $untiltime, $count);
                                 }
                             } elseif ($useinternalreader) {
                                 // New log
                                 // There is no direct way to get both posts and talks from the new log
                                 // according to the module id (forum or chat) and instance id (forum id or chat id),
                                 // so we must seperate the original log query with two different queries that don't have to refer to the new log anymore.
                                 // Bye bye new log... Bummer :(
                                 // If this is a forum course module
                                 if ($moduleid == $this->forummoduleid) {
                                     $logtablename = 'fp';
                                     $timefield = 'created';
                                     $sql = "SELECT DISTINCT (fp.userid) AS userids\n                                                FROM {forum_posts} fp\n                                                    INNER JOIN {forum_discussions} fdcs ON (fp.discussion = fdcs.id)\n                                                WHERE   fp.userid {$selectallstudents}\n                                                    AND fdcs.course = {$courseid}\n                                                    AND fdcs.forum = {$instanceid} ";
                                     // Count participating students and return the sql query to count their entries next
                                     $participatingstudents = $this->timestamp_and_count_active_studends_involved($count, $sql, $logtablename, $timefield, $fromtime, $untiltime);
                                     if ($count > 0) {
                                         // If there is at least one student.
                                         $iterations++;
                                         $sql = "SELECT COUNT(fp.id) AS TOTALS\n                                                    FROM {forum_posts} fp\n                                                        INNER JOIN {forum_discussions} fdcs ON (fp.discussion = fdcs.id)\n                                                    WHERE   fp.userid IN ({$participatingstudents})\n                                                        AND fdcs.course = {$courseid}\n                                                        AND fdcs.forum = {$instanceid} ";
                                         $this->get_value_from_learning_analytics($benchmarkstudents, $sql, $logtablename, $timefield, $fromtime, $untiltime, $count);
                                     }
                                     // Else only if this is a chat course module
                                 } else {
                                     if ($moduleid == $this->chatmoduleid) {
                                         $logtablename = 'chms';
                                         $timefield = 'timestamp';
                                         $sql = "SELECT DISTINCT (chms.userid) AS userids\n                                                FROM {chat_messages} chms\n                                                WHERE   chms.userid {$selectallstudents}\n                                                    AND chms.system = 0\n                                                    AND chms.chatid = {$instanceid} ";
                                         // Count participating students and return the sql query to count their entries next
                                         $participatingstudents = $this->timestamp_and_count_active_studends_involved($count, $sql, $logtablename, $timefield, $fromtime, $untiltime);
                                         if ($count > 0) {
                                             // If there is at least one student.
                                             $iterations++;
                                             $sql = "SELECT COUNT(chms.id) AS TOTALS\n                                                    FROM {chat_messages} chms\n                                                    WHERE   chms.userid IN ({$participatingstudents})\n                                                        AND chms.system = 0\n                                                        AND chms.chatid = {$instanceid} ";
                                             $this->get_value_from_learning_analytics($benchmarkstudents, $sql, $logtablename, $timefield, $fromtime, $untiltime, $count);
                                         }
                                     }
                                 }
                             }
                         }
                         break;
                         // In case of checking addition occurences of files in forums,
                         // just count the attachement occurences in forum posts.
                     // In case of checking addition occurences of files in forums,
                     // just count the attachement occurences in forum posts.
                     case gradingform_erubric_controller::COLLABORATION_TYPE_FILE_ADDS:
                         $sql = "SELECT COUNT(fls.id) AS TOTALS\n                                    FROM {forum_posts} fp\n                                        INNER JOIN {forum_discussions} fd ON (fd.id = fp.discussion)\n                                        INNER JOIN {files} fls ON (fls.itemid = fp.id)\n                                    WHERE   fp.userid {$selectindividual}\n                                        AND fls.filesize > 0\n                                        AND fls.component = 'mod_forum'\n                                        AND fd.forum = {$instanceid} ";
                         $this->get_value_from_learning_analytics($benchmarkstudent, $sql, 'fp', 'created', $fromtime, $untiltime, 1);
                         // If the criterion has a global reference according to all students file submissions,
                         // check all students participated in the forum, even if they haven't submited anything.
                         // Leave out all those who didn't participated in the forum at all.
                         if ($criterion['referencetype'] == gradingform_erubric_controller::REFERENCE_STUDENTS) {
                             $count = 0;
                             $sql = "SELECT DISTINCT (fp.userid) AS userids\n                                        FROM {forum_posts} fp\n                                            INNER JOIN {forum_discussions} fd ON (fd.id = fp.discussion)\n                                        WHERE   fp.userid {$selectallstudents}\n                                            AND fd.forum = {$instanceid} ";
                             $participatingstudents = $this->timestamp_and_count_active_studends_involved($count, $sql, 'fp', 'created', $fromtime, $untiltime);
                             if ($count > 0) {
                                 // If there is at least one student.
                                 $iterations++;
                                 $sql = "SELECT COUNT(fls.id) AS TOTALS\n                                            FROM {forum_posts} fp\n                                                INNER JOIN {forum_discussions} fd ON (fd.id = fp.discussion)\n                                                INNER JOIN {files} fls ON (fls.itemid = fp.id)\n                                            WHERE   fp.userid IN ({$participatingstudents})\n                                                AND fls.filesize > 0\n                                                AND fls.component = 'mod_forum'\n                                                AND fd.forum = {$instanceid} ";
                                 $this->get_value_from_learning_analytics($benchmarkstudents, $sql, 'fp', 'created', $fromtime, $untiltime, $count);
                             }
                         }
                         break;
                         // In case of checking student replies in forums,
                         // just count all student posts except self-replies and the ones referring to root post a.k.a. discussion.
                     // In case of checking student replies in forums,
                     // just count all student posts except self-replies and the ones referring to root post a.k.a. discussion.
                     case gradingform_erubric_controller::COLLABORATION_TYPE_REPLIES:
                         $sql = "SELECT COUNT(fp.id) AS TOTALS\n                                    FROM {forum_posts} fp\n                                        INNER JOIN {forum_discussions} fd ON (fd.id = fp.discussion)\n                                    WHERE fp.userid {$selectindividual}\n                                        AND fp.parent <> 0\n                                        AND fp.parent NOT IN (SELECT fp2.id AS tempids\n                                                              FROM {forum_posts} fp2\n                                                                  INNER JOIN {forum_discussions} fd2 ON (fd2.id = fp2.discussion)\n                                                              WHERE fp2.userid {$selectindividual}\n                                                                  AND fp2.parent <> 0\n                                                                  AND fd2.forum = {$instanceid})\n                                        AND fd.forum = {$instanceid} ";
                         $this->get_value_from_learning_analytics($benchmarkstudent, $sql, 'fp', 'created', $fromtime, $untiltime, 1);
                         // If the criterion has a global reference according to all students replies.
                         if ($criterion['referencetype'] == gradingform_erubric_controller::REFERENCE_STUDENTS) {
                             $count = 0;
                             $sql = "SELECT DISTINCT (fp.userid) AS userids\n                                        FROM {forum_posts} fp\n                                            INNER JOIN {forum_discussions} fd ON (fd.id = fp.discussion)\n                                        WHERE fp.userid {$selectallstudents}\n                                            AND fp.parent <> 0\n                                            AND fp.parent NOT IN (SELECT fp2.id AS tempids\n                                                                  FROM {forum_posts} fp2\n                                                                      INNER JOIN {forum_discussions} fd2 ON (fd2.id = fp2.discussion)\n                                                                  WHERE fp2.userid = fp.userid\n                                                                      AND fp2.parent <> 0\n                                                                      AND fd2.forum = {$instanceid})\n                                            AND fd.forum = {$instanceid} ";
                             $participatingstudents = $this->timestamp_and_count_active_studends_involved($count, $sql, 'fp', 'created', $fromtime, $untiltime);
                             if ($count > 0) {
                                 // If there is at least one student.
                                 $iterations++;
                                 $sql = "SELECT COUNT(fp.id) AS TOTALS\n                                            FROM {forum_posts} fp\n                                                INNER JOIN {forum_discussions} fd ON (fd.id = fp.discussion)\n                                            WHERE   fp.userid IN ({$participatingstudents})\n                                                AND fp.parent <> 0\n                                                AND fp.parent NOT IN (SELECT fp2.id AS tempids\n                                                                  FROM {forum_posts} fp2\n                                                                      INNER JOIN {forum_discussions} fd2 ON (fd2.id = fp2.discussion)\n                                                                  WHERE fp2.userid = fp.userid\n                                                                      AND fp2.parent <> 0\n                                                                      AND fd2.forum = {$instanceid})\n                                                AND fd.forum = {$instanceid} ";
                                 $this->get_value_from_learning_analytics($benchmarkstudents, $sql, 'fp', 'created', $fromtime, $untiltime, $count);
                             }
                         }
                         break;
                         // In case of checking the number of distinct students, the evaluated student has interacted, in forums or chats...
                         // 1. Retrieve all student ids (including the evaluated) for each course module.
                         // 2. Check if current evaluated student's id exists in each module of interacted student's ids.
                         // 3. Update the pile of current evaluated student's, interacted user's ids.
                         // 4. Count the pile's size to retieve the number of all students' ids,
                         //    thus get the nubmer of all students the current one interacted.
                         // In case of checking all students do the above for every student interacted in each course module...
                         //    (!!!Run time possible delay or script timeout for checking many users!!!)
                     // In case of checking the number of distinct students, the evaluated student has interacted, in forums or chats...
                     // 1. Retrieve all student ids (including the evaluated) for each course module.
                     // 2. Check if current evaluated student's id exists in each module of interacted student's ids.
                     // 3. Update the pile of current evaluated student's, interacted user's ids.
                     // 4. Count the pile's size to retieve the number of all students' ids,
                     //    thus get the nubmer of all students the current one interacted.
                     // In case of checking all students do the above for every student interacted in each course module...
                     //    (!!!Run time possible delay or script timeout for checking many users!!!)
                     case gradingform_erubric_controller::COLLABORATION_TYPE_INTERACTIONS:
                         if ($moduleid == $this->forummoduleid) {
                             // Check forum modules.
                             // Get each forum discussion and check interactions.
                             $tempsql = "SELECT fd.id AS discussionid FROM {forum_discussions} fd WHERE fd.forum = {$instanceid}";
                             $discussions = $DB->get_records_sql($tempsql, null);
                             foreach ($discussions as $dscn) {
                                 $discussionid = $dscn->discussionid;
                                 $sql = "SELECT DISTINCT(fp.userid) AS usersid\n                                            FROM {forum_posts} fp\n                                                INNER JOIN {forum_discussions} fd ON (fd.id = fp.discussion)\n                                            WHERE fd.forum = {$instanceid}\n                                                AND fd.id = {$discussionid}\n                                                AND fp.userid {$selectallstudents} ";
                                 // This line added to ensure that only students are accounted.
                                 $tempusersarray = null;
                                 $this->get_value_from_learning_analytics($tempusersarray, $sql, 'fp', 'created', $fromtime, $untiltime, null);
                                 if ($criterion['referencetype'] == gradingform_erubric_controller::REFERENCE_STUDENT) {
                                     // Check only current student evaluated.
                                     if (!is_null($tempusersarray)) {
                                         $studentin = false;
                                         // Check all participating students to see if current student's id was in.
                                         foreach ($tempusersarray as $tempid) {
                                             if (isset($tempid->usersid) && $tempid->usersid == $studentid) {
                                                 $studentin = true;
                                                 break;
                                             }
                                         }
                                         if ($studentin) {
                                             // If student took part in that discussion.
                                             foreach ($tempusersarray as $tempid) {
                                                 // Check all participating students.
                                                 // If temp user id not the same with the student's and is unique, add to pile.
                                                 if ($tempid->usersid != $studentid && (!isset($distinctUsersFound[$studentid]) || !in_array($tempid->usersid, $distinctUsersFound[$studentid]))) {
                                                     $distinctUsersFound[$studentid][] = $tempid->usersid;
                                                 }
                                             }
                                         }
                                     }
                                     // Check all students along with the current student evaluated, if there are any.
                                 } else {
                                     if (!is_null($tempusersarray)) {
                                         // Check all participating students in order to create and update
                                         // each one's unique pile of interactions.
                                         foreach ($tempusersarray as $tempcurrentid) {
                                             // loop A
                                             // Check all participating students again, to update the pile of the user selected by previous loop.
                                             foreach ($tempusersarray as $tempid) {
                                                 // loop B
                                                 // If temp user's id (loop B) is unique and not the same with user's id (loop A),
                                                 // add to pile (of user A).
                                                 if (isset($tempid->usersid) && isset($tempcurrentid->usersid) && $tempid->usersid != $tempcurrentid->usersid && (!isset($distinctUsersFound[$tempcurrentid->usersid]) || !in_array($tempid->usersid, $distinctUsersFound[$tempcurrentid->usersid]))) {
                                                     $distinctUsersFound[$tempcurrentid->usersid][] = $tempid->usersid;
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         } else {
                             // Check chat modules.
                             $tempusersarray = $this->get_interacted_users_according_to_chat_sessions($instanceid, $fromtime, $untiltime);
                             if (empty($tempusersarray)) {
                                 break;
                             }
                             if ($criterion['referencetype'] == gradingform_erubric_controller::REFERENCE_STUDENT) {
                                 // Check only current student evaluated.
                                 // Go through all chat sessions to distinct interacted students.
                                 foreach ($tempusersarray as $tempsession) {
                                     foreach ($tempsession as $tempuserid) {
                                         // If temp user id not the same with the student's and is unique, add to pile.
                                         if ($tempuserid != $studentid && (!isset($distinctUsersFound[$studentid]) || !in_array($tempuserid, $distinctUsersFound[$studentid]))) {
                                             $distinctUsersFound[$studentid][] = $tempuserid;
                                         }
                                     }
                                 }
                             } else {
                                 // Check all participating students in order to create and update
                                 // each one's unique pile of interactions.
                                 foreach ($tempusersarray as $tempsession) {
                                     // Iterate through all chat sessions.
                                     foreach ($tempsession as $tempuserid1) {
                                         // Get users list.
                                         foreach ($tempusersarray as $tempuserid2) {
                                             // Get users list again.
                                             // If temp2 user id not the same with temp1's and is unique, add to temp1's pile.
                                             if ($tempuserid1 != $tempuserid2 && (!isset($distinctUsersFound[$tempuserid1]) || !in_array($tempuserid2, $distinctUsersFound[$tempuserid1]))) {
                                                 $distinctUsersFound[$tempuserid1][] = $tempuserid2;
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                         break;
                 }
             }
             break;
     }
     // When user interactions are checked, benchmarks are calculated after all course modules are processed and only if there are interactions.
     if ($criterion['collaborationtype'] == gradingform_erubric_controller::COLLABORATION_TYPE_INTERACTIONS && !empty($distinctUsersFound)) {
         if (array_key_exists($studentid, $distinctUsersFound)) {
             // Check current student evaluated.
             $benchmarkstudent = count($distinctUsersFound[$studentid]);
         } else {
             $benchmarkstudent = 0;
         }
         if ($criterion['referencetype'] == gradingform_erubric_controller::REFERENCE_STUDENTS) {
             // Check all students participated.
             $benchmarkstudents = 0;
             $iterations = count($distinctUsersFound);
             foreach ($distinctUsersFound as $tempstudentid => $otherstudents) {
                 $benchmarkstudents += count($distinctUsersFound[$tempstudentid]);
             }
         }
     }
     // If there is a benchmark for current student evaluated, calculate the criterion benchmark. Else do nothing, leave everything null.
     if (!is_null($benchmarkstudent)) {
         if ($criterion['collaborationtype'] != gradingform_erubric_controller::COLLABORATION_TYPE_INTERACTIONS && ($criterion['criteriontype'] == gradingform_erubric_controller::INTERACTION_TYPE_GRADE || $criterion['referencetype'] == gradingform_erubric_controller::REFERENCE_STUDENTS)) {
             $benchmarkstudent = (double) round($benchmarkstudent / $iterations, 2);
         }
         if ($criterion['referencetype'] == gradingform_erubric_controller::REFERENCE_STUDENTS) {
             // Check students benchmark.
             if ($benchmarkstudents) {
                 // To avoid division by zero for small students' benchmark, make two point precision rounding.
                 $benchmarkstudents = (double) round($benchmarkstudents / $iterations, 2);
                 $benchmarkcriterion = (int) round($benchmarkstudent * 100 / $benchmarkstudents);
             } else {
                 $benchmarkcriterion = null;
             }
         } else {
             $benchmarkcriterion = (int) $benchmarkstudent;
             // Just convert student benchmark to integer.
         }
     }
     // Run enrichment procedure to return the appropriate selected level (if exists),
     // and store criterion benchmarks for future reference.
     $criterion['checkedenrich'] = $this->get_enriched_level_from_benchmark($criterion['levels'], $benchmarkcriterion, $criterion['operator'], $options['sortlevelsasc']);
     $criterion['enrichedbenchmark'] = $benchmarkcriterion;
     $criterion['enrichedbenchmarkstudent'] = $benchmarkstudent;
     $criterion['enrichedbenchmarkstudents'] = $benchmarkstudents;
 }