Skip to content

Commit

Permalink
Merge branch 'MDL-57693-master' of git://github.com/jleyva/moodle
Browse files Browse the repository at this point in the history
  • Loading branch information
dmonllao committed Mar 21, 2017
2 parents 5b95bd5 + ef8d1c9 commit 7f0ddd4
Show file tree
Hide file tree
Showing 7 changed files with 507 additions and 171 deletions.
299 changes: 258 additions & 41 deletions mod/lesson/classes/external.php

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions mod/lesson/db/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,12 @@
'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 changes: 150 additions & 0 deletions mod/lesson/locallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -2525,6 +2525,156 @@ public function add_messages_on_page_view(lesson_page $page, $reviewmode) {
}
}
}

/**
* 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);
}
}


Expand Down
74 changes: 3 additions & 71 deletions mod/lesson/renderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -477,28 +477,7 @@ public function page_action_links(lesson_page $page, $printmove, $printaddpage=f
* @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");
}

/**
Expand All @@ -508,8 +487,6 @@ public function ongoing_score(lesson $lesson) {
* @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
Expand All @@ -522,53 +499,8 @@ public function progress_bar(lesson $lesson) {
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 . '%;'));
Expand Down
79 changes: 76 additions & 3 deletions mod/lesson/tests/external_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -731,9 +731,9 @@ public function test_get_pages() {

// 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']);
Expand All @@ -750,7 +750,7 @@ public function test_get_pages() {
$this->assertCount(3, $result['pages']);

foreach ($result['pages'] as $page) {
$this->assertArrayNotHasKey('title', $page);
$this->assertArrayNotHasKey('title', $page['page']);
}
}

Expand Down Expand Up @@ -901,4 +901,77 @@ public function test_launch_attempt_not_just_finished_in_review_mode() {
$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);
}
}
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 = 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;
Loading

0 comments on commit 7f0ddd4

Please sign in to comment.