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

This commit is contained in:
David Monllao
2017-03-21 21:18:11 +01:00
7 changed files with 507 additions and 171 deletions
+258 -41
View File
@@ -951,6 +951,70 @@ class mod_lesson_external extends external_api {
);
}
/**
* Describes the external structure for a lesson page.
*
* @return external_single_structure
* @since Moodle 3.3
*/
protected static function get_page_structure() {
return new external_single_structure(
array(
'id' => new external_value(PARAM_INT, 'The id of this lesson page'),
'lessonid' => new external_value(PARAM_INT, 'The id of the lesson this page belongs to'),
'prevpageid' => new external_value(PARAM_INT, 'The id of the page before this one'),
'nextpageid' => new external_value(PARAM_INT, 'The id of the next page in the page sequence'),
'qtype' => new external_value(PARAM_INT, 'Identifies the page type of this page'),
'qoption' => new external_value(PARAM_INT, 'Used to record page type specific options'),
'layout' => new external_value(PARAM_INT, 'Used to record page specific layout selections'),
'display' => new external_value(PARAM_INT, 'Used to record page specific display selections'),
'timecreated' => new external_value(PARAM_INT, 'Timestamp for when the page was created'),
'timemodified' => new external_value(PARAM_INT, 'Timestamp for when the page was last modified'),
'title' => new external_value(PARAM_RAW, 'The title of this page', VALUE_OPTIONAL),
'contents' => new external_value(PARAM_RAW, 'The contents of this page', VALUE_OPTIONAL),
'contentsformat' => new external_format_value('contents', VALUE_OPTIONAL),
'displayinmenublock' => new external_value(PARAM_BOOL, 'Toggles display in the left menu block'),
'type' => new external_value(PARAM_INT, 'The type of the page [question | structure]'),
'typeid' => new external_value(PARAM_INT, 'The unique identifier for the page type'),
'typestring' => new external_value(PARAM_RAW, 'The string that describes this page type'),
),
'Page fields'
);
}
/**
* Returns the fields of a page object
* @param lesson_page $page the lesson page
* @param bool $returncontents whether to return the page title and contents
* @return stdClass the fields matching the external page structure
* @since Moodle 3.3
*/
protected static function get_page_fields(lesson_page $page, $returncontents = false) {
$lesson = $page->lesson;
$context = $lesson->context;
$pagedata = new stdClass; // Contains the data that will be returned by the WS.
// Return the visible data.
$visibleproperties = array('id', 'lessonid', 'prevpageid', 'nextpageid', 'qtype', 'qoption', 'layout', 'display',
'displayinmenublock', 'type', 'typeid', 'typestring', 'timecreated', 'timemodified');
foreach ($visibleproperties as $prop) {
$pagedata->{$prop} = $page->{$prop};
}
// Check if we can see title (contents required custom rendering, we won't returning it here @see get_page_data).
$canmanage = $lesson->can_manage();
// If we are managers or the menu block is enabled and is a content page visible always return contents.
if ($returncontents || $canmanage || (lesson_displayleftif($lesson) && $page->displayinmenublock && $page->display)) {
$pagedata->title = external_format_string($page->title, $context->id);
list($pagedata->contents, $pagedata->contentsformat) =
external_format_text($page->contents, $page->contentsformat, $context->id, 'mod_lesson', 'page_contents', $page->id);
}
return $pagedata;
}
/**
* Describes the parameters for get_pages.
*
@@ -988,21 +1052,10 @@ class mod_lesson_external extends external_api {
$pages = array();
foreach ($lessonpages as $page) {
$pagedata = new stdClass; // Contains the data that will be returned by the WS
$pagedata = new stdClass();
// Return the visible data.
$visibleproperties = array('id', 'lessonid', 'prevpageid', 'nextpageid', 'qtype', 'qoption', 'layout', 'display',
'displayinmenublock', 'type', 'typeid', 'typestring', 'timecreated', 'timemodified');
foreach ($visibleproperties as $prop) {
$pagedata->{$prop} = $page->{$prop};
}
// Check if we can see title (contents required custom rendering, we won't returning it here @see get_page_data).
$canmanage = $lesson->can_manage();
// If we are managers or the menu block is enabled and is a content page visible.
if ($canmanage || (lesson_displayleftif($lesson) && $page->displayinmenublock && $page->display)) {
$pagedata->title = external_format_string($page->title, $context->id);
}
// Get the page object fields.
$pagedata->page = self::get_page_fields($page);
// Now, calculate the file area files (maybe we need to download a lesson for offline usage).
$pagedata->filescount = 0;
@@ -1047,21 +1100,7 @@ class mod_lesson_external extends external_api {
'pages' => new external_multiple_structure(
new external_single_structure(
array(
'id' => new external_value(PARAM_INT, 'The id of this lesson page'),
'lessonid' => new external_value(PARAM_INT, 'The id of the lesson this page belongs to'),
'prevpageid' => new external_value(PARAM_INT, 'The id of the page before this one'),
'nextpageid' => new external_value(PARAM_INT, 'The id of the next page in the page sequence'),
'qtype' => new external_value(PARAM_INT, 'Identifies the page type of this page'),
'qoption' => new external_value(PARAM_INT, 'Used to record page type specific options'),
'layout' => new external_value(PARAM_INT, 'Used to record page specific layout selections'),
'display' => new external_value(PARAM_INT, 'Used to record page specific display selections'),
'timecreated' => new external_value(PARAM_INT, 'Timestamp for when the page was created'),
'timemodified' => new external_value(PARAM_INT, 'Timestamp for when the page was last modified'),
'title' => new external_value(PARAM_RAW, 'The title of this page', VALUE_OPTIONAL),
'displayinmenublock' => new external_value(PARAM_BOOL, 'Toggles display in the left menu block'),
'type' => new external_value(PARAM_INT, 'The type of the page [question | structure]'),
'typeid' => new external_value(PARAM_INT, 'The unique identifier for the page type'),
'typestring' => new external_value(PARAM_RAW, 'The string that describes this page type'),
'page' => self::get_page_structure(),
'answerids' => new external_multiple_structure(
new external_value(PARAM_INT, 'Answer id'), 'List of answers ids (empty for content pages in Moodle 1.9)'
),
@@ -1096,6 +1135,42 @@ class mod_lesson_external extends external_api {
);
}
/**
* Return lesson messages formatted according the external_messages structure
*
* @param lesson $lesson lesson instance
* @return array messages formatted
* @since Moodle 3.3
*/
protected static function format_lesson_messages($lesson) {
$messages = array();
foreach ($lesson->messages as $message) {
$messages[] = array(
'message' => $message[0],
'type' => $message[1],
);
}
return $messages;
}
/**
* Return a external structure representing messages.
*
* @return external_multiple_structure messages structure
* @since Moodle 3.3
*/
protected static function external_messages() {
return new external_multiple_structure(
new external_single_structure(
array(
'message' => new external_value(PARAM_RAW, 'Message.'),
'type' => new external_value(PARAM_ALPHANUMEXT, 'Message type: usually a CSS identifier like:
success, info, warning, error, notifyproblem, notifyerror, notifytiny, notifysuccess')
), 'The lesson generated messages'
)
);
}
/**
* Starts a new attempt or continues an existing one.
*
@@ -1112,7 +1187,7 @@ class mod_lesson_external extends external_api {
$params = array('lessonid' => $lessonid, 'password' => $password, 'pageid' => $pageid, 'review' => $review);
$params = self::validate_parameters(self::launch_attempt_parameters(), $params);
$warnings = $messages = array();
$warnings = array();
list($lesson, $course, $cm, $context) = self::validate_lesson($params['lessonid']);
self::validate_attempt($lesson, $params);
@@ -1141,12 +1216,7 @@ class mod_lesson_external extends external_api {
throw new moodle_exception('eolstudentoutoftime', 'lesson');
}
}
foreach ($lesson->messages as $message) {
$messages[] = array(
'message' => $message[0],
'type' => $message[1],
);
}
$messages = self::format_lesson_messages($lesson);
$result = array(
'status' => true,
@@ -1165,15 +1235,162 @@ class mod_lesson_external extends external_api {
public static function launch_attempt_returns() {
return new external_single_structure(
array(
'messages' => new external_multiple_structure(
'messages' => self::external_messages(),
'warnings' => new external_warnings(),
)
);
}
/**
* Describes the parameters for get_page_data.
*
* @return external_external_function_parameters
* @since Moodle 3.3
*/
public static function get_page_data_parameters() {
return new external_function_parameters (
array(
'lessonid' => new external_value(PARAM_INT, 'lesson instance id'),
'pageid' => new external_value(PARAM_INT, 'the page id'),
'password' => new external_value(PARAM_RAW, 'optional password (the lesson may be protected)', VALUE_DEFAULT, ''),
'review' => new external_value(PARAM_BOOL, 'if we want to review just after finishing (1 hour margin)',
VALUE_DEFAULT, false),
'returncontents' => new external_value(PARAM_BOOL, 'if we must return the complete page contents once rendered',
VALUE_DEFAULT, false),
)
);
}
/**
* Return information of a given page, including its contents.
*
* @param int $lessonid lesson instance id
* @param int $pageid page id
* @param str $password optional password (the lesson may be protected)
* @param bool $review if we want to review just after finishing (1 hour margin)
* @param bool $returncontents if we must return the complete page contents once rendered
* @return array of warnings and status result
* @since Moodle 3.3
* @throws moodle_exception
*/
public static function get_page_data($lessonid, $pageid, $password = '', $review = false, $returncontents = false) {
global $PAGE;
$params = array('lessonid' => $lessonid, 'password' => $password, 'pageid' => $pageid, 'review' => $review,
'returncontents' => $returncontents);
$params = self::validate_parameters(self::get_page_data_parameters(), $params);
$warnings = $contentfiles = $answerfiles = $responsefiles = array();
$pagecontent = $ongoingscore = '';
$progress = null;
list($lesson, $course, $cm, $context) = self::validate_lesson($params['lessonid']);
self::validate_attempt($lesson, $params);
$pageid = $params['pageid'];
// This is called if a student leaves during a lesson.
if ($pageid == LESSON_UNSEENBRANCHPAGE) {
$pageid = lesson_unseen_question_jump($lesson, $USER->id, $pageid);
}
if ($pageid != LESSON_EOL) {
$reviewmode = $lesson->is_in_review_mode();
$lessonoutput = $PAGE->get_renderer('mod_lesson');
list($page, $pagecontent) = $lesson->prepare_page_and_contents($pageid, $lessonoutput, $reviewmode);
// Page may have changed.
$pageid = $page->id;
$pagedata = self::get_page_fields($page, true);
// Files.
$contentfiles = external_util::get_area_files($context->id, 'mod_lesson', 'page_contents', $page->id);
// Answers.
$answers = array();
$pageanswers = $page->get_answers();
foreach ($pageanswers as $a) {
$answer = array(
'id' => $a->id,
'answerfiles' => external_util::get_area_files($context->id, 'mod_lesson', 'page_answers', $a->id),
'responsefiles' => external_util::get_area_files($context->id, 'mod_lesson', 'page_responses', $a->id),
);
// For managers, return all the information (including scoring, jumps).
if ($lesson->can_manage()) {
$extraproperties = array('jumpto', 'grade', 'score', 'flags', 'timecreated', 'timemodified');
foreach ($extraproperties as $prop) {
$answer[$prop] = $a->{$prop};
}
}
$answers[] = $answer;
}
// Additional lesson information.
if (!$lesson->can_manage()) {
if ($lesson->ongoing && !$reviewmode) {
$ongoingscore = $lesson->get_ongoing_score_message();
}
if ($lesson->progressbar) {
$progress = $lesson->calculate_progress();
}
}
}
$messages = self::format_lesson_messages($lesson);
$result = array(
'page' => $pagedata,
'newpageid' => $pageid,
'ongoingscore' => $ongoingscore,
'progress' => $progress,
'contentfiles' => $contentfiles,
'answers' => $answers,
'messages' => $messages,
'warnings' => $warnings,
'displaymenu' => !empty(lesson_displayleftif($lesson)),
);
if ($params['returncontents']) {
$result['pagecontent'] = $pagecontent; // Return the complete page contents rendered.
}
return $result;
}
/**
* Describes the get_page_data return value.
*
* @return external_single_structure
* @since Moodle 3.3
*/
public static function get_page_data_returns() {
return new external_single_structure(
array(
'page' => self::get_page_structure(),
'newpageid' => new external_value(PARAM_INT, 'New page id (if a jump was made)'),
'pagecontent' => new external_value(PARAM_RAW, 'Page html content', VALUE_OPTIONAL),
'ongoingscore' => new external_value(PARAM_TEXT, 'The ongoing score message'),
'progress' => new external_value(PARAM_INT, 'Progress percentage in the lesson'),
'contentfiles' => new external_files(),
'answers' => new external_multiple_structure(
new external_single_structure(
array(
'message' => new external_value(PARAM_RAW, 'Message'),
'type' => new external_value(PARAM_ALPHANUMEXT, 'Message type: usually a CSS identifier like:
success, info, warning, error, notifyproblem, notifyerror, notifytiny, notifysuccess')
), 'The lesson generated messages'
'id' => new external_value(PARAM_INT, 'The ID of this answer in the database'),
'answerfiles' => new external_files(),
'responsefiles' => new external_files(),
'jumpto' => new external_value(PARAM_INT, 'Identifies where the user goes upon completing a page with this answer',
VALUE_OPTIONAL),
'grade' => new external_value(PARAM_INT, 'The grade this answer is worth', VALUE_OPTIONAL),
'score' => new external_value(PARAM_INT, 'The score this answer will give', VALUE_OPTIONAL),
'flags' => new external_value(PARAM_INT, 'Used to store options for the answer', VALUE_OPTIONAL),
'timecreated' => new external_value(PARAM_INT, 'A timestamp of when the answer was created', VALUE_OPTIONAL),
'timemodified' => new external_value(PARAM_INT, 'A timestamp of when the answer was modified', VALUE_OPTIONAL),
), 'The page answers'
)
),
'messages' => self::external_messages(),
'displaymenu' => new external_value(PARAM_BOOL, 'Whether we should display the menu or not in this page.'),
'warnings' => new external_warnings(),
)
);
+8
View File
@@ -108,4 +108,12 @@ $functions = array(
'capabilities' => 'mod/lesson:view',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
),
'mod_lesson_get_page_data' => array(
'classname' => 'mod_lesson_external',
'methodname' => 'get_page_data',
'description' => 'Return information of a given page, including its contents.',
'type' => 'read',
'capabilities' => 'mod/lesson:view',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
),
);
+150
View File
@@ -2525,6 +2525,156 @@ class lesson extends lesson_base {
}
}
}
/**
* Get the ongoing score message for the user (depending on the user permission and lesson settings).
*
* @return str the ongoing score message
* @since Moodle 3.3
*/
public function get_ongoing_score_message() {
global $USER, $DB;
$context = $this->get_context();
if (has_capability('mod/lesson:manage', $context)) {
return get_string('teacherongoingwarning', 'lesson');
} else {
$ntries = $DB->count_records("lesson_grades", array("lessonid" => $this->properties->id, "userid" => $USER->id));
if (isset($USER->modattempts[$this->properties->id])) {
$ntries--;
}
$gradeinfo = lesson_grade($this, $ntries);
$a = new stdClass;
if ($this->properties->custom) {
$a->score = $gradeinfo->earned;
$a->currenthigh = $gradeinfo->total;
return get_string("ongoingcustom", "lesson", $a);
} else {
$a->correct = $gradeinfo->earned;
$a->viewed = $gradeinfo->attempts;
return get_string("ongoingnormal", "lesson", $a);
}
}
}
/**
* Calculate the progress of the current user in the lesson.
*
* @return int the progress (scale 0-100)
* @since Moodle 3.3
*/
public function calculate_progress() {
global $USER, $DB;
// Check if the user is reviewing the attempt.
if (isset($USER->modattempts[$this->properties->id])) {
return 100;
}
// All of the lesson pages.
$pages = $this->load_all_pages();
foreach ($pages as $page) {
if ($page->prevpageid == 0) {
$pageid = $page->id; // Find the first page id.
break;
}
}
// Current attempt number.
if (!$ntries = $DB->count_records("lesson_grades", array("lessonid" => $this->properties->id, "userid" => $USER->id))) {
$ntries = 0; // May not be necessary.
}
$viewedpageids = array();
if ($attempts = $this->get_attempts($ntries, false)) {
foreach ($attempts as $attempt) {
$viewedpageids[$attempt->pageid] = $attempt;
}
}
$viewedbranches = array();
// Collect all of the branch tables viewed.
if ($branches = $this->get_content_pages_viewed($ntries, $USER->id, 'timeseen ASC', 'id, pageid')) {
foreach ($branches as $branch) {
$viewedbranches[$branch->pageid] = $branch;
}
$viewedpageids = array_merge($viewedpageids, $viewedbranches);
}
// Filter out the following pages:
// - End of Cluster
// - End of Branch
// - Pages found inside of Clusters
// Do not filter out Cluster Page(s) because we count a cluster as one.
// By keeping the cluster page, we get our 1.
$validpages = array();
while ($pageid != 0) {
$pageid = $pages[$pageid]->valid_page_and_view($validpages, $viewedpageids);
}
// Progress calculation as a percent.
return round(count($viewedpageids) / count($validpages), 2) * 100;
}
/**
* Calculate the correct page and prepare contents for a given page id (could be a page jump id).
*
* @param int $pageid the given page id
* @param mod_lesson_renderer $lessonoutput the lesson output rendered
* @param bool $reviewmode whether we are in review mode or not
* @return array the page object and contents
* @throws moodle_exception
* @since Moodle 3.3
*/
public function prepare_page_and_contents($pageid, $lessonoutput, $reviewmode) {
global $USER, $CFG;
$page = $this->load_page($pageid);
// Check if the page is of a special type and if so take any nessecary action.
$newpageid = $page->callback_on_view($this->can_manage());
if (is_numeric($newpageid)) {
$page = $this->load_page($newpageid);
}
// Add different informative messages to the given page.
$this->add_messages_on_page_view($page, $reviewmode);
if (is_array($page->answers) && count($page->answers) > 0) {
// This is for modattempts option. Find the users previous answer to this page,
// and then display it below in answer processing.
if (isset($USER->modattempts[$this->properties->id])) {
$retries = $this->count_user_retries($USER->id);
if (!$attempts = $this->get_attempts($retries - 1, false, $page->id)) {
throw new moodle_exception('cannotfindpreattempt', 'lesson');
}
$attempt = end($attempts);
$USER->modattempts[$this->properties->id] = $attempt;
} else {
$attempt = false;
}
$lessoncontent = $lessonoutput->display_page($this, $page, $attempt);
} else {
require_once($CFG->dirroot . '/mod/lesson/view_form.php');
$data = new stdClass;
$data->id = $this->get_cm()->id;
$data->pageid = $page->id;
$data->newpageid = $this->get_next_page($page->nextpageid);
$customdata = array(
'title' => $page->title,
'contents' => $page->get_contents()
);
$mform = new lesson_page_without_answers($CFG->wwwroot.'/mod/lesson/continue.php', $customdata);
$mform->set_data($data);
ob_start();
$mform->display();
$lessoncontent = ob_get_contents();
ob_end_clean();
}
return array($page, $lessoncontent);
}
}
+3 -71
View File
@@ -477,28 +477,7 @@ class mod_lesson_renderer extends plugin_renderer_base {
* @return string
*/
public function ongoing_score(lesson $lesson) {
global $USER, $DB;
$context = context_module::instance($this->page->cm->id);
if (has_capability('mod/lesson:manage', $context)) {
return $this->output->box(get_string('teacherongoingwarning', 'lesson'), "ongoing center");
} else {
$ntries = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id, "userid"=>$USER->id));
if (isset($USER->modattempts[$lesson->id])) {
$ntries--;
}
$gradeinfo = lesson_grade($lesson, $ntries);
$a = new stdClass;
if ($lesson->custom) {
$a->score = $gradeinfo->earned;
$a->currenthigh = $gradeinfo->total;
return $this->output->box(get_string("ongoingcustom", "lesson", $a), "ongoing center");
} else {
$a->correct = $gradeinfo->earned;
$a->viewed = $gradeinfo->attempts;
return $this->output->box(get_string("ongoingnormal", "lesson", $a), "ongoing center");
}
}
return $this->output->box($lesson->get_ongoing_score_message(), "ongoing center");
}
/**
@@ -508,8 +487,6 @@ class mod_lesson_renderer extends plugin_renderer_base {
* @return string
*/
public function progress_bar(lesson $lesson) {
global $CFG, $USER, $DB;
$context = context_module::instance($this->page->cm->id);
// lesson setting to turn progress bar on or off
@@ -522,53 +499,8 @@ class mod_lesson_renderer extends plugin_renderer_base {
return $this->output->notification(get_string('progressbarteacherwarning2', 'lesson'));
}
if (!isset($USER->modattempts[$lesson->id])) {
// all of the lesson pages
$pages = $lesson->load_all_pages();
foreach ($pages as $page) {
if ($page->prevpageid == 0) {
$pageid = $page->id; // find the first page id
break;
}
}
// current attempt number
if (!$ntries = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id, "userid"=>$USER->id))) {
$ntries = 0; // may not be necessary
}
$viewedpageids = array();
if ($attempts = $lesson->get_attempts($ntries, false)) {
foreach($attempts as $attempt) {
$viewedpageids[$attempt->pageid] = $attempt;
}
}
$viewedbranches = array();
// collect all of the branch tables viewed
if ($branches = $lesson->get_content_pages_viewed($ntries, $USER->id, 'timeseen ASC', 'id, pageid')) {
foreach($branches as $branch) {
$viewedbranches[$branch->pageid] = $branch;
}
$viewedpageids = array_merge($viewedpageids, $viewedbranches);
}
// Filter out the following pages:
// End of Cluster
// End of Branch
// Pages found inside of Clusters
// Do not filter out Cluster Page(s) because we count a cluster as one.
// By keeping the cluster page, we get our 1
$validpages = array();
while ($pageid != 0) {
$pageid = $pages[$pageid]->valid_page_and_view($validpages, $viewedpageids);
}
// progress calculation as a percent
$progress = round(count($viewedpageids)/count($validpages), 2) * 100;
} else {
$progress = 100;
}
// Check if the user is reviewing the attempt.
$progress = $lesson->calculate_progress();
// print out the Progress Bar. Attempted to put as much as possible in the style sheets.
$content = '<br />' . html_writer::tag('div', $progress . '%', array('class' => 'progress_bar_completed', 'style' => 'width: '. $progress . '%;'));
+76 -3
View File
@@ -731,9 +731,9 @@ class mod_lesson_external_testcase extends externallib_advanced_testcase {
// Check pages and values.
foreach ($result['pages'] as $page) {
if ($page['id'] == $this->page2->id) {
if ($page['page']['id'] == $this->page2->id) {
$this->assertEquals(2 * count($page['answerids']), $page['filescount']);
$this->assertEquals('Lesson TF question 2', $page['title']);
$this->assertEquals('Lesson TF question 2', $page['page']['title']);
} else {
// Content page, no answers.
$this->assertCount(0, $page['answerids']);
@@ -750,7 +750,7 @@ class mod_lesson_external_testcase extends externallib_advanced_testcase {
$this->assertCount(3, $result['pages']);
foreach ($result['pages'] as $page) {
$this->assertArrayNotHasKey('title', $page);
$this->assertArrayNotHasKey('title', $page['page']);
}
}
@@ -901,4 +901,77 @@ class mod_lesson_external_testcase extends externallib_advanced_testcase {
$this->setExpectedException('moodle_exception');
mod_lesson_external::launch_attempt($this->lesson->id, '', 1, true);
}
/*
* Test get_page_data
*/
public function test_get_page_data() {
global $DB;
// Test a content page first (page1).
$result = mod_lesson_external::get_page_data($this->lesson->id, $this->page1->id, '', false, true);
$result = external_api::clean_returnvalue(mod_lesson_external::get_page_data_returns(), $result);
$this->assertCount(0, $result['warnings']);
$this->assertCount(0, $result['answers']); // No answers, auto-generated content page.
$this->assertEmpty($result['ongoingscore']);
$this->assertEmpty($result['progress']);
$this->assertEquals($this->page1->id, $result['newpageid']); // No answers, so is pointing to the itself.
$this->assertEquals($this->page1->id, $result['page']['id']);
$this->assertEquals(0, $result['page']['nextpageid']); // Is the last page.
$this->assertEquals('Content', $result['page']['typestring']);
$this->assertEquals($this->page2->id, $result['page']['prevpageid']); // Previous page.
// Check contents.
$this->assertTrue(strpos($result['pagecontent'], $this->page1->title) !== false);
$this->assertTrue(strpos($result['pagecontent'], $this->page1->contents) !== false);
// Check menu availability.
$this->assertFalse($result['displaymenu']);
// Check now a page with answers (true / false) and with menu available.
$DB->set_field('lesson', 'displayleft', 1, array('id' => $this->lesson->id));
$result = mod_lesson_external::get_page_data($this->lesson->id, $this->page2->id, '', false, true);
$result = external_api::clean_returnvalue(mod_lesson_external::get_page_data_returns(), $result);
$this->assertCount(0, $result['warnings']);
$this->assertCount(2, $result['answers']); // One for true, one for false.
// Check menu availability.
$this->assertTrue($result['displaymenu']);
// Check contents.
$this->assertTrue(strpos($result['pagecontent'], $this->page2->contents) !== false);
$this->assertEquals(0, $result['page']['prevpageid']); // Previous page.
$this->assertEquals($this->page1->id, $result['page']['nextpageid']); // Next page.
}
/**
* Test get_page_data as student
*/
public function test_get_page_data_student() {
// Now check using a normal student account.
$this->setUser($this->student);
// First we need to launch the lesson so the timer is on.
mod_lesson_external::launch_attempt($this->lesson->id);
$result = mod_lesson_external::get_page_data($this->lesson->id, $this->page2->id, '', false, true);
$result = external_api::clean_returnvalue(mod_lesson_external::get_page_data_returns(), $result);
$this->assertCount(0, $result['warnings']);
$this->assertCount(2, $result['answers']); // One for true, one for false.
// Check contents.
$this->assertTrue(strpos($result['pagecontent'], $this->page2->contents) !== false);
// Check we don't see answer information.
$this->assertArrayNotHasKey('jumpto', $result['answers'][0]);
$this->assertArrayNotHasKey('score', $result['answers'][0]);
$this->assertArrayNotHasKey('jumpto', $result['answers'][1]);
$this->assertArrayNotHasKey('score', $result['answers'][1]);
}
/**
* Test get_page_data without launching attempt.
*/
public function test_get_page_data_without_launch() {
// Now check using a normal student account.
$this->setUser($this->student);
$this->setExpectedException('moodle_exception');
$result = mod_lesson_external::get_page_data($this->lesson->id, $this->page2->id, '', false, true);
}
}
+1 -1
View File
@@ -24,7 +24,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2016120509; // The current module version (Date: YYYYMMDDXX)
$plugin->version = 2016120510; // 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;
+11 -55
View File
@@ -25,7 +25,6 @@
require_once(__DIR__ . '/../../config.php');
require_once($CFG->dirroot.'/mod/lesson/locallib.php');
require_once($CFG->dirroot.'/mod/lesson/view_form.php');
require_once($CFG->libdir . '/grade/constants.php');
$id = required_param('id', PARAM_INT); // Course Module ID
@@ -181,24 +180,14 @@ $lessonpageid = null;
$timer = null;
if ($pageid != LESSON_EOL) {
/// This is the code updates the lessontime for a timed test
$startlastseen = optional_param('startlastseen', '', PARAM_ALPHA);
$page = $lesson->load_page($pageid);
// Check if the page is of a special type and if so take any nessecary action
$newpageid = $page->callback_on_view($canmanage);
if (is_numeric($newpageid)) {
$page = $lesson->load_page($newpageid);
}
$lesson->set_module_viewed();
$timer = null;
// This is the code updates the lessontime for a timed test.
$startlastseen = optional_param('startlastseen', '', PARAM_ALPHA);
// This is where several messages (usually warnings) are displayed
// all of this is displayed above the actual page
// check to see if the user can see the left menu
// Check to see if the user can see the left menu.
if (!$canmanage) {
$lesson->displayleft = lesson_displayleftif($lesson);
@@ -213,8 +202,11 @@ if ($pageid != LESSON_EOL) {
}
}
// Add different informative messages to the given page.
$lesson->add_messages_on_page_view($page, $reviewmode);
list($page, $lessoncontent) = $lesson->prepare_page_and_contents($pageid, $lessonoutput, $reviewmode);
if (($edit != -1) && $PAGE->user_allowed_editing()) {
$USER->editing = $edit;
}
$PAGE->set_subpage($page->id);
$currenttab = 'view';
@@ -222,49 +214,13 @@ if ($pageid != LESSON_EOL) {
$lessonpageid = $page->id;
$extrapagetitle = $page->title;
if (($edit != -1) && $PAGE->user_allowed_editing()) {
$USER->editing = $edit;
}
if (is_array($page->answers) && count($page->answers)>0) {
// this is for modattempts option. Find the users previous answer to this page,
// and then display it below in answer processing
if (isset($USER->modattempts[$lesson->id])) {
$retries = $lesson->count_user_retries($USER->id);
if (!$attempts = $lesson->get_attempts($retries-1, false, $page->id)) {
print_error('cannotfindpreattempt', 'lesson');
}
$attempt = end($attempts);
$USER->modattempts[$lesson->id] = $attempt;
} else {
$attempt = false;
}
$lessoncontent = $lessonoutput->display_page($lesson, $page, $attempt);
} else {
$data = new stdClass;
$data->id = $PAGE->cm->id;
$data->pageid = $page->id;
$data->newpageid = $lesson->get_next_page($page->nextpageid);
$customdata = array(
'title' => $page->title,
'contents' => $page->get_contents()
);
$mform = new lesson_page_without_answers($CFG->wwwroot.'/mod/lesson/continue.php', $customdata);
$mform->set_data($data);
ob_start();
$mform->display();
$lessoncontent = ob_get_contents();
ob_end_clean();
}
lesson_add_fake_blocks($PAGE, $cm, $lesson, $timer);
echo $lessonoutput->header($lesson, $cm, $currenttab, $extraeditbuttons, $lessonpageid, $extrapagetitle);
if ($attemptflag) {
// We are using level 3 header because attempt heading is a sub-heading of lesson title (MDL-30911).
echo $OUTPUT->heading(get_string('attempt', 'lesson', $retries), 3);
}
/// This calculates and prints the ongoing score
// This calculates and prints the ongoing score.
if ($lesson->ongoing && !empty($pageid) && !$reviewmode) {
echo $lessonoutput->ongoing_score($lesson);
}
@@ -278,8 +234,8 @@ if ($pageid != LESSON_EOL) {
} else {
$lessoncontent = '';
// end of lesson reached work out grade
// Used to check to see if the student ran out of time
// End of lesson reached work out grade.
// Used to check to see if the student ran out of time.
$outoftime = optional_param('outoftime', '', PARAM_ALPHA);
$ntries = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id, "userid"=>$USER->id));