Skip to content

Commit

Permalink
Merge pull request #299 from learnweb/feature/completiontracking
Browse files Browse the repository at this point in the history
Feature/completiontracking
  • Loading branch information
Laur0r authored Aug 26, 2024
2 parents fe1947a + 0f04901 commit 89ad999
Show file tree
Hide file tree
Showing 13 changed files with 493 additions and 9 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/moodle-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ jobs:

- name: Initialise moodle-plugin-ci
run: |
composer create-project -n --no-dev --prefer-dist moodlehq/moodle-plugin-ci ci ^3
composer create-project -n --no-dev --prefer-dist moodlehq/moodle-plugin-ci ci ^4
echo $(cd ci/bin; pwd) >> $GITHUB_PATH
echo $(cd ci/vendor/bin; pwd) >> $GITHUB_PATH
sudo locale-gen en_AU.UTF-8
Expand Down
107 changes: 107 additions & 0 deletions classes/completion/custom_completion.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?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/>.

declare(strict_types=1);

namespace mod_ratingallocate\completion;

use context_module;
use core_completion\activity_custom_completion;

/**
* Activity custom completion subclass for the ratingallocate activity.
*
* Class for defining the custom completion rules of ratingallocate and fetching the completion statuses
* of the custom completion rules for a given ratingallocate instance and a user.
*
* @package mod_ratingallocate
* @copyright Irina Hoppe Uni Münster
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class custom_completion extends activity_custom_completion {

/**
* Fetches the completion state for a given completion rule.
*
* @param string $rule The completion rule.
* @return int The completion state.
* @throws \moodle_exception
*/
public function get_state(string $rule): int {
global $DB;
$status = false;
$this->validate_rule($rule);

$userid = $this->userid;
$instance = $this->cm->instance;

if (!$DB->get_record('ratingallocate', ['id' => $instance])) {
throw new \moodle_exception('Unable to find ratingallocate instance with id ' . $instance);
}

if ($rule == 'completionvote') {
$sql = "SELECT * FROM {ratingallocate_ratings} r INNER JOIN {ratingallocate_choices} c on r.choiceid=c.id " .
"WHERE r.userid= :userid AND c.ratingallocateid= :ratingallocateid AND c.active=1";
$votesofuser = $DB->get_records_sql($sql, ['userid' => $userid, 'ratingallocateid' => $instance]);
$status = count($votesofuser) > 0;
} else if ($rule == 'completionallocation') {
$sql = "SELECT * FROM {ratingallocate_allocations} a INNER JOIN {ratingallocate_choices} c
ON a.choiceid = c.id WHERE userid= :userid AND a.ratingallocateid= :ratingallocateid AND c.active=1";
$allocationsofuser = $DB->get_records_sql($sql, ['userid' => $userid, 'ratingallocateid' => $instance]);
$status = count($allocationsofuser) > 0;
}

return $status ? COMPLETION_COMPLETE : COMPLETION_INCOMPLETE;
}

/**
* Fetch the list of custom completion rules that this module defines.
*
* @return array
*/
public static function get_defined_custom_rules(): array {
return [
'completionvote',
'completionallocation',
];
}

/**
* Returns an associative array of the descriptions of custom completion rules.
*
* @return array
*/
public function get_custom_rule_descriptions(): array {
return [
'completionvote' => get_string('completionvote_desc', RATINGALLOCATE_MOD_NAME),
'completionallocation' => get_string('completionallocation_desc', RATINGALLOCATE_MOD_NAME),
];
}

/**
* Returns an array of all completion rules, in the order they should be displayed to users.
*
* @return array
*/
public function get_sort_order(): array {
return [
'completionview',
'completionvote',
'completionallocation',
];
}
}

2 changes: 2 additions & 0 deletions db/install.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
<FIELD NAME="runalgorithmbycron" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="0 don't run algorithm by cron; 1 run algorithm by cron"/>
<FIELD NAME="algorithmstarttime" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="only set while running"/>
<FIELD NAME="algorithmstatus" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="-1 failure while running algorithm; 0 algorithm has not been running; 1 algorithm running; 2 algorithm finished"/>
<FIELD NAME="completionvote" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Wether completion on vote is enabled"/>
<FIELD NAME="completionallocation" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Wether completion on allocation is enabled"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
Expand Down
19 changes: 19 additions & 0 deletions db/upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -218,5 +218,24 @@ function xmldb_ratingallocate_upgrade($oldversion) {
upgrade_mod_savepoint(true, 2023050900, 'ratingallocate');
}

if ($oldversion < 2024080900) {

// Define completionrules fields to be added to ratingallocate.
$table = new xmldb_table('ratingallocate');
$votefield = new xmldb_field('completionvote', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, false, '0');
$allocationfield = new xmldb_field('completionallocation', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, false, '0');

// Conditionally launch add field notification_send.
if (!$dbman->field_exists($table, $votefield)) {
$dbman->add_field($table, $votefield);
}
if (!$dbman->field_exists($table, $allocationfield)) {
$dbman->add_field($table, $allocationfield);
}

// Ratingallocate savepoint reached.
upgrade_mod_savepoint(true, 2024080900, 'ratingallocate');
}

return true;
}
7 changes: 7 additions & 0 deletions lang/en/ratingallocate.php
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,13 @@
$string['err_required'] = 'You need to provide a value for this field.';
$string['err_minimum'] = 'The minimum value for this field is {$a}.';
$string['err_maximum'] = 'The maximum value for this field is {$a}.';

$string['completionvote'] = "Vote in the activity";
$string['completionallocation'] = "Been allocated to a choice";
$string['completionvote_help'] = "To complete this activity, users have to submit a vote.";
$string['completionallocation_help'] = "To complete this activity, users have to be allocated to a choice.";
$string['completionvote_desc'] = "Vote";
$string['completionallocation_desc'] = "Be allocated";
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Form to edit choices">
$string['show_choices_header'] = 'List of all choices';
Expand Down
48 changes: 46 additions & 2 deletions lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ function ratingallocate_supports($feature) {
return true;
case FEATURE_COMPLETION_TRACKS_VIEWS:
return true;
case FEATURE_COMPLETION_HAS_RULES:
return true;
default :
return null;
}
Expand Down Expand Up @@ -760,12 +762,14 @@ function ratingallocate_reset_course_form_defaults($course) {
* @param stdClass $coursemodule The coursemodule object (record).
* @return cached_cm_info An object on information that the courses
* will know about (most noticeably, an icon).
* @throws dml_exception
*/
function ratingallocate_get_coursemodule_info($coursemodule) {
global $DB;

$dbparams = ['id' => $coursemodule->instance];
if (! $ratingallocate = $DB->get_record('ratingallocate', $dbparams)) {
$fields = 'id, name, intro, introformat, accesstimestart, accesstimestop, completionvote, completionallocation';
if (!$ratingallocate = $DB->get_record(RATINGALLOCATE_MOD_NAME, $dbparams, $fields)) {
return false;
}

Expand All @@ -774,7 +778,13 @@ function ratingallocate_get_coursemodule_info($coursemodule) {

if ($coursemodule->showdescription) {
// Convert intro to html. Do not filter cached version, filters run at display time.
$result->content = format_module_intro('ratingallocate', $ratingallocate, $coursemodule->id, false);
$result->content = format_module_intro(RATINGALLOCATE_MOD_NAME, $ratingallocate, $coursemodule->id, false);
}

// Populate the custom completion rules as key => value pairs, but only if the completion mode is 'automatic'.
if ($coursemodule->completion == COMPLETION_TRACKING_AUTOMATIC) {
$result->customdata['customcompletionrules']['completionvote'] = $ratingallocate->completionvote;
$result->customdata['customcompletionrules']['completionallocation'] = $ratingallocate->completionallocation;
}

// Populate some other values that can be used in calendar or on dashboard.
Expand All @@ -787,3 +797,37 @@ function ratingallocate_get_coursemodule_info($coursemodule) {

return $result;
}

/**
* Callback which returns human-readable strings describing the active completion custom rules for the module instance.
*
* @param cm_info|stdClass $cm object with fields ->completion and ->customdata['customcompletionrules']
* @return array $descriptions the array of descriptions for the custom rules.
*/
function mod_ratingallocate_get_completion_active_rule_descriptions($cm) {
// Values will be present in cm_info, and we assume these are up to date.
if (empty($cm->customdata['customcompletionrules']) || $cm->completion != COMPLETION_TRACKING_AUTOMATIC) {
return [];
}

$descriptions = [];

foreach ($cm->customdata['customcompletionrules'] as $key => $val) {
switch ($key) {
case 'completionvote':
if ($val == 1) {
$descriptions[] = get_string('copletionvotedesc', RATINGALLOCATE_MOD_NAME);
}
break;
case 'completionallocation':
if ($val == 1) {
$descriptions[] = get_string('copletionallocationdesc', RATINGALLOCATE_MOD_NAME);
}
break;
default:
break;
}
}

return $descriptions;
}
Loading

0 comments on commit 89ad999

Please sign in to comment.