Skip to content

Commit

Permalink
Merge branch 'MDL-48715' of git://github.com/jmvedrine/moodle
Browse files Browse the repository at this point in the history
  • Loading branch information
David Monllao committed Mar 18, 2015
2 parents 63fe1c1 + 10e2355 commit 7794f80
Show file tree
Hide file tree
Showing 10 changed files with 186 additions and 18 deletions.
2 changes: 1 addition & 1 deletion mod/lesson/backup/moodle2/backup_lesson_stepslib.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ protected function define_structure() {
'mediafile', 'mediaheight', 'mediawidth', 'mediaclose', 'slideshow',
'width', 'height', 'bgcolor', 'displayleft', 'displayleftif', 'progressbar',
'showhighscores', 'maxhighscores', 'available', 'deadline', 'timemodified',
'completionendreached'
'completionendreached', 'completiontimespent'
));
// Tell the lesson element about the showhighscores elements mapping to the highscores
// database field.
Expand Down
5 changes: 4 additions & 1 deletion mod/lesson/backup/moodle2/restore_lesson_stepslib.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,13 @@ protected function process_lesson($data) {
unset($data->showhighscores);
}

// Supply item that maybe missing from previous versions.
// Supply items that maybe missing from previous versions.
if (!isset($data->completionendreached)) {
$data->completionendreached = 0;
}
if (!isset($data->completiontimespent)) {
$data->completiontimespent = 0;
}

// Compatibility with old backups with maxtime and timed fields.
if (!isset($data->timelimit)) {
Expand Down
1 change: 1 addition & 0 deletions mod/lesson/db/install.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
<FIELD NAME="deadline" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="completionendreached" TYPE="int" LENGTH="1" NOTNULL="false" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="completiontimespent" TYPE="int" LENGTH="11" NOTNULL="false" DEFAULT="0" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
Expand Down
15 changes: 15 additions & 0 deletions mod/lesson/db/upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -217,5 +217,20 @@ function xmldb_lesson_upgrade($oldversion) {
upgrade_mod_savepoint(true, 2015030401, 'lesson');
}

if ($oldversion < 2015031500) {

// Define field completiontimespent to be added to lesson.
$table = new xmldb_table('lesson');
$field = new xmldb_field('completiontimespent', XMLDB_TYPE_INTEGER, '11', null, null, null, '0', 'completionendreached');

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

// Lesson savepoint reached.
upgrade_mod_savepoint(true, 2015031500, 'lesson');
}

return true;
}
3 changes: 3 additions & 0 deletions mod/lesson/lang/en/lesson.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@
$string['completethefollowingconditions'] = 'You must complete the following condition(s) in <b>{$a}</b> lesson before you can proceed.';
$string['completionendreached'] = 'Require end reached';
$string['completionendreached_desc'] = 'Student must reach the end of lesson page to complete this activity';
$string['completiontimespent'] = 'Student must do this activity for';
$string['completiontimespentgroup'] = 'Require time spent';
$string['conditionsfordependency'] = 'Condition(s) for the dependency';
$string['configactionaftercorrectanswer'] = 'The default action to take after a correct answer';
$string['configmaxanswers'] = 'Default maximum number of answers per page';
Expand Down Expand Up @@ -324,6 +326,7 @@
$string['notcompleted'] = 'Not completed';
$string['notdefined'] = 'Not defined';
$string['notenoughsubquestions'] = 'Not enough sub-questions have been defined!';
$string['notenoughtimespent'] = 'You completed this lesson in {$a->timespent}, which is less than the required time of {$a->timerequired}. You might need to attempt the lesson again.';
$string['nothighscore'] = 'You did not make the top {$a} high scores list.';
$string['notitle'] = 'No title';
$string['numberofcorrectanswers'] = 'Number of correct answers: {$a}';
Expand Down
28 changes: 24 additions & 4 deletions mod/lesson/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -779,14 +779,34 @@ function lesson_get_completion_state($course, $cm, $userid, $type) {
$lesson = $DB->get_record('lesson', array('id' => $cm->instance), '*',
MUST_EXIST);

$result = $type; // Default return value.
// If completion option is enabled, evaluate it and return true/false.
if ($lesson->completionendreached) {
return $DB->record_exists('lesson_timer', array(
$value = $DB->record_exists('lesson_timer', array(
'lessonid' => $lesson->id, 'userid' => $userid, 'completed' => 1));
} else {
// Completion option is not enabled so just return $type.
return $type;
if ($type == COMPLETION_AND) {
$result = $result && $value;
} else {
$result = $result || $value;
}
}
if ($lesson->completiontimespent != 0) {
$duration = $DB->get_field_sql(
"SELECT SUM(lessontime - starttime)
FROM {lesson_timer}
WHERE lessonid = :lessonid
AND userid = :userid",
array('userid' => $userid, 'lessonid' => $lesson->id));
if (!$duration) {
$duration = 0;
}
if ($type == COMPLETION_AND) {
$result = $result && ($lesson->completiontimespent < $duration);
} else {
$result = $result || ($lesson->completiontimespent < $duration);
}
}
return $result;
}
/**
* This function extends the settings navigation block for the site.
Expand Down
48 changes: 38 additions & 10 deletions mod/lesson/mod_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -294,22 +294,26 @@ function definition() {
/**
* Enforce defaults here
*
* @param array $default_values Form defaults
* @param array $defaultvalues Form defaults
* @return void
**/
function data_preprocessing(&$default_values) {
if (isset($default_values['conditions'])) {
$conditions = unserialize($default_values['conditions']);
$default_values['timespent'] = $conditions->timespent;
$default_values['completed'] = $conditions->completed;
$default_values['gradebetterthan'] = $conditions->gradebetterthan;
public function data_preprocessing(&$defaultvalues) {
if (isset($defaultvalues['conditions'])) {
$conditions = unserialize($defaultvalues['conditions']);
$defaultvalues['timespent'] = $conditions->timespent;
$defaultvalues['completed'] = $conditions->completed;
$defaultvalues['gradebetterthan'] = $conditions->gradebetterthan;
}

// Set up the completion checkbox which is not part of standard data.
$defaultvalues['completiontimespentenabled'] =
!empty($defaultvalues['completiontimespent']) ? 1 : 0;

if ($this->current->instance) {
// Editing existing instance - copy existing files into draft area.
$draftitemid = file_get_submitted_draft_itemid('mediafile');
file_prepare_draft_area($draftitemid, $this->context->id, 'mod_lesson', 'mediafile', 0, array('subdirs'=>0, 'maxbytes' => $this->course->maxbytes, 'maxfiles' => 1));
$default_values['mediafile'] = $draftitemid;
$defaultvalues['mediafile'] = $draftitemid;
}
}

Expand Down Expand Up @@ -339,7 +343,16 @@ public function add_completion_rules() {

$mform->addElement('checkbox', 'completionendreached', get_string('completionendreached', 'lesson'),
get_string('completionendreached_desc', 'lesson'));
return array('completionendreached');

$group = array();
$group[] =& $mform->createElement('checkbox', 'completiontimespentenabled', '',
get_string('completiontimespent', 'lesson'));
$group[] =& $mform->createElement('duration', 'completiontimespent', array('optional' => true));
$mform->addGroup($group, 'completiontimespentgroup', get_string('completiontimespentgroup', 'lesson'), array(' '), false);
$mform->disabledIf('completiontimespent[number]', 'completiontimespentenabled', 'notchecked');
$mform->disabledIf('completiontimespent[timeunit]', 'completiontimespentenabled', 'notchecked');

return array('completionendreached', 'completiontimespentgroup');
}

/**
Expand All @@ -349,7 +362,22 @@ public function add_completion_rules() {
* @return bool True if one or more rules is enabled, false if none are.
*/
public function completion_rule_enabled($data) {
return !empty($data['completionendreached']);
return !empty($data['completionendreached']) || $data['completiontimespent'] > 0;
}

public function get_data() {
$data = parent::get_data();
if (!$data) {
return false;
}
// Turn off completion setting if the checkbox is not ticked.
if (!empty($data->completionunlocked)) {
$autocompletion = !empty($data->completion) && $data->completion == COMPLETION_TRACKING_AUTOMATIC;
if (empty($data->completiontimespentenabled) || !$autocompletion) {
$data->completiontimespent = 0;
}
}
return $data;
}
}

77 changes: 77 additions & 0 deletions mod/lesson/tests/behat/completion_condition_time_spent.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
@mod @mod_lesson
Feature: Set time spent as a completion condition for a lesson
In order to ensure students spend the needed time to study lessons
As a teacher
I need to set time spent to mark the lesson activity as completed

@javascript
Scenario: Set time spent as a condition
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | 1 | student1@asd.com |
| teacher1 | Teacher | 1 | teacher1@asd.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
And I log in as "admin"
And I set the following administration settings values:
| Enable completion tracking | 1 |
And I log out
And I log in as "teacher1"
And I follow "Course 1"
And I turn editing mode on
And I click on "Edit settings" "link" in the "Administration" "block"
And I set the following fields to these values:
| Enable completion tracking | Yes |
And I press "Save and display"
And I add a "Lesson" to section "1" and I fill the form with:
| Name | Test lesson |
| Description | Test lesson description |
| Completion tracking | Show activity as complete when conditions are met |
| completiontimespentenabled | 1 |
| completiontimespent[timeunit] | 60 |
| completiontimespent[number] | 1 |
And I follow "Test lesson"
And I follow "Add a content page"
And I set the following fields to these values:
| Page title | First page name |
| Page contents | First page contents |
| id_answer_editor_0 | Next page |
| id_jumpto_0 | Next page |
And I press "Save page"
And I set the field "qtype" to "Add a content page"
And I set the following fields to these values:
| Page title | Second page name |
| Page contents | Second page contents |
| id_answer_editor_0 | Previous page |
| id_jumpto_0 | Previous page |
| id_answer_editor_1 | Next page |
| id_jumpto_1 | Next page |
And I press "Save page"
And I log out
When I log in as "student1"
And I follow "Course 1"
Then I hover "//li[contains(concat(' ', normalize-space(@class), ' '), ' modtype_lesson ')]/descendant::img[@alt='Not completed: Test lesson']" "xpath_element"
And I follow "Test lesson"
And I press "Next page"
And I press "Next page"
And I should see "You completed this lesson in"
And I should see ", which is less than the required time of 1 min. You might need to attempt the lesson again."
And I follow "Course 1"
And I hover "//li[contains(concat(' ', normalize-space(@class), ' '), ' modtype_lesson ')]/descendant::img[@alt='Not completed: Test lesson']" "xpath_element"
And I follow "Course 1"
And I follow "Test lesson"
And I press "Next page"
And I wait "61" seconds
And I press "Next page"
And I should not see "You might need to attempt the lesson again."
And I follow "Course 1"
And I hover "//li[contains(concat(' ', normalize-space(@class), ' '), ' modtype_lesson ')]/descendant::img[@alt='Completed: Test lesson']" "xpath_element"
And I log out
And I log in as "teacher1"
And I follow "Course 1"
And "Student 1" user has completed "Test lesson" activity
2 changes: 1 addition & 1 deletion mod/lesson/version.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

defined('MOODLE_INTERNAL') || die();

$plugin->version = 2015030401; // The current module version (Date: YYYYMMDDXX)
$plugin->version = 2015031500; // The current module version (Date: YYYYMMDDXX)
$plugin->requires = 2014110400; // Requires this Moodle version
$plugin->component = 'mod_lesson'; // Full name of the plugin (used for diagnostics)
$plugin->cron = 0;
23 changes: 22 additions & 1 deletion mod/lesson/view.php
Original file line number Diff line number Diff line change
Expand Up @@ -458,10 +458,31 @@

// Update completion state.
$completion = new completion_info($course);
if ($completion->is_enabled($cm) && $lesson->completionendreached) {
if ($completion->is_enabled($cm) && ($lesson->completionendreached || $lesson->completiontimespent > 0)) {
$completion->update_state($cm, COMPLETION_COMPLETE);
}

if ($lesson->completiontimespent > 0) {
$duration = $DB->get_field_sql(
"SELECT SUM(lessontime - starttime)
FROM {lesson_timer}
WHERE lessonid = :lessonid
AND userid = :userid",
array('userid' => $USER->id, 'lessonid' => $lesson->id));
if (!$duration) {
$duration = 0;
}

// If student has not spend enough time in the lesson, display a message.
if ($duration < $lesson->completiontimespent) {
$a = new stdClass;
$a->timespent = format_time($duration);
$a->timerequired = format_time($lesson->completiontimespent);
$lessoncontent .= $lessonoutput->paragraph(get_string("notenoughtimespent", "lesson", $a), 'center');
}
}


if ($gradeinfo->attempts) {
if (!$lesson->custom) {
$lessoncontent .= $lessonoutput->paragraph(get_string("numberofpagesviewed", "lesson", $gradeinfo->nquestions), 'center');
Expand Down

0 comments on commit 7794f80

Please sign in to comment.