update for moodle 1.3.1
[moodle.git] / mod / scorm / lib.php
CommitLineData
98ca59f6 1<?PHP // $Id$
2
3/// Library of functions and constants for module scorm
4/// (replace scorm with the name of your module and delete this line)
5
6
c5163bfd 7$SCORM_FRAME_SIZE = 140;
98ca59f6 8
9function scorm_add_instance($scorm) {
10/// Given an object containing all the necessary data,
11/// (defined by the form in mod.html) this function
12/// will create a new instance and return the id number
13/// of the new instance.
14
15 $scorm->timemodified = time();
16
17 # May have to add extra stuff in here #
18
19 return insert_record("scorm", $scorm);
20}
21
22
23function scorm_update_instance($scorm) {
24/// Given an object containing all the necessary data,
25/// (defined by the form in mod.html) this function
26/// will update an existing instance with new data.
27
28 $scorm->timemodified = time();
29 $scorm->id = $scorm->instance;
30
31 # May have to add extra stuff in here #
32
33 return update_record("scorm", $scorm);
34}
35
36
37function scorm_delete_instance($id) {
38/// Given an ID of an instance of this module,
39/// this function will permanently delete the instance
40/// and any data that depends on it.
4a9df373 41
98ca59f6 42 require('../config.php');
43
44 if (! $scorm = get_record("scorm", "id", "$id")) {
45 return false;
46 }
47
48 $result = true;
49
50 # Delete any dependent files #
51 scorm_delete_files($CFG->dataroot."/".$scorm->course."/moddata/scorm".$scorm->datadir);
52
53 # Delete any dependent records here #
54 if (! delete_records("scorm_sco_users", "scormid", "$scorm->id")) {
55 $result = false;
56 }
57 if (! delete_records("scorm_scoes", "scorm", "$scorm->id")) {
58 $result = false;
59 }
60 if (! delete_records("scorm", "id", "$scorm->id")) {
61 $result = false;
62 }
63
64
65 return $result;
66}
67
68function scorm_user_outline($course, $user, $mod, $scorm) {
69/// Return a small object with summary information about what a
70/// user has done with a given particular instance of this module
71/// Used for user activity reports.
72/// $return->time = the time they did it
73/// $return->info = a short text description
74
75 return $return;
76}
77
78function scorm_user_complete($course, $user, $mod, $scorm) {
79/// Print a detailed representation of what a user has done with
80/// a given particular instance of this module, for user activity reports.
81
82 return true;
83}
84
85function scorm_print_recent_activity(&$logs, $isteacher=false) {
86/// Given a list of logs, assumed to be those since the last login
87/// this function prints a short list of changes related to this module
88/// If isteacher is true then perhaps additional information is printed.
89/// This function is called from course/lib.php: print_recent_activity()
90
91 global $CFG, $COURSE_TEACHER_COLOR;
92
e1e108d4 93 $content = NULL;
94
98ca59f6 95 return $content; // True if anything was printed, otherwise false
96}
97
98function scorm_cron () {
99/// Function to be run periodically according to the moodle cron
100/// This function searches for things that need to be done, such
101/// as sending out mail, toggling flags etc ...
102
103 global $CFG;
104
105 return true;
106}
107
108function scorm_grades($scormid) {
109/// Must return an array of grades for a given instance of this module,
110/// indexed by user. It also returns a maximum allowed grade.
111
4a9df373 112 global $CFG;
113
114 if (!$return->maxgrade = count_records_select("scorm_scoes","scorm='$scormid' AND launch<>''")) {
115 return NULL;
116 }
117
98ca59f6 118 $return->grades = NULL;
119 if ($sco_users=get_records_select("scorm_sco_users", "scormid='$scormid' GROUP BY userid")) {
120 foreach ($sco_users as $sco_user) {
4a9df373 121 $user_data=get_records_select("scorm_sco_users","scormid='$scormid' AND userid='$sco_user->userid'");
122 $scores->completed=0;
123 $scores->browsed=0;
124 $scores->incomplete=0;
125 $scores->failed=0;
126 $scores->notattempted=0;
127 $result="";
128 $data = current($user_data);
129 foreach ($user_data as $data) {
130 if ($data->cmi_core_lesson_status=="passed")
131 $scores->completed++;
132 else
133 $scores->{scorm_remove_spaces($data->cmi_core_lesson_status)}++;
134
135 }
136 if ($scores->completed)
137 $result.="<img src=\"$CFG->wwwroot/mod/scorm/pix/completed.gif\" alt=\"".get_string("completed","scorm")."\" title=\"".get_string("completed","scorm")."\"> $scores->completed ";
138 if ($scores->incomplete)
139 $result.="<img src=\"$CFG->wwwroot/mod/scorm/pix/incomplete.gif\" alt=\"".get_string("incomplete","scorm")."\" title=\"".get_string("incomplete","scorm")."\"> $scores->incomplete ";
140 if ($scores->failed)
141 $result.="<img src=\"$CFG->wwwroot/mod/scorm/pix/failed.gif\" alt=\"".get_string("failed","scorm")."\" title=\"".get_string("failed","scorm")."\"> $scores->failed ";
142 if ($scores->browsed)
143 $result.="<img src=\"$CFG->wwwroot/mod/scorm/pix/browsed.gif\" alt=\"".get_string("browsed","scorm")."\" title=\"".get_string("browsed","scorm")."\"> $scores->browsed ";
144 if ($scores->notattempted)
145 $result.="<img src=\"$CFG->wwwroot/mod/scorm/pix/notattempted.gif\" alt=\"".get_string("notattempted","scorm")."\" title=\"".get_string("notattempted","scorm")."\"> $scores->notattempted ";
146
147 $return->grades[$sco_user->userid]=$result;
98ca59f6 148 }
149
150 }
98ca59f6 151
152 return $return;
153}
154
155
156//////////////////////////////////////////////////////////////////////////////////////
157/// Any other scorm functions go here. Each of them must have a name that
158/// starts with scorm_
159
160
161function scorm_randstring($len = "8")
162{
163 $rstring = NULL;
164 for($i=0; $i<$len; $i++) {
165 $char = chr(rand(48,122));
166 while (!ereg("[a-zA-Z0-9]", $char)){
167 if($char == $lchar) continue;
168 $char = chr(rand(48,90));
169 }
170 $rstring .= $char;
171 $lchar = $char;
172 }
173 return $rstring;
174}
175
98ca59f6 176
177function scorm_datadir($strPath, $existingdir="", $prefix = "SCORM")
178{
e23ef951 179 global $CFG;
180
4a9df373 181 if (($existingdir!="") && (is_dir($strPath.$existingdir)))
182 return $strPath.$existingdir;
183
184 if (is_dir($strPath)) {
185 do {
186 $datadir="/".$prefix.scorm_randstring();
187 } while (file_exists($strPath.$datadir));
188 mkdir($strPath.$datadir, $CFG->directorypermissions);
e23ef951 189 @chmod($strPath.$datadir, $CFG->directorypermissions); // Just in case mkdir didn't do it
4a9df373 190 return $strPath.$datadir;
191 } else {
192 return false;
193 }
98ca59f6 194}
195
196function scorm_validate($manifest)
197{
198 if (is_file ($manifest)) {
4a9df373 199 if (file_exists($manifest))
200 {
201 return "regular";
202 }
98ca59f6 203 } else {
4a9df373 204 return "nomanifest";
98ca59f6 205 }
206}
207
208function scorm_delete_files($directory)
209{
210 if (is_dir($directory))
211 {
212 $handle=opendir($directory);
213 while (($file = readdir($handle)) != '')
214 {
215 if ($file != "." && $file != "..")
4a9df373 216 {
217 if (!is_dir($directory."/".$file))
98ca59f6 218 unlink($directory."/".$file);
4a9df373 219 else
220 scorm_delete_files($directory."/".$file);
221 }
98ca59f6 222 }
223 rmdir($directory);
224 }
225}
226
227function scorm_startElement($parser, $name, $attrs) {
228 global $manifest,$i,$resources,$parent,$level;
229 if ($name == "ITEM") {
4a9df373 230 $i++;
231 $manifest[$i]["identifier"] = $attrs["IDENTIFIER"];
232 if (empty($attrs["IDENTIFIERREF"]))
233 $attrs["IDENTIFIERREF"] = "";
234 $manifest[$i]["identifierref"] = $attrs["IDENTIFIERREF"];
235 if (empty($attrs["ISVISIBLE"]))
236 $attrs["ISVISIBLE"] = "";
237 $manifest[$i]["isvisible"] = $attrs["ISVISIBLE"];
238 $manifest[$i]["parent"] = $parent[$level];
239 $level++;
240 $parent[$level] = $attrs["IDENTIFIER"];
98ca59f6 241 }
242 if ($name == "RESOURCE") {
4a9df373 243 $resources[$attrs["IDENTIFIER"]]["href"]=$attrs["HREF"];
244 $resources[$attrs["IDENTIFIER"]]["type"]=$attrs["ADLCP:SCORMTYPE"];
98ca59f6 245 }
246}
247
248function scorm_endElement($parser, $name) {
249 global $manifest,$i,$level,$datacontent,$navigation;
250 if ($name == "ITEM") {
251 $level--;
252 }
253 if ($name == "TITLE" && $level>0)
4a9df373 254 $manifest[$i]["title"] = $datacontent;
5d8790cb 255 if ($name == "ADLCP:HIDERTSUI")
4a9df373 256 $manifest[$i][$datacontent] = 1;
98ca59f6 257}
258
259function scorm_characterData($parser, $data) {
260 global $datacontent;
261 $datacontent = $data;
262}
263
264function scorm_parse($basedir,$file,$scorm_id) {
265 global $manifest,$i,$resources,$parent,$level;
266 $datacontent = "";
267 $manifest[][] = "";
268 $resources[] = "";
269 $i = 0;
270 $level = 0;
271 $parent[$level] = "/";
272
273 $xml_parser = xml_parser_create();
274 // use case-folding so we are sure to find the tag in $map_array
275 xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true);
276 xml_set_element_handler($xml_parser, "scorm_startElement", "scorm_endElement");
277 xml_set_character_data_handler($xml_parser, "scorm_characterData");
278 if (!($fp = fopen($basedir.$file, "r"))) {
279 die("could not open XML input");
280 }
281
282 while ($data = fread($fp, 4096)) {
4a9df373 283 if (!xml_parse($xml_parser, $data, feof($fp))) {
98ca59f6 284 die(sprintf("XML error: %s at line %d",
285 xml_error_string(xml_get_error_code($xml_parser)),
286 xml_get_current_line_number($xml_parser)));
287 }
288 }
289 xml_parser_free($xml_parser);
290 $launch = 0;
291
292 $sco->scorm = $scorm_id;
293 delete_records("scorm_scoes","scorm",$scorm_id);
294 delete_records("scorm_sco_users","scormid",$scorm_id);
295 for ($j=1; $j<=$i; $j++) {
296 $sco->identifier = $manifest[$j]["identifier"];
297 $sco->parent = $manifest[$j]["parent"];
298 $sco->title = $manifest[$j]["title"];
5d8790cb 299 if (empty($resources[($manifest[$j]["identifierref"])]["href"]))
300 $resources[($manifest[$j]["identifierref"])]["href"] = "";
301 $sco->launch = $resources[($manifest[$j]["identifierref"])]["href"];
302 if (empty($resources[($manifest[$j]["identifierref"])]["type"]))
303 $resources[($manifest[$j]["identifierref"])]["type"] = "";
4a9df373 304 $sco->type = $resources[($manifest[$j]["identifierref"])]["type"];
305 if (empty($manifest[$j]["previous"]))
306 $manifest[$j]["previous"] = 0;
307 $sco->previous = $manifest[$j]["previous"];
308 if (empty($manifest[$j]["continue"]))
309 $manifest[$j]["continue"] = 0;
310 $sco->next = $manifest[$j]["continue"];
311 if (scorm_remove_spaces($manifest[$j]["isvisible"]) != "false")
312 $id = insert_record("scorm_scoes",$sco);
313 if ($launch==0 && $sco->launch)
314 $launch = $id;
98ca59f6 315 }
316 return $launch;
317}
318
319function scorm_get_scoes_records($sco_user) {
320/// Gets all info required to display the table of scorm results
321/// for report.php
322 global $CFG;
323
324 return get_records_sql("SELECT su.*, u.firstname, u.lastname, u.picture
325 FROM {$CFG->prefix}scorm_sco_users su,
326 {$CFG->prefix}user u
327 WHERE su.scormid = '$sco_user->scormid'
328 AND su.userid = u.id
329 AND su.userid = $sco_user->userid
330 ORDER BY scoid");
331}
332
333function scorm_remove_spaces($sourcestr) {
334// Remove blank space from a string
335 $newstr="";
4a9df373 336 for( $i=0; $i<strlen($sourcestr); $i++) {
337 if ($sourcestr[$i]!=' ')
338 $newstr .=$sourcestr[$i];
339 }
340 return $newstr;
98ca59f6 341}
342
343function scorm_string_round($stringa) {
344// Crop a string to $len character and set an anchor title to the full string
345 $len=11;
346 if ( strlen($stringa)>$len ) {
4a9df373 347 return "<A name=\"\" title=\"$stringa\">".substr($stringa,0,$len-4)."...".substr($stringa,strlen($stringa)-1,1)."</A>";
98ca59f6 348 } else
4a9df373 349 return $stringa;
98ca59f6 350}
351
352function scorm_external_link($link) {
353// check if a link is external
354 $result = false;
355 $link = strtolower($link);
356 if (substr($link,0,7) == "http://")
4a9df373 357 $result = true;
98ca59f6 358 else if (substr($link,0,8) == "https://")
4a9df373 359 $result = true;
98ca59f6 360 else if (substr($link,0,4) == "www.")
4a9df373 361 $result = true;
5d8790cb 362 /*else if (substr($link,0,7) == "rstp://")
4a9df373 363 $result = true;
98ca59f6 364 else if (substr($link,0,6) == "rtp://")
4a9df373 365 $result = true;
98ca59f6 366 else if (substr($link,0,6) == "ftp://")
4a9df373 367 $result = true;
98ca59f6 368 else if (substr($link,0,9) == "gopher://")
4a9df373 369 $result = true; */
98ca59f6 370 return $result;
371}
372?>