From bbcbc0fecc7f8c7f5b71424864bdef4f1b540c17 Mon Sep 17 00:00:00 2001 From: moodler Date: Mon, 16 Feb 2004 05:41:13 +0000 Subject: [PATCH] Adding the Lesson module to the main CVS. Nice job Ray! Still needs PostgreSQL support and wider testing --- lang/en/help/lesson/grade.html | 7 + lang/en/help/lesson/jumpto.html | 13 + lang/en/help/lesson/maxanswers.html | 7 + lang/en/help/lesson/mods.html | 11 + lang/en/help/lesson/overview.html | 55 +++ lang/en/help/lesson/retake.html | 16 + lang/en/lesson.php | 39 ++ mod/lesson/backuplib.php | 258 +++++++++++ mod/lesson/db/mysql.php | 18 + mod/lesson/db/mysql.sql | 72 +++ mod/lesson/icon.gif | Bin 0 -> 128 bytes mod/lesson/index.php | 105 +++++ mod/lesson/lesson.php | 669 ++++++++++++++++++++++++++++ mod/lesson/lib.php | 316 +++++++++++++ mod/lesson/mod.html | 101 +++++ mod/lesson/restorelib.php | 329 ++++++++++++++ mod/lesson/version.php | 12 + mod/lesson/view.php | 342 ++++++++++++++ 18 files changed, 2370 insertions(+) create mode 100644 lang/en/help/lesson/grade.html create mode 100644 lang/en/help/lesson/jumpto.html create mode 100644 lang/en/help/lesson/maxanswers.html create mode 100644 lang/en/help/lesson/mods.html create mode 100644 lang/en/help/lesson/overview.html create mode 100644 lang/en/help/lesson/retake.html create mode 100644 lang/en/lesson.php create mode 100644 mod/lesson/backuplib.php create mode 100644 mod/lesson/db/mysql.php create mode 100644 mod/lesson/db/mysql.sql create mode 100755 mod/lesson/icon.gif create mode 100644 mod/lesson/index.php create mode 100644 mod/lesson/lesson.php create mode 100644 mod/lesson/lib.php create mode 100644 mod/lesson/mod.html create mode 100644 mod/lesson/restorelib.php create mode 100644 mod/lesson/version.php create mode 100644 mod/lesson/view.php diff --git a/lang/en/help/lesson/grade.html b/lang/en/help/lesson/grade.html new file mode 100644 index 0000000000..ded2142651 --- /dev/null +++ b/lang/en/help/lesson/grade.html @@ -0,0 +1,7 @@ +

The Grade of the Lesson

+ +

This value determines the maximum grade which can be awarded in + the lesson. The range is 0 to 100%. This value can be changed at + any time during the lesson. Any change has an immediate effect in + the Grades page and on the grades shown to the students in various + lists.

diff --git a/lang/en/help/lesson/jumpto.html b/lang/en/help/lesson/jumpto.html new file mode 100644 index 0000000000..de7fc2e27b --- /dev/null +++ b/lang/en/help/lesson/jumpto.html @@ -0,0 +1,13 @@ +

The Jump-to Link

+ +

Each answer has a Jump-to link. When this answer is chosen, the answer's response + is shown to the student. Atfer that the student sees the page given in the Jump-to + link. This link can be either relative or absolute. Relative links are This + page and Next page. This page means that the student sees the + current page again. Next page shows the page which follows this page in the + logical order of pages. An absolute page link is specified by choosing the page's + title.

+

Note that a (relative) Next page Jump-to link may show a different page + after pages have been moved. Whereas Jump-to links which use page titles + always show the same page after pages have been moved.

+ diff --git a/lang/en/help/lesson/maxanswers.html b/lang/en/help/lesson/maxanswers.html new file mode 100644 index 0000000000..a72db12f7f --- /dev/null +++ b/lang/en/help/lesson/maxanswers.html @@ -0,0 +1,7 @@ +

The Maximum Number of Answers in a Lesson

+ +

This value determines the maximum number of answers the teacher can use. + The default value is 4. If the lesson uses only TRUE or FALSE + questions throughout then it is sensible to set this value to 2.

+ +

It is safe to change this value in a lesson with existing content.

diff --git a/lang/en/help/lesson/mods.html b/lang/en/help/lesson/mods.html new file mode 100644 index 0000000000..c1c6988410 --- /dev/null +++ b/lang/en/help/lesson/mods.html @@ -0,0 +1,11 @@ + Lesson + + + diff --git a/lang/en/help/lesson/overview.html b/lang/en/help/lesson/overview.html new file mode 100644 index 0000000000..0083ff2e81 --- /dev/null +++ b/lang/en/help/lesson/overview.html @@ -0,0 +1,55 @@ +

Overview

+ +
    +
  1. A lesson is made up of a number of pages. +
  2. A page contains some content and it normally ends with a question. +
  3. Each page normally has a set of answers. +
  4. Each answer can have a short piece of text which is displayed if the answer is + chosen. This piece of text is called the response. +
  5. Also associated with each answer is a jump. The jump can be relative - + this page, next page - or absolute - specifying any one of the pages in the + lesson or the end of the lesson. +
  6. By default, the first answer jumps to the next page in the lesson. + The subsequent answers jump to the same page. That is, the student is shown + the same page of the lesson again if they do not chose the first answer. +
  7. The next page is determined by the lesson's logical order. This is + the order of the pages as seen by the teacher. This order can be altered + by moving pages within the lesson. +
  8. The lesson also has a navigation order. This is the order of the + pages as seen by the students. This is determined by the jumps specified + for individual answers and it can be very different from the logical order. + (Although if the jumps are not changed from their default values + the two are strongly related.) The teacher has the option to check the + navigation order. +
  9. When displayed to the students, the answers are always shuffled. That is, the + first answer from the teacher's point of view will not necessarily be the + first answer in the list shown to the students. (Further, each time the same + set of answers is displayed they are likely to appear in a different order.) +
  10. The number of answers can vary from page to page. For example, it is allowed + that some pages can end with a true/false question while others have questions + with one correct answer and three, say, distractors. +
  11. It is possible to set up a page without any answers. The students are shown + a Continue link instead of the set of shuffled answers. +
  12. For the purposes of grading the lessons, correct answers are ones which + jump to a page which is further down the logical order than the current page. + Wrong answers are ones which either jump to the same page or to a page + further up the logical order than the current page. Thus, if the jumps are + not changed, the first answer is a correct answer and the other answers are + wrong answers. +
  13. Questions can have more than one correct answer. For example, if two of the answers + jump to the next page then either answer is taken as a correct answer. (Although + the same destination page is shown to the students, the responses shown on the way + to that page may well be different for the two answers.) +
  14. In the teacher's view of the lesson the correct answers have underlined Answer + Labels. +
  15. The end of the lesson is reached by either jumping to that location explicitly + or by jumping to the next page from the last (logical) page of the lesson. When the + end of the lesson is reached, the student receives a congratulations message and is + shown their grade. The grade is (the number of correct answers checked / number of + pages seen) * the grade of the lesson. +
  16. If the end of the lesson is not reached, when the student goes into the + lesson they are given the choice of starting at the begining or picking up the lesson + where they answered their last correct answer. +
  17. For a lesson which allow re-takes, students are allowed to re-take the lesson until + they have achieved the maximum grade. +
diff --git a/lang/en/help/lesson/retake.html b/lang/en/help/lesson/retake.html new file mode 100644 index 0000000000..a0027e69b7 --- /dev/null +++ b/lang/en/help/lesson/retake.html @@ -0,0 +1,16 @@ +

Allowing the Students to Re-take the Lesson

+ +

This setting determines whether the students can take the lesson more than once + or only once. The teacher may decide that the lesson contains material which + the students ought to know throughly. In which case repeated viewings of the + lesson should be allowed. If, however, the material is used more like an exam + then the students should not be allowed to re-take the lesson.

+ +

When the students are allowed to re-take the lesson, the grades shown + in the Grades page are the grades from their best attempts of the lesson. + However, the Question Analysis always uses the answers from the + first attempts of the lesson, subsequent attempts are ignored.

+ +

By default this option is Yes, meaning that students are allowed to re-take + the lesson. It is expected that only in exceptional circumstances will this + option be set to No. diff --git a/lang/en/lesson.php b/lang/en/lesson.php new file mode 100644 index 0000000000..7fbd87e351 --- /dev/null +++ b/lang/en/lesson.php @@ -0,0 +1,39 @@ +Do you want to start at the last page you saw?"; + +?> diff --git a/mod/lesson/backuplib.php b/mod/lesson/backuplib.php new file mode 100644 index 0000000000..07ce4d3007 --- /dev/null +++ b/mod/lesson/backuplib.php @@ -0,0 +1,258 @@ +id) | + // | | + // | lesson_grades + // | (UL, pk->id,fk->lessonid) + // lesson_pages + // (pk->id,fk->lessonid) + // | + // | + // | + // lesson_answers + // (pk->id,fk->pageid) + // | + // | + // | + // lesson_attempts + // (UL,pk->id,fk->answerid) + // + // Meaning: pk->primary key field of the table + // fk->foreign key to link with parent + // nt->nested field (recursive data) + // CL->course level info + // UL->user level info + // files->table may have files) + // + //----------------------------------------------------------- + + //This function executes all the backup procedure about this mod + function lesson_backup_mods($bf, $preferences) { + + global $CFG; + + $status = true; + + //Iterate over lesson table + $lessons = get_records("lesson", "course", $preferences->backup_course, "id"); + if ($lessons) { + foreach ($lessons as $lesson) { + //Start mod + fwrite ($bf,start_tag("MOD",3,true)); + //Print lesson data + fwrite ($bf,full_tag("ID",4,false,$lesson->id)); + fwrite ($bf,full_tag("MODTYPE",4,false,"lesson")); + fwrite ($bf,full_tag("NAME",4,false,$lesson->name)); + fwrite ($bf,full_tag("GRADE",4,false,$lesson->grade)); + fwrite ($bf,full_tag("MAXANSWERS",4,false,$lesson->maxanswers)); + fwrite ($bf,full_tag("RETAKE",4,false,$lesson->retake)); + fwrite ($bf,full_tag("AVAILABLE",4,false,$lesson->available)); + fwrite ($bf,full_tag("DEADLINE",4,false,$lesson->deadline)); + fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$lesson->timemodified)); + //Now we backup lesson pages + $status = backup_lesson_pages($bf,$preferences,$lesson->id); + //if we've selected to backup users info, then backup grades + if ($status) { + if ($preferences->mods["lesson"]->userinfo) { + $status = backup_lesson_grades($bf, $preferences, $lesson->id); + } + //End mod + $status =fwrite ($bf,end_tag("MOD",3,true)); + } + } + } + return $status; + } + + //Backup lesson_pages contents (executed from lesson_backup_mods) + function backup_lesson_pages ($bf, $preferences, $lessonid) { + + global $CFG; + + $status = true; + + // run through the pages in their logical order, get the first page + if ($page = get_record_select("lesson_pages", "lessonid = $lessonid AND prevpageid = 0")) { + //Write start tag + $status =fwrite ($bf,start_tag("PAGES",4,true)); + //Iterate over each page + while (true) { + //Start of page + $status =fwrite ($bf,start_tag("PAGE",5,true)); + //Print page contents (prevpageid and nextpageid not needed) + fwrite ($bf,full_tag("PAGEID",6,false,$page->id)); // needed to fix (absolute) jumps + fwrite ($bf,full_tag("TIMECREATED",6,false,$page->timecreated)); + fwrite ($bf,full_tag("TIMEMODIFIED",6,false,$page->timemodified)); + fwrite ($bf,full_tag("TITLE",6,false,$page->title)); + fwrite ($bf,full_tag("CONTENTS",6,false,$page->contents)); + //Now we backup lesson answers for this page + $status = backup_lesson_answers($bf, $preferences, $page->id); + //End of page + $status =fwrite ($bf,end_tag("PAGE",5,true)); + // move to the next (logical) page + if ($page->nextpageid) { + if (!$page = get_record("lesson_pages", "id", $page->nextpageid)) { + error("Lesson Backup: Next page not found!"); + } + } else { + // last page reached + break; + } + + } + //Write end tag + $status =fwrite ($bf,end_tag("PAGES",4,true)); + } + return $status; + } + + //Backup lesson_answers contents (executed from backup_lesson_pages) + function backup_lesson_answers($bf,$preferences,$pageno) { + + global $CFG; + + $status = true; + + $lesson_answers = get_records("lesson_answers", "pageid", $pageno); + + //If there is lesson_answers + if ($lesson_answers) { + //Write start tag + $status =fwrite ($bf,start_tag("ANSWERS",6,true)); + //Iterate over each element + foreach ($lesson_answers as $answer) { + //Start answer + $status =fwrite ($bf,start_tag("ANSWER",7,true)); + //Print answer contents + fwrite ($bf,full_tag("JUMPTO",8,false,$answer->jumpto)); + fwrite ($bf,full_tag("TIMECREATED",8,false,$answer->timecreated)); + fwrite ($bf,full_tag("TIMEMODIFIED",8,false,$answer->timemodified)); + fwrite ($bf,full_tag("ANSWERTEXT",8,false,$answer->answer)); + fwrite ($bf,full_tag("RESPONSE",8,false,$answer->response)); + //Now we backup any lesson attempts (if student data required) + if ($preferences->mods["lesson"]->userinfo) { + $status = backup_lesson_attempts($bf,$preferences,$answer->id); + } + //End rubric + $status =fwrite ($bf,end_tag("ANSWER",7,true)); + } + //Write end tag + $status =fwrite ($bf,end_tag("ANSWERS",6,true)); + } + return $status; + } + + //Backup lesson_attempts contents (executed from lesson_backup_answers) + function backup_lesson_attempts ($bf,$preferences,$answerid) { + + global $CFG; + + $status = true; + + $lesson_attempts = get_records("lesson_attempts","answerid", $answerid); + //If there are attempts + if ($lesson_attempts) { + //Write start tag + $status =fwrite ($bf,start_tag("ATTEMPTS",4,true)); + //Iterate over each attempt + foreach ($lesson_attempts as $attempt) { + //Start Attempt + $status =fwrite ($bf,start_tag("ATTEMPT",5,true)); + //Print attempt contents + fwrite ($bf,full_tag("USERID",6,false,$attempt->userid)); + fwrite ($bf,full_tag("CORRECT",6,false,$attempt->correct)); + fwrite ($bf,full_tag("TIMESEEN",6,false,$attempt->timeseen)); + fwrite ($bf,full_tag("RETRY",6,false,$attempt->retry)); + //End attempt + $status =fwrite ($bf,end_tag("ATTEMPT",5,true)); + } + //Write end tag + $status =fwrite ($bf,end_tag("ATTEMPTS",4,true)); + } + return $status; + } + + + //Backup lesson_grades contents (executed from backup_lesson_mods) + function backup_lesson_grades ($bf,$preferences,$lessonid) { + + global $CFG; + + $status = true; + + $grades = get_records("lesson_grades", "lessonid", $lessonid); + + //If there is grades + if ($grades) { + //Write start tag + $status =fwrite ($bf,start_tag("GRADES",8,true)); + //Iterate over each grade + foreach ($grades as $grade) { + //Start grade + $status =fwrite ($bf,start_tag("GRADE",9,true)); + //Print grade contents + fwrite ($bf,full_tag("USERID",10,false,$grade->userid)); + fwrite ($bf,full_tag("GRADE_VALUE",10,false,$grade->grade)); + fwrite ($bf,full_tag("LATE",10,false,$grade->late)); + fwrite ($bf,full_tag("COMPLETED",10,false,$grade->completed)); + //End comment + $status =fwrite ($bf,end_tag("GRADE",9,true)); + } + //Write end tag + $status =fwrite ($bf,end_tag("GRADES",8,true)); + } + return $status; + } + //Return an array of info (name,value) + function lesson_check_backup_mods($course,$user_data=false,$backup_unique_code) { + //First the course data + $info[0][0] = get_string("modulenameplural","lesson"); + if ($ids = lesson_ids($course)) { + $info[0][1] = count($ids); + } else { + $info[0][1] = 0; + } + + //Now, if requested, the user_data + if ($user_data) { + $info[1][0] = get_string("attempts","lesson"); + if ($ids = lesson_attempts_ids_by_course ($course)) { + $info[1][1] = count($ids); + } else { + $info[1][1] = 0; + } + } + return $info; + } + + + + // INTERNAL FUNCTIONS. BASED IN THE MOD STRUCTURE + + //Returns an array of lesson id + function lesson_ids ($course) { + + global $CFG; + + return get_records_sql ("SELECT l.id, l.course + FROM {$CFG->prefix}lesson l + WHERE l.course = '$course'"); + } + + //Returns an array of lesson_submissions id + function lesson_attempts_ids_by_course ($course) { + + global $CFG; + + return get_records_sql ("SELECT a.id , a.lessonid + FROM {$CFG->prefix}lesson_attempts a, + {$CFG->prefix}lesson l + WHERE l.course = '$course' AND + a.lessonid = l.id"); + } +?> diff --git a/mod/lesson/db/mysql.php b/mod/lesson/db/mysql.php new file mode 100644 index 0000000000..b3bfa4dd34 --- /dev/null +++ b/mod/lesson/db/mysql.php @@ -0,0 +1,18 @@ + diff --git a/mod/lesson/db/mysql.sql b/mod/lesson/db/mysql.sql new file mode 100644 index 0000000000..4561319b6a --- /dev/null +++ b/mod/lesson/db/mysql.sql @@ -0,0 +1,72 @@ +# This file contains a complete database schema for all the +# tables used by the mlesson module, written in SQL + +# It may also contain INSERT statements for particular data +# that may be used, especially new entries in the table log_display + +CREATE TABLE `prefix_lesson` ( + `id` int(10) unsigned NOT NULL auto_increment, + `course` int(10) unsigned NOT NULL default '0', + `name` varchar(255) NOT NULL default '', + `grade` tinyint(3) NOT NULL default '0', + `maxanswers` int(3) unsigned NOT NULL default '4', + `retake` int(3) unsigned NOT NULL default '1', + `available` int(10) unsigned NOT NULL default '0', + `deadline` int(10) unsigned NOT NULL default '0', + `timemodified` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`id`) +) COMMENT='Defines lesson'; +# -------------------------------------------------------- + +CREATE TABLE `prefix_lesson_pages` ( + `id` int(10) unsigned NOT NULL auto_increment, + `lessonid` int(10) unsigned NOT NULL default '0', + `prevpageid` int(10) unsigned NOT NULL default '0', + `nextpageid` int(10) unsigned NOT NULL default '0', + `timecreated` int(10) unsigned NOT NULL default '0', + `timemodified` int(10) unsigned NOT NULL default '0', + `title` varchar(255) NOT NULL default '', + `contents` text NOT NULL default '', + PRIMARY KEY (`id`) +) COMMENT='Defines lesson_pages'; +# -------------------------------------------------------- + +CREATE TABLE `prefix_lesson_answers` ( + `id` int(10) unsigned NOT NULL auto_increment, + `lessonid` int(10) unsigned NOT NULL default '0', + `pageid` int(10) unsigned NOT NULL default '0', + `jumpto` int(11) NOT NULL default '0', + `timecreated` int(10) unsigned NOT NULL default '0', + `timemodified` int(10) unsigned NOT NULL default '0', + `answer` text NOT NULL default '', + `response` text NOT NULL default '', + PRIMARY KEY (`id`) +) COMMENT='Defines lesson_answers'; +# -------------------------------------------------------- + +CREATE TABLE `prefix_lesson_attempts` ( + `id` int(10) unsigned NOT NULL auto_increment, + `lessonid` int(10) unsigned NOT NULL default '0', + `pageid` int(10) unsigned NOT NULL default '0', + `userid` int(10) unsigned NOT NULL default '0', + `answerid` int(10) unsigned NOT NULL default '0', + `retry` int(3) unsigned NOT NULL default '0', + `correct` int(10) unsigned NOT NULL default '0', + `timeseen` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`id`) +) COMMENT='Defines lesson_attempts'; +# -------------------------------------------------------- + +CREATE TABLE `prefix_lesson_grades` ( + `id` int(10) unsigned NOT NULL auto_increment, + `lessonid` int(10) unsigned NOT NULL default '0', + `userid` int(10) unsigned NOT NULL default '0', + `grade` int(3) unsigned NOT NULL default '0', + `late` int(3) unsigned NOT NULL default '0', + `completed` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`id`) +) COMMENT='Defines lesson_grades'; +# -------------------------------------------------------- + + + diff --git a/mod/lesson/icon.gif b/mod/lesson/icon.gif new file mode 100755 index 0000000000000000000000000000000000000000..550df5db8c43d778c40a1290f1d3a724d0e88133 GIT binary patch literal 128 zcmZ?wbhEHb6krfwSoEKPf#I&Pahh>jn(@rE0|yTL|Np+Z^fq{iV2gnAh z6kuRrcJid); + + add_to_log($course->id, "lesson", "view all", "index.php?id=$course->id", ""); + + +/// Get all required strings + + $strlessons = get_string("modulenameplural", "lesson"); + $strlesson = get_string("modulename", "lesson"); + + +/// Print the header + + if ($course->category) { + $navigation = "id\">$course->shortname ->"; + } + + print_header("$course->shortname: $strlessons", "$course->fullname", "$navigation $strlessons", "", "", true, "", navmenu($course)); + +/// Get all the appropriate data + + if (! $lessons = get_all_instances_in_course("lesson", $course)) { + notice("There are no lessons", "../../course/view.php?id=$course->id"); + die; + } + +/// Print the list of instances (your module will probably extend this) + + $timenow = time(); + $strname = get_string("name"); + $strgrade = get_string("grade"); + $strdeadline = get_string("deadline", "lesson"); + $strweek = get_string("week"); + $strtopic = get_string("topic"); + + if ($course->format == "weeks") { + $table->head = array ($strweek, $strname, $strgrade, $strdeadline); + $table->align = array ("CENTER", "LEFT", "CENTER", "CENTER"); + } else if ($course->format == "topics") { + $table->head = array ($strtopic, $strname); + $table->align = array ("CENTER", "LEFT", "CENTER", "CENTER"); + } else { + $table->head = array ($strname); + $table->align = array ("LEFT", "CENTER", "CENTER"); + } + + foreach ($lessons as $lesson) { + if (!$lesson->visible) { + //Show dimmed if the mod is hidden + $link = "coursemodule\">$lesson->name"; + } else { + //Show normal if the mod is visible + $link = "coursemodule\">$lesson->name"; + } + + if ($lesson->deadline > $timenow) { + $due = userdate($lesson->deadline); + } else { + $due = "".userdate($lesson->deadline).""; + } + + if ($course->format == "weeks" or $course->format == "topics") { + if (isteacher($course->id)) { + $grade_value = $lesson->grade; + } else { + // it's a student, show their maximum grade + if ($grades = get_records_select("lesson_grades", "lessonid = $lesson->id AND + userid = $USER->id", "grade DESC")) { + foreach ($grades as $grade) { + // grades are stored as percentages + $grade_value = number_format($grade->grade * $lesson->grade / 100, 1); + break; // only the first (largest) grade needed + } + } else { + $grade_value = 0; + } + } + $table->data[] = array ($lesson->section, $link, $grade_value, $due); + } else { + $table->data[] = array ($link, $grade_value, $due); + } + } + + echo "
"; + + print_table($table); + +/// Finish the page + + print_footer($course); + +?> diff --git a/mod/lesson/lesson.php b/mod/lesson/lesson.php new file mode 100644 index 0000000000..4654026045 --- /dev/null +++ b/mod/lesson/lesson.php @@ -0,0 +1,669 @@ +course)) { + error("Course is misconfigured"); + } + + if (! $lesson = get_record("lesson", "id", $cm->instance)) { + error("Course module is incorrect"); + } + + require_login($course->id); + + // set up some general variables + $usehtmleditor = can_use_html_editor(); + echo "\$usehtmleditor:$usehtmleditor"; + + $navigation = ""; + if ($course->category) { + $navigation = "id\">$course->shortname ->"; + } + + $strlessons = get_string("modulenameplural", "lesson"); + $strlesson = get_string("modulename", "lesson"); + $strlessonname = $lesson->name; + + // ... print the header and... + print_header("$course->shortname: $lesson->name", "$course->fullname", + "$navigation id>$strlessons -> + id\">$lesson->name -> $action", + "", "", true); + + //...get the action + require_variable($action); + + + /************** add page ************************************/ + if ($action == 'addpage' ) { + + if (!isteacher($course->id)) { + error("Only teachers can look at this page"); + } + + // first get the preceeding page + $pageid = $_GET['pageid']; + + // set of jump array + $jump[0] = get_string("thispage", "lesson"); + $jump[NEXTPAGE] = get_string("nextpage", "lesson"); + $jump[EOL] = get_string("endoflesson", "lesson"); + if (!$apageid = get_field("lesson_pages", "id", "lessonid", $lesson->id, "prevpageid", 0)) { + error("Add page: first page not found"); + } + while (true) { + if ($apageid) { + $title = get_field("lesson_pages", "title", "id", $apageid); + $jump[$apageid] = $title; + $apageid = get_field("lesson_pages", "nextpageid", "id", $apageid); + } else { + // last page reached + break; + } + } + + // give teacher a blank proforma + print_heading_with_help(get_string("addanewpage", "lesson"), "overview", "lesson"); + ?> +

+ + + +
+ + + \n"; + for ($i = 0; $i < $lesson->maxanswers; $i++) { + $iplus1 = $i + 1; + echo "\n"; + echo "\n"; + echo "\n"; + } + use_html_editor(); + // close table and form + ?> +
+
:
+
"; + echo get_string("pagecontents", "lesson").":
\n"; + print_textarea($usehtmleditor, 25,70, 630, 400, "contents"); + echo "
".get_string("answer", "lesson")." $iplus1:
\n"; + print_textarea($usehtmleditor, 20, 70, 630, 300, "answer[$i]"); + echo "
".get_string("response", "lesson")." $iplus1:
\n"; + print_textarea($usehtmleditor, 20, 70, 630, 300, "response[$i]"); + echo "
".get_string("jumpto", "lesson").": \n"; + if ($i) { + // answers 2, 3, 4... jumpto this page + lesson_choose_from_menu($jump, "jumpto[$i]", 0, ""); + } else { + // answer 1 jumpto next page + lesson_choose_from_menu($jump, "jumpto[$i]", NEXTPAGE, ""); + } + helpbutton("jumpto", get_string("jumpto", "lesson"), "lesson"); + echo "

+ "> + "> +
+
+ id)) { + error("Only teachers can look at this page"); + } + + if (empty($_GET['pageid'])) { + error("Confirm delete: pageid missing"); + } + $pageid = $_GET['pageid']; + if (!$thispage = get_record("lesson_pages", "id", $pageid)) { + error("Confirm delete: the page record not found"); + } + print_heading(get_string("deletingpage", "lesson", $thispage->title)); + // print the jumps to this page + if ($answers = get_records_select("lesson_answers", "lessonid = $lesson->id AND jumpto = $pageid + 1")) { + print_heading(get_string("thefollowingpagesjumptothispage", "lesson")); + echo "

\n"; + foreach ($answers as $answer) { + if (!$title = get_field("lesson_pages", "title", "id", $answer->pageid)) { + error("Confirm delete: page title not found"); + } + echo $title."
\n"; + } + } + notice_yesno(get_string("confirmdeletionofthispage","lesson"), + "lesson.php?action=delete&id=$cm->id&pageid=$pageid]", + "view.php?id=$cm->id"); + } + + + /****************** continue ************************************/ + elseif ($action == 'continue' ) { + // record answer (if necessary) and show response (if any) + + if (empty($_POST['pageid'])) { + error("Continue: pageid missing"); + } + $pageid = $_POST['pageid']; + // get the answer + if (empty($_POST['answerid'])) { + print_heading(get_string("noanswer", "lesson")); + redirect("view.php?id=$cm->id&action=navigation&pageid=$pageid", + get_string("continue", "lesson")); + } else { + $answerid = $_POST['answerid']; + if (!$answer = get_record("lesson_answers", "id", $answerid)) { + error("Continue: answer record not found"); + } + $ntries = count_records("lesson_grades", "lessonid", $lesson->id, "userid", $USER->id); + if (isstudent($course->id)) { + // record student's attempt + $correct = get_field("lesson_answers", "correct", "id", $answerid); + $attempt->lessonid = $lesson->id; + $attempt->pageid = $pageid; + $attempt->userid = $USER->id; + $attempt->answerid = $answerid; + $attempt->retry = $ntries; + $attempt->correct = lesson_iscorrect($pageid, $answer->jumpto); + $attempt->timeseen = time(); + if (!$newattemptid = insert_record("lesson_attempts", $attempt)) { + error("Continue: attempt not inserted"); + } + } + + // convert jumpto to a proper page id + if ($answer->jumpto == 0) { + $newpageid = $pageid; + } elseif ($answer->jumpto == NEXTPAGE) { + if (!$newpageid = get_field("lesson_pages", "nextpageid", "id", $pageid)) { + // no nextpage go to end of lesson + $newpageid = EOL; + } + } else { + $newpageid = $answer->jumpto; + } + + // display response (if there is one) + if ($answer->response) { + $title = get_field("lesson_pages", "title", "id", $pageid); + print_heading($title); + echo "
\n"; + print_simple_box(format_text($answer->response), 'center'); + echo "
\n"; + print_continue("view.php?id=$cm->id&action=navigation&pageid=$newpageid"); + } else { + // there's no response text - just go straight to the next page + redirect("lesson.php?id=$cm->id&action=navigation&pageid=$newpageid", + get_string("continue")); + } + } + } + + + + /******************* delete ************************************/ + elseif ($action == 'delete' ) { + + if (!isteacher($course->id)) { + error("Only teachers can look at this page"); + } + + if (empty($_GET['pageid'])) { + error("Delete: pageid missing"); + } + $pageid = $_GET['pageid']; + if (!$thispage = get_record("lesson_pages", "id", $pageid)) { + error("Delete: page record not found"); + } + + print_string("deleting", "lesson"); + // first delete all the associated records... + delete_records("lesson_attempts", "pageid", $pageid); + // ...now delete the answers... + delete_records("lesson_answers", "pageid", $pageid); + // ..and the page itself + delete_records("lesson_pages", "id", $pageid); + + // repair the hole in the linkage + if (!$thispage->prevpageid) { + // this is the first page... + if (!$page = get_record("lesson_pages", "id", $thispage->nextpageid)) { + error("Delete: next page not found"); + } + if (!set_field("lesson_pages", "prevpageid", 0, "id", $page->id)) { + error("Delete: unable to set prevpage link"); + } + } elseif (!$thispage->nextpageid) { + // this is the last page... + if (!$page = get_record("lesson_pages", "id", $thispage->prevpageid)) { + error("Delete: prev page not found"); + } + if (!set_field("lesson_pages", "nextpageid", 0, "id", $page->id)) { + error("Delete: unable to set nextpage link"); + } + } else { + // page is in the middle... + if (!$prevpage = get_record("lesson_pages", "id", $thispage->prevpageid)) { + error("Delete: prev page not found"); + } + if (!$nextpage = get_record("lesson_pages", "id", $thispage->nextpageid)) { + error("Delete: next page not found"); + } + if (!set_field("lesson_pages", "nextpageid", $nextpage->id, "id", $prevpage->id)) { + error("Delete: unable to set next link"); + } + if (!set_field("lesson_pages", "prevpageid", $prevpage->id, "id", $nextpage->id)) { + error("Delete: unable to set prev link"); + } + } + redirect("view.php?id=$cm->id", get_string("ok")); + } + + + + /************** edit page ************************************/ + elseif ($action == 'editpage' ) { + + if (!isteacher($course->id)) { + error("Only teachers can look at this page"); + } + + // get the page + if (!$page = get_record("lesson_pages", "id", $_GET['pageid'])) { + error("Edit page: page record not found"); + } + // set of jump array + $jump[0] = get_string("thispage", "lesson"); + $jump[NEXTPAGE] = get_string("nextpage", "lesson"); + $jump[EOL] = get_string("endoflesson", "lesson"); + if (!$apageid = get_field("lesson_pages", "id", "lessonid", $lesson->id, "prevpageid", 0)) { + error("Edit page: first page not found"); + } + while (true) { + if ($apageid) { + $title = get_field("lesson_pages", "title", "id", $apageid); + $jump[$apageid] = $title; + $apageid = get_field("lesson_pages", "nextpageid", "id", $apageid); + } else { + // last page reached + break; + } + } + + // give teacher a proforma + ?> +

+ + + +
+ + + + \n"; + $n = 0; + if ($answers = get_records("lesson_answers", "pageid", $page->id, "id")) { + foreach ($answers as $answer) { + $nplus1 = $n + 1; + echo "id\">\n"; + echo "\n"; + echo "\n"; + echo "\n"; + $n++; + } + } + for ($i = $n; $i < $lesson->maxanswers; $i++) { + $iplus1 = $i + 1; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + } + use_html_editor(); + // close table and form + ?> +
+
:
+
"; + echo get_string("pagecontents", "lesson").":
\n"; + print_textarea($usehtmleditor, 25, 70, 630, 400, "contents", $page->contents); + echo "
".get_string("answer", "lesson")." $nplus1:
\n"; + print_textarea($usehtmleditor, 20, 70, 630, 300, "answer[$n]", $answer->answer); + echo "
".get_string("response", "lesson")." $nplus1:
\n"; + print_textarea($usehtmleditor, 20, 70, 630, 300, "response[$n]", $answer->response); + echo "
".get_string("jumpto", "lesson").": \n"; + lesson_choose_from_menu($jump, "jumpto[$n]", $answer->jumpto, ""); + helpbutton("jumpto", get_string("jumpto", "lesson"), "lesson"); + echo "
".get_string("answer", "lesson")." $iplus1:
\n"; + print_textarea($usehtmleditor, 20, 70, 630, 300, "answer[$i]"); + echo "
".get_string("response", "lesson")." $iplus1:
\n"; + print_textarea($usehtmleditor, 20, 70, 630, 300, "response[$i]"); + echo "
".get_string("jumpto", "lesson").": \n"; + lesson_choose_from_menu($jump, "jumpto[$i]", 0, ""); + helpbutton("jumpto", get_string("jumpto", "lesson"), "lesson"); + echo "

+ "> + "> +
+
+ id)) { + error("Only teachers can look at this page"); + } + + $timenow = time(); + $form = (object) $HTTP_POST_VARS; + + if ($form->pageid) { + // the new page is not the first page + if (!$page = get_record("lesson_pages", "id", $form->pageid)) { + error("Insert page: page record not found"); + } + $newpage->lessonid = $lesson->id; + $newpage->prevpageid = $form->pageid; + $newpage->nextpageid = $page->nextpageid; + $newpage->timecreated = $timenow; + $newpage->title = $form->title; + $newpage->contents = trim($form->contents); + $newpageid = insert_record("lesson_pages", $newpage); + if (!$newpageid) { + error("Insert page: new page not inserted"); + } + // update the linked list + if (!set_field("lesson_pages", "nextpageid", $newpageid, "id", $form->pageid)) { + error("Insert page: unable to update link"); + } + } else { + // new page is the first page + // get the existing (first) page (if any) + if (!$page = get_record_select("lesson_pages", "lessonid = $lesson->id AND prevpageid = 0")) { + // there are no existing pages + $newpage->lessonid = $lesson->id; + $newpage->prevpageid = 0; // this is a first page + $newpage->nextpageid = 0; // this is the only page + $newpage->timecreated = $timenow; + $newpage->title = $form->title; + $newpage->contents = trim($form->contents); + $newpageid = insert_record("lesson_pages", $newpage); + if (!$newpageid) { + error("Insert page: new first page not inserted"); + } + } else { + // there are existing pages put this at the start + $newpage->lessonid = $lesson->id; + $newpage->prevpageid = 0; // this is a first page + $newpage->nextpageid = $page->id; + $newpage->timecreated = $timenow; + $newpage->title = $form->title; + $newpage->contents = trim($form->contents); + $newpageid = insert_record("lesson_pages", $newpage); + if (!$newpageid) { + error("Insert page: first page not inserted"); + } + // update the linked list + if (!set_field("lesson_pages", "prevpageid", $newpageid, "id", $page->id)) { + error("Insert page: unable to update link"); + } + } + } + // now add the answers + for ($i = 0; $i < $lesson->maxanswers; $i++) { + if (trim(strip_tags($form->answer[$i]))) { // strip_tags because the HTML editor adds


... + $newanswer->lessonid = $lesson->id; + $newanswer->pageid = $newpageid; + $newanswer->timecreated = $timenow; + $newanswer->answer = trim($form->answer[$i]); + $newanswer->response = trim($form->response[$i]); + if (isset($form->jumpto[$i])) { + $newanswer->jumpto = $form->jumpto[$i]; + } + $newanswerid = insert_record("lesson_answers", $newanswer); + if (!$newanswerid) { + error("Insert Page: answer record $i not inserted"); + } + } else { + break; + } + } + redirect("view.php?id=$cm->id", get_string("ok")); + } + + + /****************** move ************************************/ + elseif ($action == 'move') { + + if (!isteacher($course->id)) { + error("Only teachers can look at this page"); + } + + $pageid = $_GET['pageid']; + $title = get_field("lesson_pages", "title", "id", $pageid); + print_heading(get_string("moving", "lesson", $title)); + + if (!$page = get_record_select("lesson_pages", "lessonid = $lesson->id AND prevpageid = 0")) { + error("Move: first page not found"); + } + + echo "

\n"; + echo "\n"; + while (true) { + if ($page->id != $pageid) { + echo "\n"; + echo "\n"; + } + if ($page->nextpageid) { + if (!$page = get_record("lesson_pages", "id", $page->nextpageid)) { + error("Teacher view: Next page not found!"); + } + } else { + // last page reached + break; + } + } + echo "
id&action=moveit&pageid=$pageid&after=0\">". + get_string("movepagehere", "lesson")."
cellheading2\">$page->title
id&action=moveit&pageid=$pageid&after={$page->id}\">". + get_string("movepagehere", "lesson")."
\n"; + } + + + /****************** moveit ************************************/ + elseif ($action == 'moveit') { + + if (!isteacher($course->id)) { + error("Only teachers can look at this page"); + } + + $pageid = $_GET['pageid']; // page to move + if (!$page = get_record("lesson_pages", "id", $pageid)) { + error("Moveit: page not found"); + } + $after = $_GET['after']; // target page + + print_heading(get_string("moving", "lesson", $page->title)); + + // first step. determine the new first page + // (this is done first as the current first page will be lost in the next step) + if (!$after) { + // the moved page is the new first page + $newfirstpageid = $pageid; + // reset $after so that is points to the last page + // (when the pages are in a ring this will in effect be the first page) + if ($page->nextpageid) { + if (!$after = get_field("lesson_pages", "id", "lessonid", $lesson->id, "nextpageid", 0)) { + error("Moveit: last page id not found"); + } + } else { + // the page being moved is the last page, so the new last page will be + $after = $page->prevpageid; + } + } elseif (!$page->prevpageid) { + // the page to be moved was the first page, so the following page must be the new first page + $newfirstpageid = $page->nextpageid; + } else { + // the current first page remains the first page + if (!$newfirstpageid = get_field("lesson_pages", "id", "lessonid", $lesson->id, "prevpageid", 0)) { + error("Moveit: current first page id not found"); + } + } + // the rest is all unconditional... + + // second step. join pages into a ring + if (!$firstpageid = get_field("lesson_pages", "id", "lessonid", $lesson->id, "prevpageid", 0)) { + error("Moveit: firstpageid not found"); + } + if (!$lastpageid = get_field("lesson_pages", "id", "lessonid", $lesson->id, "nextpageid", 0)) { + error("Moveit: lastpage not found"); + } + if (!set_field("lesson_pages", "prevpageid", $lastpageid, "id", $firstpageid)) { + error("Moveit: unable to update link"); + } + if (!set_field("lesson_pages", "nextpageid", $firstpageid, "id", $lastpageid)) { + error("Moveit: unable to update link"); + } + + echo "

\$newfirstpageid: $newfirstpageid"; + echo "

\$after: $after"; + + // third step. remove the page to be moved + if (!$prevpageid = get_field("lesson_pages", "prevpageid", "id", $pageid)) { + error("Moveit: prevpageid not found"); + } + if (!$nextpageid = get_field("lesson_pages", "nextpageid", "id", $pageid)) { + error("Moveit: nextpageid not found"); + } + if (!set_field("lesson_pages", "nextpageid", $nextpageid, "id", $prevpageid)) { + error("Moveit: unable to update link"); + } + if (!set_field("lesson_pages", "prevpageid", $prevpageid, "id", $nextpageid)) { + error("Moveit: unable to update link"); + } + + // fourth step. insert page to be moved in new place... + if (!$nextpageid = get_field("lesson_pages", "nextpageid", "id", $after)) { + error("Movit: nextpageid not found"); + } + if (!set_field("lesson_pages", "nextpageid", $pageid, "id", $after)) { + error("Moveit: unable to update link"); + } + if (!set_field("lesson_pages", "prevpageid", $pageid, "id", $nextpageid)) { + error("Moveit: unable to update link"); + } + // ...and set the links in the moved page + if (!set_field("lesson_pages", "prevpageid", $after, "id", $pageid)) { + error("Moveit: unable to update link"); + } + if (!set_field("lesson_pages", "nextpageid", $nextpageid, "id", $pageid)) { + error("Moveit: unable to update link"); + } + + // fifth step. break the ring + if (!$newlastpageid = get_field("lesson_pages", "prevpageid", "id", $newfirstpageid)) { + error("Moveit: newlastpageid not found"); + } + if (!set_field("lesson_pages", "prevpageid", 0, "id", $newfirstpageid)) { + error("Moveit: unable to update link"); + } + if (!set_field("lesson_pages", "nextpageid", 0, "id", $newlastpageid)) { + error("Moveit: unable to update link"); + } + } + + + /****************** update page ************************************/ + elseif ($action == 'updatepage' ) { + + if (!isteacher($course->id)) { + error("Only teachers can look at this page"); + } + + $timenow = time(); + $form = (object) $HTTP_POST_VARS; + + $page->id = $form->pageid; + $page->timemodified = $timenow; + $page->title = $form->title; + $page->contents = trim($form->contents); + if (!update_record("lesson_pages", $page)) { + error("Update page: page not updated"); + } + for ($i = 0; $i < $lesson->maxanswers; $i++) { + if (trim(strip_tags($form->answer[$i]))) { // strip_tags because the HTML gives


... + if ($form->answerid[$i]) { + $oldanswer->id = $form->answerid[$i]; + $oldanswer->timemodified = $timenow; + $oldanswer->answer = trim($form->answer[$i]); + $oldanswer->response = trim($form->response[$i]); + $oldanswer->jumpto = $form->jumpto[$i]; + if (!update_record("lesson_answers", $oldanswer)) { + error("Update page: answer $i not updated"); + } + } else { + // it's a new answer + $newanswer->lessonid = $lesson->id; + $newanswer->pageid = $page->id; + $newanswer->timecreated = $timenow; + $newanswer->answer = trim($form->answer[$i]); + $newanswer->response = trim($form->response[$i]); + $newanswer->jumpto = $form->jumpto[$i]; + $newanswerid = insert_record("lesson_answers", $newanswer); + if (!$newanswerid) { + error("Update page: answer record not inserted"); + } + } + } else { + if ($form->answerid[$i]) { + // need to delete blanked out answer + if (!delete_records("lesson_answers", "id", $form->answerid[$i])) { + error("Update page: unable to delete answer record"); + } + } + } + } + redirect("view.php?id=$cm->id", get_string("ok")); + } + + + /*************** no man's land **************************************/ + else { + error("Fatal Error: Unknown Action: ".$action."\n"); + } + + print_footer($course); + +?> + diff --git a/mod/lesson/lib.php b/mod/lesson/lib.php new file mode 100644 index 0000000000..d4800d348c --- /dev/null +++ b/mod/lesson/lib.php @@ -0,0 +1,316 @@ +\n"; + if ($nothing) { + $output .= "

".get_string("gradeis", "lesson", $max_grade)." (". + get_string("attempts", "lesson").": ".count($grades).")

"; + } else { + echo "

".get_string("gradeis", "lesson", $max_grade)."

"; + } + } + } else { + echo get_string("no")." ".get_string("attempts", "lesson"); + } + + + return true; +} + +/*******************************************************************/ +function lesson_print_recent_activity($course, $isteacher, $timestart) { +/// Given a course and a time, this module should find recent activity +/// that has occurred in lesson activities and print it out. +/// Return true if there was output, or false is there was none. + + global $CFG; + + return false; // True if anything was printed, otherwise false +} + +/*******************************************************************/ +function lesson_cron () { +/// Function to be run periodically according to the moodle cron +/// This function searches for things that need to be done, such +/// as sending out mail, toggling flags etc ... + + global $CFG; + + return true; +} + +/*******************************************************************/ +function lesson_grades($lessonid) { +/// Must return an array of grades for a given instance of this module, +/// indexed by user. It also returns a maximum allowed grade. + global $CFG; + + if (!$lesson = get_record("lesson", "id", $lessonid)) { + error("Lesson record not found"); + } + $grades = get_records_sql_menu("SELECT userid,MAX(grade) FROM {$CFG->prefix}lesson_grades WHERE + lessonid = $lessonid GROUP BY userid"); + + // convert grades from percentages and tidy the numbers + if ($grades) { + foreach ($grades as $userid => $grade) { + $return->grades[$userid] = number_format($grade * $lesson->grade / 100.0, 1); + } + } + $return->maxgrade = $lesson->grade; + + return $return; +} + +/*******************************************************************/ +function lesson_get_participants($lessonid) { +//Must return an array of user records (all data) who are participants +//for a given instance of lesson. Must include every user involved +//in the instance, independient of his role (student, teacher, admin...) +//See other modules as example. + + return false; +} + +////////////////////////////////////////////////////////////////////////////////////// +/// Any other lesson functions go here. Each of them must have a name that +/// starts with lesson_ + +/*******************************************************************/ +function lesson_iscorrect($pageid, $jumpto) { + // returns true is jumpto page is (logically) after the pageid page, other returns false + + // first test the special values + if (!$jumpto) { + // same page + return false; + } elseif ($jumpto == NEXTPAGE) { + return true; + } elseif ($jumpto == EOL) { + return true; + } + // we have to run through the pages from pageid looking for jumpid + $apageid = get_field("lesson_pages", "nextpageid", "id", $pageid); + while (true) { + if ($jumpto == $apageid) { + return true; + } + if ($apageid) { + $apageid = get_field("lesson_pages", "nextpageid", "id", $apageid); + } else { + return false; + } + } + return false; // should never be reached +} + +?> diff --git a/mod/lesson/mod.html b/mod/lesson/mod.html new file mode 100644 index 0000000000..f30cae3567 --- /dev/null +++ b/mod/lesson/mod.html @@ -0,0 +1,101 @@ + + +name)) { + $form->name = ""; + } + if (!isset($form->grade)) { + $form->grade = 0; + } + if (!isset($form->maxanswers)) { + $form->maxanswers = 4; + } + if (!isset($form->retake)) { + $form->retake = 1; + } + if (!isset($form->available)) { + $form->available = 0; + } + if (!isset($form->deadline)) { + $form->deadline = 0; + } +?> + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

:

+ +

:

+ =0; $i--) { + $grades[$i] = $i; + } + choose_from_menu($grades, "grade", "$form->grade", ""); + helpbutton("grade", get_string("maximumgrade", "lesson"), "lesson"); + ?> +

:

+ 1; $i--) { + $numbers[$i] = $i; + } + choose_from_menu($numbers, "maxanswers", "$form->maxanswers", ""); + helpbutton("maxanswers", get_string("maximumnumberofanswers", "lesson"), "lesson"); + ?> +

student) ?>:

+ retake, ""); + helpbutton("retake", get_string("canretake", "lesson"), "lesson"); + ?> +

:

available); + echo " - "; + print_time_selector("availablehour", "availableminute", $form->available); + ?>

:

deadline); + echo " - "; + print_time_selector("deadlinehour", "deadlineminute", $form->deadline); + ?>
+ + + + + + + + +"> +
+
diff --git a/mod/lesson/restorelib.php b/mod/lesson/restorelib.php new file mode 100644 index 0000000000..486507bf3d --- /dev/null +++ b/mod/lesson/restorelib.php @@ -0,0 +1,329 @@ +id) | + // | | + // | lesson_grades + // | (UL, pk->id,fk->lessonid) + // lesson_pages + // (pk->id,fk->lessonid) + // | + // | + // | + // lesson_answers + // (pk->id,fk->pageid) + // | + // | + // | + // lesson_attempts + // (UL,pk->id,fk->answerid) + // + // Meaning: pk->primary key field of the table + // fk->foreign key to link with parent + // nt->nested field (recursive data) + // CL->course level info + // UL->user level info + // files->table may have files) + // + //----------------------------------------------------------- + + //This function executes all the restore procedure about this mod + function lesson_restore_mods($mod,$restore) { + + global $CFG; + + $status = true; + + //Get record from backup_ids + $data = backup_getid($restore->backup_unique_code,$mod->modtype,$mod->id); + + if ($data) { + //Now get completed xmlized object + $info = $data->info; + //traverse_xmlize($info); //Debug + //print_object ($GLOBALS['traverse_array']); //Debug + //$GLOBALS['traverse_array']=""; //Debug + + //Now, build the lesson record structure + $lesson->course = $restore->course_id; + $lesson->name = backup_todb($info['MOD']['#']['NAME']['0']['#']); + $lesson->grade = backup_todb($info['MOD']['#']['GRADE']['0']['#']); + $lesson->maxanswers = backup_todb($info['MOD']['#']['MAXANSWERS']['0']['#']); + $lesson->retake = backup_todb($info['MOD']['#']['RETAKE']['0']['#']); + $lesson->available = backup_todb($info['MOD']['#']['AVAILABLE']['0']['#']); + $lesson->deadline = backup_todb($info['MOD']['#']['DEADLINE']['0']['#']); + $lesson->timemodified = backup_todb($info['MOD']['#']['TIMEMODIFIED']['0']['#']); + + //The structure is equal to the db, so insert the lesson + $newid = insert_record("lesson", $lesson); + + //Do some output + echo ""; + + } else { + $status = false; + } + + return $status; + } + + //This function restores the lesson_pages + function lesson_pages_restore_mods($lessonid,$info,$restore) { + + global $CFG; + + $status = true; + + //Get the lesson_elements array + $pages = $info['MOD']['#']['PAGES']['0']['#']['PAGE']; + + //Iterate over lesson pages (they are held in their logical order) + $prevpageid = 0; + for($i = 0; $i < sizeof($pages); $i++) { + $page_info = $pages[$i]; + //traverse_xmlize($ele_info); //Debug + //print_object ($GLOBALS['traverse_array']); //Debug + //$GLOBALS['traverse_array']=""; //Debug + + + //Now, build the lesson_pages record structure + $page->lessonid = $lessonid; + $page->prevpageid = $prevpageid; + $page->timecreated = backup_todb($page_info['#']['TIMECREATED']['0']['#']); + $page->timemodified = backup_todb($page_info['#']['TIMEMODIFIED']['0']['#']); + $page->title = backup_todb($page_info['#']['TITLE']['0']['#']); + $page->contents = backup_todb($page_info['#']['CONTENTS']['0']['#']); + + //The structure is equal to the db, so insert the lesson_elements + $newid = insert_record ("lesson_pages",$page); + + // save the new pageids (needed to fix the absolute jumps in the answers) + $newpageid[backup_todb($page_info['#']['PAGEID']['0']['#'])] = $newid; + + // fix the forwards link of the previous page + if ($prevpageid) { + if (!set_field("lesson_pages", "nextpageid", $newid, "id", $prevpageid)) { + error("Lesson restorelib: unable to update link"); + } + } + $prevpageid = $newid; + + //Do some output + if (($i+1) % 10 == 0) { + echo "."; + if (($i+1) % 200 == 0) { + echo "
"; + } + backup_flush(300); + } + + if ($newid) { + //We have to restore the lesson_answers table now (a page level table) + $status = lesson_answers_restore($lessonid,$newid,$page_info,$restore); + } else { + $status = false; + } + } + + // we've restored all the pages and answers, we now need to fix the jumps in the + // answer records if they are absolute + if ($answers = get_records("lesson_answers", "lessonid", $lessonid)) { + foreach ($answers as $answer) { + if ($answer->jumpto > 0) { + // change the absolute page id + if (!set_field("lesson_answers", "jumpto", $newpageid[$answer->jumpto], "id", + $answer->id)) { + error("Lesson restorelib: unable to reset jump"); + } + } + } + } + + return $status; + } + + + //This function restores the lesson_answers + function lesson_answers_restore($lessonid,$pageid,$info,$restore) { + + global $CFG; + + $status = true; + + //Get the lesson_answers array (optional) + if (isset($info['#']['ANSWERS']['0']['#']['ANSWER'])) { + $answers = $info['#']['ANSWERS']['0']['#']['ANSWER']; + + //Iterate over lesson_answers + for($i = 0; $i < sizeof($answers); $i++) { + $answer_info = $answers[$i]; + //traverse_xmlize($rub_info); //Debug + //print_object ($GLOBALS['traverse_array']); //Debug + //$GLOBALS['traverse_array']=""; //Debug + + //Now, build the lesson_answers record structure + $answer->lessonid = $lessonid; + $answer->pageid = $pageid; + // the absolute jumps will need fixing + $answer->jumpto = backup_todb($answer_info['#']['JUMPTO']['0']['#']); + $answer->timecreated = backup_todb($answer_info['#']['TIMECREATED']['0']['#']); + $answer->timemodified = backup_todb($answer_info['#']['TIMEMODIFIED']['0']['#']); + $answer->answer = backup_todb($answer_info['#']['ANSWERTEXT']['0']['#']); + $answer->response = backup_todb($answer_info['#']['RESPONSE']['0']['#']); + + //The structure is equal to the db, so insert the lesson_rubrics + $newid = insert_record ("lesson_answers",$answer); + + //Do some output + if (($i+1) % 10 == 0) { + echo "."; + if (($i+1) % 200 == 0) { + echo "
"; + } + backup_flush(300); + } + + if ($newid) { + if ($restore->mods['lesson']->userinfo) { + //We have to restore the lesson_attempts table now (a answers level table) + $status = lesson_attempts_restore($lessonid, $pageid, $newid, $answer_info, $restore); + } + } else { + $status = false; + } + } + } + return $status; + } + + + //This function restores the attempts + function lesson_attempts_restore($lessonid, $pageid, $answerid, $info, $restore) { + + global $CFG; + + $status = true; + + //Get the attempts array (optional) + if (isset($info['#']['ATTEMPTS']['0']['#']['ATTEMPT'])) { + $attempts = $info['#']['ATTEMPTS']['0']['#']['ATTEMPT']; + //Iterate over attempts + for($i = 0; $i < sizeof($attempts); $i++) { + $attempt_info = $attempts[$i]; + //traverse_xmlize($sub_info); //Debug + //print_object ($GLOBALS['traverse_array']); //Debug + //$GLOBALS['traverse_array']=""; //Debug + + //We'll need this later!! + $olduserid = backup_todb($attempt_info['#']['USERID']['0']['#']); + + //Now, build the lesson_attempts record structure + $attempt->lessonid = $lessonid; + $attempt->pageid = $pageid; + $attempt->answerid = $answerid; + $attempt->userid = backup_todb($attempt_info['#']['USERID']['0']['#']); + $attempt->correct = backup_todb($attempt_info['#']['CORRECT']['0']['#']); + $attempt->timeseen = backup_todb($attempt_info['#']['TIMESEEN']['0']['#']); + $attempt->retry = backup_todb($attempt_info['#']['RETRY']['0']['#']); + + //We have to recode the userid field + $user = backup_getid($restore->backup_unique_code,"user",$olduserid); + if ($user) { + $attempt->userid = $user->new_id; + } + + //The structure is equal to the db, so insert the lesson_attempt + $newid = insert_record ("lesson_attempts",$attempt); + + //Do some output + if (($i+1) % 50 == 0) { + echo "."; + if (($i+1) % 1000 == 0) { + echo "
"; + } + backup_flush(300); + } + } + } + + return $status; + } + + //This function restores the lesson_grades + function lesson_grades_restore_mods($lessonid, $info, $restore) { + + global $CFG; + + $status = true; + + //Get the grades array (optional) + if (isset($info['MOD']['#']['GRADES']['0']['#']['GRADE'])) { + $grades = $info['MOD']['#']['GRADES']['0']['#']['GRADE']; + + //Iterate over grades + for($i = 0; $i < sizeof($grades); $i++) { + $grade_info = $grades[$i]; + //traverse_xmlize($grade_info); //Debug + //print_object ($GLOBALS['traverse_array']); //Debug + //$GLOBALS['traverse_array']=""; //Debug + + //We'll need this later!! + $olduserid = backup_todb($grade_info['#']['USERID']['0']['#']); + + //Now, build the lesson_GRADES record structure + $grade->lessonid = $lessonid; + $grade->userid = backup_todb($grade_info['#']['USERID']['0']['#']); + $grade->grade = backup_todb($grade_info['#']['GRADE_VALUE']['0']['#']); + $grade->late = backup_todb($grade_info['#']['LATE']['0']['#']); + $grade->completed = backup_todb($grade_info['#']['COMPLETED']['0']['#']); + + //We have to recode the userid field + $user = backup_getid($restore->backup_unique_code,"user",$olduserid); + if ($user) { + $attempt->userid = $user->new_id; + } + + //The structure is equal to the db, so insert the lesson_grade + $newid = insert_record ("lesson_grades",$grade); + + //Do some output + if (($i+1) % 50 == 0) { + echo "."; + if (($i+1) % 1000 == 0) { + echo "
"; + } + backup_flush(300); + } + + if (!$newid) { + $status = false; + } + } + } + + return $status; + } + +?> diff --git a/mod/lesson/version.php b/mod/lesson/version.php new file mode 100644 index 0000000000..0e30fdd94f --- /dev/null +++ b/mod/lesson/version.php @@ -0,0 +1,12 @@ +version = 2004021400; // The current module version (Date: YYYYMMDDXX) +$module->requires = 2004013101; // Requires this Moodle version +$module->cron = 0; // Period for cron to check this module (secs) + +?> diff --git a/mod/lesson/view.php b/mod/lesson/view.php new file mode 100644 index 0000000000..a124986c1c --- /dev/null +++ b/mod/lesson/view.php @@ -0,0 +1,342 @@ +course)) { + error("Course is misconfigured"); + } + + if (! $lesson = get_record("lesson", "id", $cm->instance)) { + error("Course module is incorrect"); + } + + require_login($course->id); + + add_to_log($course->id, "lesson", "view", "view.php?id=$cm->id", "$lesson->id"); + +/// Print the page header + + if ($course->category) { + $navigation = "id\">$course->shortname ->"; + } + + $strlessons = get_string("modulenameplural", "lesson"); + $strlesson = get_string("modulename", "lesson"); + + print_header("$course->shortname: $lesson->name", "$course->fullname", + "$navigation id>$strlessons -> id\">$lesson->name", + "", "", true, update_module_button($cm->id, $course->id, $strlesson), + navmenu($course, $cm)); + + // set up some general variables + $usehtmleditor = can_use_html_editor(); + $path = "$CFG->wwwroot/course"; + if (empty($THEME->custompix)) { + $pixpath = "$path/../pix"; + } else { + $pixpath = "$path/../theme/$CFG->theme/pix"; + } + + if (empty($action)) { + if (isteacher($course->id)) { + $action = 'teacherview'; + } else { + $action = 'navigation'; + } + } + + /************** navigation **************************************/ + if ($action == 'navigation') { + // display individual pages and their sets of answers + // if pageid is EOL then the end of the lesson has been reached + print_heading($lesson->name); + if (empty($_GET['pageid'])) { + // if no pageid given see if the lesson has been started + if ($grades = get_records_select("lesson_grades", "lessonid = $lesson->id AND userid = $USER->id", + "grade DESC")) { + $retries = count($grades); + } else { + $retries = 0; + } + if ($retries) { + print_heading(get_string("attempt", "lesson", $retries + 1)); + } + // if there are any questions have been answered correctly in this attempt + if ($attempts = get_records_select("lesson_attempts", + "lessonid = $lesson->id AND userid = $USER->id AND retry = $retries AND + correct = 1", "timeseen DESC")) { + // get the first page + if (!$firstpageid = get_field("lesson_pages", "id", "lessonid", $lesson->id, + "prevpageid", 0)) { + error("Navigation: first page not found"); + } + foreach ($attempts as $attempt) { + $jumpto = get_field("lesson_answers", "jumpto", "id", $attempt->answerid); + // convert the jumpto to a proper page id + if ($jumpto == 0) { // unlikely value! + $lastpageseen = $attempt->pageid; + } elseif ($jumpto == NEXTPAGE) { + if (!$lastpageseen = get_field("lesson_pages", "nextpageid", "id", + $attempt->pageid)) { + // no nextpage go to end of lesson + $lastpageseen = EOL; + } + } else { + $lastpageseen = $jumpto; + } + break; // only look at the latest correct attempt + } + if ($lastpageseen != $firstpageid) { + notice_yesno(get_string("youhaveseen","lesson"), + "view.php?id=$cm->id&action=navigation&pageid=$lastpageseen", + "view.php?id=$cm->id&action=navigation&pageid=$firstpageid"); + print_footer($course); + exit(); + } + } + if ($grades) { + foreach ($grades as $grade) { + $bestgrade = $grade->grade; + break; + } + if (!$lesson->retake) { + redirect("../../course/view.php?id=$course->id", get_string("alreadytaken", "lesson")); + // allow student to retake course even if they have the maximum grade + // } elseif ($bestgrade == 100) { + // redirect("../../course/view.php?id=$course->id", get_string("maximumgradeachieved", + // "lesson")); + } + } + // start at the first page + if (!$pageid = get_field("lesson_pages", "id", "lessonid", $lesson->id, "prevpageid", 0)) { + error("Navigation: first page not found"); + } + } else { + $pageid = $_GET['pageid']; + } + if ($pageid != EOL) { + if (!$page = get_record("lesson_pages", "id", $pageid)) { + error("Navigation: the page record not found"); + } + echo "
\n"; + print_heading($page->title); + print_simple_box(format_text($page->contents), 'center'); + echo "
\n"; + if ($answers = get_records("lesson_answers", "pageid", $page->id)) { + shuffle($answers); + echo "
\n"; + echo "id\">\n"; + echo "\n"; + echo "\n"; + print_simple_box_start("center"); + foreach ($answers as $answer) { + echo "

id}\"> \n"; + $options->para = false; // no

+ echo format_text(trim($answer->answer), FORMAT_MOODLE, $options); + echo "

\n"; + } + print_simple_box_end(); + echo "

\n"; + echo "
\n"; + } else { + // a page without answers - find the next (logical) page + if (!$newpageid = get_field("lesson_pages", "nextpageid", "id", $pageid)) { + // this is the last page - flag end of lesson + $newpageid = EOL; + } + print_continue("view.php?id=$cm->id&action=navigation&pageid=$newpageid"); + } + echo "
\n"; + } else { + // end of lesson reached work out grade + print_heading(get_string("congratulations", "lesson")); + print_simple_box_start("center"); + $ntries = count_records("lesson_grades", "lessonid", $lesson->id, "userid", $USER->id); + if (isstudent($course->id)) { + $ncorrect = count_records_select("lesson_attempts", "lessonid = $lesson->id AND + userid = $USER->id AND retry = $ntries AND correct = 1"); + $nviewed = count_records("lesson_attempts", "lessonid", $lesson->id, "userid", $USER->id, + "retry", $ntries); + if ($nviewed) { + $thegrade = intval(100 * $ncorrect / $nviewed); + } else { + $thegrade = 0; + } + echo "

".get_string("numberofpagesviewed", "lesson", $nviewed)."

\n"; + echo "

".get_string("numberofcorrectanswers", "lesson", $ncorrect). + "

\n"; + echo "

".get_string("gradeis", "lesson", + number_format($thegrade * $lesson->grade / 100, 1)). + " (".get_string("outof", "lesson", $lesson->grade).")

\n"; + $grade->lessonid = $lesson->id; + $grade->userid = $USER->id; + $grade->grade = $thegrade; + $grade->completed = time(); + if (!$newgradeid = insert_record("lesson_grades", $grade)) { + error("Navigation: grade not inserted"); + } + } else { + // display for teacher + echo "

".get_string("displayofgrade", "lesson")."

\n"; + } + print_simple_box_end(); + print_continue("../../course/view.php?id=$course->id"); + } + + } + + + /*******************teacher view **************************************/ + elseif ($action == 'teacherview') { + print_heading_with_help($lesson->name, "overview", "lesson"); + // get number of pages + if ($page = get_record_select("lesson_pages", "lessonid = $lesson->id AND prevpageid = 0")) { + $npages = 1; + while (true) { + if ($page->nextpageid) { + if (!$page = get_record("lesson_pages", "id", $page->nextpageid)) { + error("Teacher view: Next page not found!"); + } + } else { + // last page reached + break; + } + $npages++; + } + } + + if (!$page = get_record_select("lesson_pages", "lessonid = $lesson->id AND prevpageid = 0")) { + // if there are no pages give teacher a blank proforma + ?> +
+ + + +
+ + + + \n"; + for ($i = 0; $i < $lesson->maxanswers; $i++) { + $iplus1 = $i + 1; + echo "\n"; + echo "\n"; + if ($i) { + // answers 2,3,4... jump to this page + echo "\n"; + } else { + // answer 1 jumps to next page + echo "\n"; + } + } + use_html_editor(); + // close table and form + ?> +
+

:

"; + echo get_string("pagecontents", "lesson").":
\n"; + print_textarea($usehtmleditor, 25, 70, 630, 400, "contents"); + echo "
".get_string("answer", "lesson")." $iplus1:
\n"; + print_textarea($usehtmleditor, 20, 70, 630, 100, "answer[$i]"); + echo "
".get_string("response", "lesson")." $iplus1:
\n"; + print_textarea($usehtmleditor, 20, 70, 630, 100, "response[$i]"); + echo "

+ "> + "> +
+
+ \n"; + echo "
id&action=addpage&pageid=0\">". + get_string("addpagehere", "lesson")."
\n"; + while (true) { + echo "\n"; + echo "\n"; + if ($answers = get_records("lesson_answers", "pageid", $page->id, "id")) { + $i = 1; + foreach ($answers as $answer) { + echo "\n"; + echo "\n"; + echo "\n"; + if ($answer->jumpto == 0) { + $jumptitle = get_string("thispage", "lesson"); + } elseif ($answer->jumpto == NEXTPAGE) { + $jumptitle = get_string("nextpage", "lesson"); + } elseif ($answer->jumpto == EOL) { + $jumptitle = get_string("endoflesson", "lesson"); + } else { + if (!$jumptitle = get_field("lesson_pages", "title", "id", $answer->jumpto)) { + $jumptitle = "".get_string("notdefined", "lesson").""; + } + } + echo "\n"; + $i++; + } + // print_simple_box_end(); + } + echo "
cellheading2\" colspan=\"2\">$page->title  \n"; + if ($npages > 1) { + echo "id&action=move&pageid=$page->id\">\n". + "\n"; + } + echo "id&action=editpage&pageid=$page->id\">\n". + "\n". + "id&action=confirmdelete&pageid=$page->id\">\n". + "". + "
\n"; + print_simple_box(format_text($page->contents), "center"); + echo "
cellheading2\" colspan=\"2\"> 
\n"; + if (lesson_iscorrect($page->id, $answer->jumpto)) { + // underline correct answers + echo "".get_string("answer", "lesson")." $i: \n"; + } else { + echo "".get_string("answer", "lesson")." $i: \n"; + } + echo "\n"; + echo format_text($answer->answer); + echo "
".get_string("response", "lesson")." $i: \n"; + echo "\n"; + echo format_text($answer->response); + echo "
".get_string("jumpto", "lesson").": \n"; + echo "\n"; + echo "$jumptitle
id&action=addpage&pageid=$page->id\">". + get_string("addpagehere", "lesson")."
\n"; + if ($page->nextpageid) { + if (!$page = get_record("lesson_pages", "id", $page->nextpageid)) { + error("Teacher view: Next page not found!"); + } + } else { + // last page reached + break; + } + } + echo "
\n"; + print_heading("id&action=navigation\">".get_string("checknavigation", + "lesson")."\n"); + } + } + + + /*************** no man's land **************************************/ + else { + error("Fatal Error: Unknown Action: ".$action."\n"); + } + +/// Finish the page + print_footer($course); + +?> -- 2.39.5