Skip to content

Commit

Permalink
WIP: codeclean userstats table
Browse files Browse the repository at this point in the history
  • Loading branch information
TamaroWalter committed Jun 20, 2024
1 parent 34ca1b8 commit 1e58530
Showing 1 changed file with 136 additions and 122 deletions.
258 changes: 136 additions & 122 deletions classes/tables/userstats_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
defined('MOODLE_INTERNAL') || die();

use mod_moodleoverflow\ratings;
global $CFG;
require_once($CFG->dirroot . '/mod/moodleoverflow/lib.php');
require_once($CFG->libdir . '/tablelib.php');

Expand Down Expand Up @@ -69,13 +70,8 @@ public function __construct($uniqueid, $courseid, $moodleoverflow, $url) {

$this->set_attribute('class', 'moodleoverflow-statistics-table');
$this->set_attribute('id', $uniqueid);
$this->define_columns(['username',
'receivedupvotes',
'receiveddownvotes',
'forumactivity',
'courseactivity',
'forumreputation',
'coursereputation', ]);
$this->define_columns(['username', 'receivedupvotes', 'receiveddownvotes', 'forumactivity', 'courseactivity',
'forumreputation', 'coursereputation', ]);
$this->define_baseurl($url);
$this->define_headers([get_string('fullnameuser'),
get_string('userstatsupvotes', 'moodleoverflow'),
Expand All @@ -102,84 +98,6 @@ public function out() {
$this->finish_output();
}

/**
* Method to sort the userstatsdata-table.
*
* @param array $sortorder The sort order array.
*
* @return void
*/
private function sort_table_data($sortorder) {
$key = $sortorder['sortby'];
// The index of each object in usertable is it's value of $key.
$length = count($this->userstatsdata);
if ($sortorder['sortorder'] == 4) {
// 4 means sort in ascending order.
$this->quick_usertable_sort(0, $length - 1, $key, 'asc');
} else if ($sortorder['sortorder'] == 3) {
// 3 means sort in descending order.
$this->quick_usertable_sort(0, $length - 1, $key, 'desc');
}
}

/**
* Sorts userstatsdata with quicksort algorithm.
*
* @param int $low index for quicksort.
* @param int $high index for quicksort.
* @param int $key the column that is being sorted (upvotes, downvotes etc.).
* @param string $order sort in ascending or descending order.
*
* @return void
*/
private function quick_usertable_sort($low, $high, $key, $order) {
if ($low >= $high) {
return;
}
$left = $low;
$right = $high;
$pivot = $this->userstatsdata[intval(($low + $high) / 2)];
$pivot = $pivot->$key;
do {
if ($order == 'asc') {
while ($this->userstatsdata[$left]->$key < $pivot) {
$left++;
}
while ($this->userstatsdata[$right]->$key > $pivot) {
$right--;
}
} else if ($order == 'desc') {
while ($this->userstatsdata[$left]->$key > $pivot) {
$left++;
}
while ($this->userstatsdata[$right]->$key < $pivot) {
$right--;
}
}
if ($left <= $right) {
$temp = $this->userstatsdata[$right];
$this->userstatsdata[$right] = $this->userstatsdata[$left];
$this->userstatsdata[$left] = $temp;
$right--;
$left++;
}
} while ($left <= $right);
if ($low < $right) {
if ($order == 'asc') {
$this->quick_usertable_sort($low, $right, $key, 'asc');
} else if ($order == 'desc') {
$this->quick_usertable_sort($low, $right, $key, 'desc');
}
}
if ($high > $left) {
if ($order == 'asc') {
$this->quick_usertable_sort($left, $high, $key, 'asc');
} else if ($order == 'desc') {
$this->quick_usertable_sort($left, $high, $key, 'desc');
}
}
}

/**
* Method to collect all the data.
* Method will collect all users from the given course and will determine the user statistics
Expand All @@ -198,55 +116,25 @@ public function get_table_data() {
$student = $this->createstudent($user);

foreach ($ratingdata as $row) {
// Is the rating from or for the current student?
if ($row->postuserid !== $student->id && $row->rateuserid !== $student->id) {
continue;
}

// Did the student receive an up- or downvote?
// Only count if the discussion is not anonymous or if the user is not starter of the discussion.
if ($row->postuserid == $student->id &&
(($row->anonymoussetting == 0) || ($row->anonymoussetting == 1 && $row->postuserid != $row->discussuserid))) {
if ($row->rating == RATING_UPVOTE) {
$student->receivedupvotes += 1;
} else if ($row->rating == RATING_DOWNVOTE) {
$student->receiveddownvotes += 1;
}
}
// Only count if the post is not anonymous (no anonymous setting or only questioner anonymous discussion).
$this->process_received_votes($student, $row);

// Did a student submit a rating?
// For solution marks: only count a solution if the discussion is not completely anonymous.
// For helpful marks: only count helpful marks if the discussion is not any kind of anonymous.
// Up and downvotes are always counted.
if ($row->rateuserid == $student->id && !array_key_exists($row->rateid, $student->ratedposts) &&
(($row->rating == RATING_SOLVED && $row->anonymoussetting != 2) ||
($row->rating == RATING_HELPFUL && $row->anonymoussetting == 0) ||
($row->rating == RATING_UPVOTE) ||
($row->rating == RATING_DOWNVOTE))) {

if ($row->moodleoverflowid == $this->moodleoverflowid) {
$student->forumactivity += 1;
}
$student->courseactivity += 1;
$student->ratedposts[$row->rateid] = $row->rateid;
}
$this->process_submitted_ratings($student, $row);

// Did the student write a post? Only count a written post if: the post is not in an anonymous discussion;
// or the post is in a partial anonymous discussion and the user is not the starter of the discussion.
if ($row->postuserid == $student->id && !array_key_exists($row->postid, $student->submittedposts) &&
($row->anonymoussetting == 0 || ($row->anonymoussetting == 1 && $row->postuserid != $row->discussuserid))) {

if ($row->moodleoverflowid == $this->moodleoverflowid) {
$student->forumactivity += 1;
}
$student->courseactivity += 1;
$student->submittedposts[$row->postid] = $row->postid;
}
$this->process_written_posts($student, $row);

}
// Get the user reputation from the course.
$student->forumreputation = ratings::moodleoverflow_get_reputation_instance($this->moodleoverflowid, $student->id);
$student->coursereputation = ratings::moodleoverflow_get_reputation_course($this->courseid, $student->id);
array_push($this->userstatsdata, $student);
$this->userstatsdata[] = $student;
}
}

Expand Down Expand Up @@ -350,7 +238,7 @@ public function col_coursereputation($row) {
}

/**
* Dependeng on the value display success or warning badge.
* Depending on the value display success or warning badge.
* @param int $number
* @return string
*/
Expand All @@ -373,6 +261,8 @@ public function other_cols($colname, $attempt) {
return null;
}

// Helper functions.

/**
* Return a student object.
* @param \stdClass $user
Expand Down Expand Up @@ -421,4 +311,128 @@ private function get_rating_data() {
WHERE discuss.course = ' . $this->courseid . ';';
return $DB->get_records_sql($sqlquery);
}

/**
* Process the received votes for a student.
* @param $student
* @param $row
* @return void
*/
private function process_received_votes(&$student, $row) {
if ($row->postuserid == $student->id &&
(($row->anonymoussetting == 0) || ($row->anonymoussetting == 1 && $row->postuserid != $row->discussuserid))) {
if ($row->rating == RATING_UPVOTE) {
$student->receivedupvotes += 1;
} else if ($row->rating == RATING_DOWNVOTE) {
$student->receiveddownvotes += 1;
}
}
}

/**
* Process the submitted ratings from a student.
* @param $student
* @param $row
* @return void
*/
private function process_submitted_ratings(&$student, $row) {
$solvedcheck = ($row->rating == RATING_SOLVED && $row->anonymoussetting != 2);
$helpfulcheck = ($row->rating == RATING_HELPFUL && $row->anonymoussetting == 0);
$isvote = ($row->rating == RATING_UPVOTE || $row->rating == RATING_DOWNVOTE);

if ($row->rateuserid == $student->id && !array_key_exists($row->rateid, $student->ratedpost)) {
if ($solvedcheck || $helpfulcheck || $isvote) {
if ($row->moodleoverflowid == $this->moodleoverflowid) {
$student->forumactivity++;
}
$student->courseactivity++;
$student->ratedposts[$row->rateid] = $row->rateid;
}
}
}

/**
* Process the written posts from a student.
* @param $student
* @param $row
* @return void
*/
private function process_written_posts(&$student, $row) {
if ($row->postuserid == $student->id && !array_key_exists($row->postid, $student->submittedposts) &&
($row->anonymoussetting == 0 || ($row->anonymoussetting == 1 && $row->postuserid != $row->discussuserid))) {

if ($row->moodleoverflowid == $this->moodleoverflowid) {
$student->forumactivity += 1;
}
$student->courseactivity += 1;
$student->submittedposts[$row->postid] = $row->postid;
}
}
// Sort function.

/**
* Method to sort the userstatsdata-table.
* @param array $sortorder The sort order array.
* @return void
*/
private function sort_table_data($sortorder) {
$key = $sortorder['sortby'];
// The index of each object in usertable is it's value of $key.
$length = count($this->userstatsdata);
if ($sortorder['sortorder'] == 4) {
// 4 means sort in ascending order.
$this->quick_usertable_sort(0, $length - 1, $key, 'asc');
} else if ($sortorder['sortorder'] == 3) {
// 3 means sort in descending order.
$this->quick_usertable_sort(0, $length - 1, $key, 'desc');
}
}

/**
* Sorts userstatsdata with quicksort algorithm.
*
* @param int $low index for quicksort.
* @param int $high index for quicksort.
* @param int $key the column that is being sorted (upvotes, downvotes etc.).
* @param string $order sort in ascending or descending order.
* @return void
*/
private function quick_usertable_sort($low, $high, $key, $order) {
if ($low >= $high) {
return;
}
$left = $low;
$right = $high;
$pivot = $this->userstatsdata[intval(($low + $high) / 2)]->key;

$compare = function($a, $b) use ($order) {
if ($order == 'asc') {
return $a < $b;
} else {
return $a > $b;
}
};

do {
while ($compare($this->userstatsdata[$left]->$key, $pivot)) {
$left++;
}
while ($compare($pivot, $this->userstatsdata[$right]->$key)) {
$right--;
}
if ($left <= $right) {
$temp = $this->userstatsdata[$right];
$this->userstatsdata[$right] = $this->userstatsdata[$left];
$this->userstatsdata[$left] = $temp;
$right--;
$left++;
}
} while ($left <= $right);
if ($low < $right) {
$this->quick_usertable_sort($low, $right, $key, $order);
}
if ($high > $left) {
$this->quick_usertable_sort($left, $high, $key, $order);
}
}
}

0 comments on commit 1e58530

Please sign in to comment.