Support for extra question types added; Flash Card style lessons now an
[moodle.git] / mod / lesson / format.php
CommitLineData
394c97c8 1<?PHP // $Id$
2
3////////////////////////////////////////////////////////////////////
4/// format.php - Default format class for file imports/exports. //
5/// //
6/// Doesn't do everything on it's own -- it needs to be extended. //
7////////////////////////////////////////////////////////////////////
8
9// Included by import.php
10
11class quiz_default_format {
12
13 var $displayerrors = true;
14 var $category = NULL;
15 var $questionids = array();
16
17/// Importing functions
18
19 function importpreprocess() {
20 /// Does any pre-processing that may be desired
21
22 return true;
23 }
24
25 function importprocess($filename, $lesson, $pageid) {
26 /// Processes a given file. There's probably little need to change this
27 $timenow = time();
28
29 if (! $lines = $this->readdata($filename)) {
30 notify("File could not be read, or was empty");
31 return false;
32 }
33
34 if (! $questions = $this->readquestions($lines)) { // Extract all the questions
35 notify("There are no questions in this file!");
36 return false;
37 }
38
39 notify("Importing ".count($questions)." questions");
40
41 $count = 0;
42
43 foreach ($questions as $question) { // Process and store each question
44 switch ($question->qtype) {
45 // the good ones
46 case SHORTANSWER :
47 case NUMERICAL :
48 case TRUEFALSE :
49 case MULTICHOICE :
50 case MATCH :
51 $count++;
52
53 echo "<hr><p><b>$count</b>. ".stripslashes($question->questiontext)."</p>";
54 unset($newpage);
55 $newpage->lessonid = $lesson->id;
56 $newpage->qtype = $question->qtype;
57 switch ($question->qtype) {
58 case SHORTANSWER :
59 $newpage->qoption = $question->usecase;
60 break;
61 case MULTICHOICE :
62 if (isset($question->single)) {
63 $newpage->qoption = !$question->single;
64 }
65 break;
66 }
67 $newpage->timecreated = $timenow;
68 if ($question->name != $question->questiontext) {
69 $newpage->title = $question->name;
70 } else {
71 $newpage->title = "Page $count";
72 }
73 $newpage->contents = $question->questiontext;
74
75 // set up page links
76 if ($pageid) {
77 // the new page follows on from this page
78 if (!$page = get_record("lesson_pages", "id", $pageid)) {
79 error ("Format: Page $pageid not found");
80 }
81 $newpage->prevpageid = $pageid;
82 $newpage->nextpageid = $page->nextpageid;
83 // insert the page and reset $pageid
84 if (!$newpageid = insert_record("lesson_pages", $newpage)) {
85 error("Format: Could not insert new page!");
86 }
87 // update the linked list
88 if (!set_field("lesson_pages", "nextpageid", $newpageid, "id", $pageid)) {
89 error("Format: unable to update link");
90 }
91
92 } else {
93 // new page is the first page
94 // get the existing (first) page (if any)
95 if (!$page = get_record_select("lesson_pages", "lessonid = $lesson->id AND prevpageid = 0")) {
96 // there are no existing pages
97 $newpage->prevpageid = 0; // this is a first page
98 $newpage->nextpageid = 0; // this is the only page
99 $newpageid = insert_record("lesson_pages", $newpage);
100 if (!$newpageid) {
101 error("Insert page: new first page not inserted");
102 }
103 } else {
104 // there are existing pages put this at the start
105 $newpage->prevpageid = 0; // this is a first page
106 $newpage->nextpageid = $page->id;
107 $newpageid = insert_record("lesson_pages", $newpage);
108 if (!$newpageid) {
109 error("Insert page: first page not inserted");
110 }
111 // update the linked list
112 if (!set_field("lesson_pages", "prevpageid", $newpageid, "id", $page->id)) {
113 error("Insert page: unable to update link");
114 }
115 }
116 }
117 // reset $pageid and put the page ID in $question, used in save_question_option()
118 $pageid = $newpageid;
119 $question->id = $newpageid;
120
121 $this->questionids[] = $question->id;
122
123 // Now to save all the answers and type-specific options
124
125 $question->lessonid = $lesson->id; // needed for foreign key
126 $result = lesson_save_question_options($question);
127
128 if (!empty($result->error)) {
129 notify($result->error);
130 return false;
131 }
132
133 if (!empty($result->notice)) {
134 notify($result->notice);
135 return true;
136 }
137 break;
138 // the Bad ones
139 default :
140 echo "<p>Unsupported question type ($question->qtype)!</p>";
141 }
142
143 }
144 return true;
145 }
146
147
148 function readdata($filename) {
149 /// Returns complete file with an array, one item per line
150
151 if (is_readable($filename)) {
152 $filearray = file($filename);
153
154 /// Check for Macintosh OS line returns (ie file on one line), and fix
155 if (ereg("\r", $filearray[0]) AND !ereg("\n", $filearray[0])) {
156 return explode("\r", $filearray[0]);
157 } else {
158 return $filearray;
159 }
160 }
161 return false;
162 }
163
164 function readquestions($lines) {
165 /// Parses an array of lines into an array of questions,
166 /// where each item is a question object as defined by
167 /// readquestion(). Questions are defined as anything
168 /// between blank lines.
169
170 $questions = array();
171 $currentquestion = array();
172
173 foreach ($lines as $line) {
174 $line = trim($line);
175 if (empty($line)) {
176 if (!empty($currentquestion)) {
177 if ($question = $this->readquestion($currentquestion)) {
178 $questions[] = $question;
179 }
180 $currentquestion = array();
181 }
182 } else {
183 $currentquestion[] = $line;
184 }
185 }
186
187 if (!empty($currentquestion)) { // There may be a final question
188 if ($question = $this->readquestion($currentquestion)) {
189 $questions[] = $question;
190 }
191 }
192
193 return $questions;
194 }
195
196
197 function readquestion($lines) {
198 /// Given an array of lines known to define a question in
199 /// this format, this function converts it into a question
200 /// object suitable for processing and insertion into Moodle.
201
202 echo "<p>This flash question format has not yet been completed!</p>";
203
204 return NULL;
205 }
206
207
208 function importpostprocess() {
209 /// Does any post-processing that may be desired
210 /// Argument is a simple array of question ids that
211 /// have just been added.
212
213 return true;
214 }
215
216}
217
218?>