Merge branch 'MDL-57760-master' of git://github.com/jleyva/moodle

This commit is contained in:
David Monllao 2017-03-27 13:39:44 +02:00
commit 76e4853585
5 changed files with 232 additions and 67 deletions

View file

@ -1883,4 +1883,99 @@ class mod_lesson_external extends external_api {
)
);
}
/**
* Describes the parameters for get_pages_possible_jumps.
*
* @return external_external_function_parameters
* @since Moodle 3.3
*/
public static function get_pages_possible_jumps_parameters() {
return new external_function_parameters (
array(
'lessonid' => new external_value(PARAM_INT, 'lesson instance id'),
)
);
}
/**
* Return all the possible jumps for the pages in a given lesson.
*
* You may expect different results on consecutive executions due to the random nature of the lesson module.
*
* @param int $lessonid lesson instance id
* @return array of warnings and possible jumps
* @since Moodle 3.3
* @throws moodle_exception
*/
public static function get_pages_possible_jumps($lessonid) {
global $USER;
$params = array('lessonid' => $lessonid);
$params = self::validate_parameters(self::get_pages_possible_jumps_parameters(), $params);
$warnings = $jumps = array();
list($lesson, $course, $cm, $context) = self::validate_lesson($params['lessonid']);
// Only return for managers or if offline attempts are enabled.
if ($lesson->can_manage() || $lesson->allowofflineattempts) {
$lessonpages = $lesson->load_all_pages();
foreach ($lessonpages as $page) {
$jump = array();
$jump['pageid'] = $page->id;
$answers = $page->get_answers();
if (count($answers) > 0) {
foreach ($answers as $answer) {
$jump['answerid'] = $answer->id;
$jump['jumpto'] = $answer->jumpto;
$jump['calculatedjump'] = $lesson->calculate_new_page_on_jump($page, $answer->jumpto);
// Special case, only applies to branch/end of branch.
if ($jump['calculatedjump'] == LESSON_RANDOMBRANCH) {
$jump['calculatedjump'] = lesson_unseen_branch_jump($lesson, $USER->id);
}
$jumps[] = $jump;
}
} else {
// Imported lessons from 1.x.
$jump['answerid'] = 0;
$jump['jumpto'] = $page->nextpageid;
$jump['calculatedjump'] = $lesson->calculate_new_page_on_jump($page, $page->nextpageid);
$jumps[] = $jump;
}
}
}
$result = array(
'jumps' => $jumps,
'warnings' => $warnings,
);
return $result;
}
/**
* Describes the get_pages_possible_jumps return value.
*
* @return external_single_structure
* @since Moodle 3.3
*/
public static function get_pages_possible_jumps_returns() {
return new external_single_structure(
array(
'jumps' => new external_multiple_structure(
new external_single_structure(
array(
'pageid' => new external_value(PARAM_INT, 'The page id'),
'answerid' => new external_value(PARAM_INT, 'The answer id'),
'jumpto' => new external_value(PARAM_INT, 'The jump (page id or type of jump)'),
'calculatedjump' => new external_value(PARAM_INT, 'The real page id (or EOL) to jump'),
), 'Jump for a page answer'
)
),
'warnings' => new external_warnings(),
)
);
}
}

View file

@ -148,4 +148,12 @@ $functions = array(
'capabilities' => 'mod/lesson:viewreports',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
),
'mod_lesson_get_pages_possible_jumps' => array(
'classname' => 'mod_lesson_external',
'methodname' => 'get_pages_possible_jumps',
'description' => 'Return all the possible jumps for the pages in a given lesson.',
'type' => 'read',
'capabilities' => 'mod/lesson:view',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
),
);

View file

@ -3164,6 +3164,85 @@ class lesson extends lesson_base {
return array($page, $lessoncontent);
}
/**
* This returns a real page id to jump to (or LESSON_EOL) after processing page responses.
*
* @param lesson_page $page lesson page
* @param int $newpageid the new page id
* @return int the real page to jump to (or end of lesson)
* @since Moodle 3.3
*/
public function calculate_new_page_on_jump(lesson_page $page, $newpageid) {
global $USER, $DB;
$canmanage = $this->can_manage();
if (isset($USER->modattempts[$this->properties->id])) {
// Make sure if the student is reviewing, that he/she sees the same pages/page path that he/she saw the first time.
if ($USER->modattempts[$this->properties->id]->pageid == $page->id && $page->nextpageid == 0) {
// Remember, this session variable holds the pageid of the last page that the user saw.
$newpageid = LESSON_EOL;
} else {
$nretakes = $DB->count_records("lesson_grades", array("lessonid" => $this->properties->id, "userid" => $USER->id));
$nretakes--; // Make sure we are looking at the right try.
$attempts = $DB->get_records("lesson_attempts", array("lessonid" => $this->properties->id, "userid" => $USER->id, "retry" => $nretakes), "timeseen", "id, pageid");
$found = false;
$temppageid = 0;
// Make sure that the newpageid always defaults to something valid.
$newpageid = LESSON_EOL;
foreach ($attempts as $attempt) {
if ($found && $temppageid != $attempt->pageid) {
// Now try to find the next page, make sure next few attempts do no belong to current page.
$newpageid = $attempt->pageid;
break;
}
if ($attempt->pageid == $page->id) {
$found = true; // If found current page.
$temppageid = $attempt->pageid;
}
}
}
} else if ($newpageid != LESSON_CLUSTERJUMP && $page->id != 0 && $newpageid > 0) {
// Going to check to see if the page that the user is going to view next, is a cluster page.
// If so, dont display, go into the cluster.
// The $newpageid > 0 is used to filter out all of the negative code jumps.
$newpage = $this->load_page($newpageid);
if ($overridenewpageid = $newpage->override_next_page($newpageid)) {
$newpageid = $overridenewpageid;
}
} else if ($newpageid == LESSON_UNSEENBRANCHPAGE) {
if ($canmanage) {
if ($page->nextpageid == 0) {
$newpageid = LESSON_EOL;
} else {
$newpageid = $page->nextpageid;
}
} else {
$newpageid = lesson_unseen_question_jump($this, $USER->id, $page->id);
}
} else if ($newpageid == LESSON_PREVIOUSPAGE) {
$newpageid = $page->prevpageid;
} else if ($newpageid == LESSON_RANDOMPAGE) {
$newpageid = lesson_random_question_jump($this, $page->id);
} else if ($newpageid == LESSON_CLUSTERJUMP) {
if ($canmanage) {
if ($page->nextpageid == 0) { // If teacher, go to next page.
$newpageid = LESSON_EOL;
} else {
$newpageid = $page->nextpageid;
}
} else {
$newpageid = $this->cluster_jump($page->id);
}
} else if ($newpageid == 0) {
$newpageid = $page->id;
} else if ($newpageid == LESSON_NEXTPAGE) {
$newpageid = $this->get_next_page($page->nextpageid);
}
return $newpageid;
}
/**
* Process page responses.
*
@ -3171,9 +3250,6 @@ class lesson extends lesson_base {
* @since Moodle 3.3
*/
public function process_page_responses(lesson_page $page) {
global $USER, $DB;
$canmanage = $this->can_manage();
$context = $this->get_context();
// Check the page has answers [MDL-25632].
@ -3189,64 +3265,10 @@ class lesson extends lesson_base {
if ($result->inmediatejump) {
return $result;
} else if (isset($USER->modattempts[$this->properties->id])) {
// Make sure if the student is reviewing, that he/she sees the same pages/page path that he/she saw the first time.
if ($USER->modattempts[$this->properties->id]->pageid == $page->id && $page->nextpageid == 0) {
// Remember, this session variable holds the pageid of the last page that the user saw.
$result->newpageid = LESSON_EOL;
} else {
$nretakes = $DB->count_records("lesson_grades", array("lessonid" => $this->properties->id, "userid" => $USER->id));
$nretakes--; // Make sure we are looking at the right try.
$attempts = $DB->get_records("lesson_attempts", array("lessonid" => $this->properties->id, "userid" => $USER->id, "retry" => $nretakes), "timeseen", "id, pageid");
$found = false;
$temppageid = 0;
// Make sure that the newpageid always defaults to something valid.
$result->newpageid = LESSON_EOL;
foreach ($attempts as $attempt) {
if ($found && $temppageid != $attempt->pageid) {
// Now try to find the next page, make sure next few attempts do no belong to current page.
$result->newpageid = $attempt->pageid;
break;
}
if ($attempt->pageid == $page->id) {
$found = true; // If found current page.
$temppageid = $attempt->pageid;
}
}
}
} else if ($result->newpageid != LESSON_CLUSTERJUMP && $page->id != 0 && $result->newpageid > 0) {
// Going to check to see if the page that the user is going to view next, is a cluster page.
// If so, dont display, go into the cluster.
// The $result->newpageid > 0 is used to filter out all of the negative code jumps.
$newpage = $this->load_page($result->newpageid);
if ($newpageid = $newpage->override_next_page($result->newpageid)) {
$result->newpageid = $newpageid;
}
} else if ($result->newpageid == LESSON_UNSEENBRANCHPAGE) {
if ($canmanage) {
if ($page->nextpageid == 0) {
$result->newpageid = LESSON_EOL;
} else {
$result->newpageid = $page->nextpageid;
}
} else {
$result->newpageid = lesson_unseen_question_jump($this, $USER->id, $page->id);
}
} else if ($result->newpageid == LESSON_PREVIOUSPAGE) {
$result->newpageid = $page->prevpageid;
} else if ($result->newpageid == LESSON_RANDOMPAGE) {
$result->newpageid = lesson_random_question_jump($this, $page->id);
} else if ($result->newpageid == LESSON_CLUSTERJUMP) {
if ($canmanage) {
if ($page->nextpageid == 0) { // If teacher, go to next page.
$result->newpageid = LESSON_EOL;
} else {
$result->newpageid = $page->nextpageid;
}
} else {
$result->newpageid = $this->cluster_jump($page->id);
}
}
$result->newpageid = $this->calculate_new_page_on_jump($page, $result->newpageid);
return $result;
}
@ -3992,12 +4014,6 @@ abstract class lesson_page extends lesson_base {
}
}
}
// TODO: merge this code with the jump code below. Convert jumpto page into a proper page id
if ($result->newpageid == 0) {
$result->newpageid = $this->properties->id;
} elseif ($result->newpageid == LESSON_NEXTPAGE) {
$result->newpageid = $this->lesson->get_next_page($this->properties->nextpageid);
}
// Determine default feedback if necessary
if (empty($result->response)) {

View file

@ -1236,4 +1236,50 @@ class mod_lesson_external_testcase extends externallib_advanced_testcase {
$this->setExpectedException('moodle_exception');
$result = mod_lesson_external::get_user_attempt($this->lesson->id, $this->teacher->id, 0);
}
/**
* Test get_pages_possible_jumps
*/
public function test_get_pages_possible_jumps() {
$this->setAdminUser();
$result = mod_lesson_external::get_pages_possible_jumps($this->lesson->id);
$result = external_api::clean_returnvalue(mod_lesson_external::get_pages_possible_jumps_returns(), $result);
$this->assertCount(0, $result['warnings']);
$this->assertCount(3, $result['jumps']); // 3 jumps, 2 from the question page and 1 from the content.
foreach ($result['jumps'] as $jump) {
if ($jump['answerid'] != 0) {
// Check only pages with answers.
if ($jump['jumpto'] == 0) {
$this->assertEquals($jump['pageid'], $jump['calculatedjump']); // 0 means to jump to current page.
} else {
// Question is configured to jump to next page if correct.
$this->assertEquals($this->page1->id, $jump['calculatedjump']);
}
}
}
}
/**
* Test get_pages_possible_jumps when offline attemps are disabled for a normal user
*/
public function test_get_pages_possible_jumps_with_offlineattemps_disabled() {
$this->setUser($this->student->id);
$result = mod_lesson_external::get_pages_possible_jumps($this->lesson->id);
$result = external_api::clean_returnvalue(mod_lesson_external::get_pages_possible_jumps_returns(), $result);
$this->assertCount(0, $result['jumps']);
}
/**
* Test get_pages_possible_jumps when offline attemps are enabled for a normal user
*/
public function test_get_pages_possible_jumps_with_offlineattemps_enabled() {
global $DB;
$DB->set_field('lesson', 'allowofflineattempts', 1, array('id' => $this->lesson->id));
$this->setUser($this->student->id);
$result = mod_lesson_external::get_pages_possible_jumps($this->lesson->id);
$result = external_api::clean_returnvalue(mod_lesson_external::get_pages_possible_jumps_returns(), $result);
$this->assertCount(3, $result['jumps']);
}
}

View file

@ -24,7 +24,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2016120516; // The current module version (Date: YYYYMMDDXX)
$plugin->version = 2016120517; // The current module version (Date: YYYYMMDDXX)
$plugin->requires = 2016112900; // Requires this Moodle version
$plugin->component = 'mod_lesson'; // Full name of the plugin (used for diagnostics)
$plugin->cron = 0;