small bug fix: $USER was not laoded in course admin block
[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.
41
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
112 global $CFG;
113
114 $return->grades = NULL;
115 if ($sco_users=get_records_select("scorm_sco_users", "scormid='$scormid' GROUP BY userid")) {
116 foreach ($sco_users as $sco_user) {
117 $user_data=get_records_select("scorm_sco_users","scormid='$scormid' AND userid='$sco_user->userid'");
118 $scores->completed=0;
119 $scores->browsed=0;
120 $scores->incomplete=0;
121 $scores->failed=0;
122 $scores->notattempted=0;
123 $result="";
124 $data = current($user_data);
125 foreach ($user_data as $data) {
126 if ($data->cmi_core_lesson_status=="passed")
127 $scores->completed++;
128 else
129 $scores->{scorm_remove_spaces($data->cmi_core_lesson_status)}++;
130
131 }
132 if ($scores->completed)
133 $result.="<img src=\"$CFG->wwwroot/mod/scorm/pix/completed.gif\" alt=\"".get_string("completed","scorm")."\" title=\"".get_string("completed","scorm")."\"> $scores->completed ";
134 if ($scores->incomplete)
135 $result.="<img src=\"$CFG->wwwroot/mod/scorm/pix/incomplete.gif\" alt=\"".get_string("incomplete","scorm")."\" title=\"".get_string("incomplete","scorm")."\"> $scores->incomplete ";
136 if ($scores->failed)
137 $result.="<img src=\"$CFG->wwwroot/mod/scorm/pix/failed.gif\" alt=\"".get_string("failed","scorm")."\" title=\"".get_string("failed","scorm")."\"> $scores->failed ";
138 if ($scores->browsed)
139 $result.="<img src=\"$CFG->wwwroot/mod/scorm/pix/browsed.gif\" alt=\"".get_string("browsed","scorm")."\" title=\"".get_string("browsed","scorm")."\"> $scores->browsed ";
140 if ($scores->notattempted)
141 $result.="<img src=\"$CFG->wwwroot/mod/scorm/pix/notattempted.gif\" alt=\"".get_string("notattempted","scorm")."\" title=\"".get_string("notattempted","scorm")."\"> $scores->notattempted ";
142
143 $return->grades[$sco_user->userid]=$result;
144 }
145
146 }
147
148 $return->maxgrade = count_records_select("scorm_scoes","scorm='$scormid' AND launch<>''");
149
150 return $return;
151}
152
153
154//////////////////////////////////////////////////////////////////////////////////////
155/// Any other scorm functions go here. Each of them must have a name that
156/// starts with scorm_
157
158
159function scorm_randstring($len = "8")
160{
161 $rstring = NULL;
162 for($i=0; $i<$len; $i++) {
163 $char = chr(rand(48,122));
164 while (!ereg("[a-zA-Z0-9]", $char)){
165 if($char == $lchar) continue;
166 $char = chr(rand(48,90));
167 }
168 $rstring .= $char;
169 $lchar = $char;
170 }
171 return $rstring;
172}
173
98ca59f6 174
175function scorm_datadir($strPath, $existingdir="", $prefix = "SCORM")
176{
e23ef951 177 global $CFG;
178
98ca59f6 179 if (($existingdir!="") && (is_dir($strPath.$existingdir)))
180 return $strPath.$existingdir;
181
182 if (is_dir($strPath)) {
183 do {
184 $datadir="/".$prefix.scorm_randstring();
185 } while (file_exists($strPath.$datadir));
c5163bfd 186 mkdir($strPath.$datadir, $CFG->directorypermissions);
e23ef951 187 @chmod($strPath.$datadir, $CFG->directorypermissions); // Just in case mkdir didn't do it
98ca59f6 188 return $strPath.$datadir;
189 } else {
190 return false;
191 }
192}
193
194function scorm_validate($manifest)
195{
196 if (is_file ($manifest)) {
197 if (file_exists($manifest))
198 {
199 return "regular";
200 }
201 } else {
202 return "nomanifest";
203 }
204}
205
206function scorm_delete_files($directory)
207{
208 if (is_dir($directory))
209 {
210 $handle=opendir($directory);
211 while (($file = readdir($handle)) != '')
212 {
213 if ($file != "." && $file != "..")
214 {
215 if (!is_dir($directory."/".$file))
216 unlink($directory."/".$file);
217 else
218 scorm_delete_files($directory."/".$file);
219 }
220 }
221 rmdir($directory);
222 }
223}
224
225function scorm_startElement($parser, $name, $attrs) {
226 global $manifest,$i,$resources,$parent,$level;
227 if ($name == "ITEM") {
228 $i++;
229 $manifest[$i]["identifier"] = $attrs["IDENTIFIER"];
5d8790cb 230 if (empty($attrs["IDENTIFIERREF"]))
231 $attrs["IDENTIFIERREF"] = "";
98ca59f6 232 $manifest[$i]["identifierref"] = $attrs["IDENTIFIERREF"];
5d8790cb 233 if (empty($attrs["ISVISIBLE"]))
234 $attrs["ISVISIBLE"] = "";
98ca59f6 235 $manifest[$i]["isvisible"] = $attrs["ISVISIBLE"];
236 $manifest[$i]["parent"] = $parent[$level];
237 $level++;
238 $parent[$level] = $attrs["IDENTIFIER"];
239 }
240 if ($name == "RESOURCE") {
241 $resources[$attrs["IDENTIFIER"]]["href"]=$attrs["HREF"];
242 $resources[$attrs["IDENTIFIER"]]["type"]=$attrs["ADLCP:SCORMTYPE"];
243 }
244}
245
246function scorm_endElement($parser, $name) {
247 global $manifest,$i,$level,$datacontent,$navigation;
248 if ($name == "ITEM") {
249 $level--;
250 }
251 if ($name == "TITLE" && $level>0)
5d8790cb 252 $manifest[$i]["title"] = $datacontent;
253 if ($name == "ADLCP:HIDERTSUI")
254 $manifest[$i][$datacontent] = 1;
98ca59f6 255}
256
257function scorm_characterData($parser, $data) {
258 global $datacontent;
259 $datacontent = $data;
260}
261
262function scorm_parse($basedir,$file,$scorm_id) {
263 global $manifest,$i,$resources,$parent,$level;
264 $datacontent = "";
265 $manifest[][] = "";
266 $resources[] = "";
267 $i = 0;
268 $level = 0;
269 $parent[$level] = "/";
270
271 $xml_parser = xml_parser_create();
272 // use case-folding so we are sure to find the tag in $map_array
273 xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true);
274 xml_set_element_handler($xml_parser, "scorm_startElement", "scorm_endElement");
275 xml_set_character_data_handler($xml_parser, "scorm_characterData");
276 if (!($fp = fopen($basedir.$file, "r"))) {
277 die("could not open XML input");
278 }
279
280 while ($data = fread($fp, 4096)) {
281 if (!xml_parse($xml_parser, $data, feof($fp))) {
282 die(sprintf("XML error: %s at line %d",
283 xml_error_string(xml_get_error_code($xml_parser)),
284 xml_get_current_line_number($xml_parser)));
285 }
286 }
287 xml_parser_free($xml_parser);
288 $launch = 0;
289
290 $sco->scorm = $scorm_id;
291 delete_records("scorm_scoes","scorm",$scorm_id);
292 delete_records("scorm_sco_users","scormid",$scorm_id);
293 for ($j=1; $j<=$i; $j++) {
294 $sco->identifier = $manifest[$j]["identifier"];
295 $sco->parent = $manifest[$j]["parent"];
296 $sco->title = $manifest[$j]["title"];
5d8790cb 297 if (empty($resources[($manifest[$j]["identifierref"])]["href"]))
298 $resources[($manifest[$j]["identifierref"])]["href"] = "";
299 $sco->launch = $resources[($manifest[$j]["identifierref"])]["href"];
300 if (empty($resources[($manifest[$j]["identifierref"])]["type"]))
301 $resources[($manifest[$j]["identifierref"])]["type"] = "";
302 $sco->type = $resources[($manifest[$j]["identifierref"])]["type"];
303 if (empty($manifest[$j]["previous"]))
304 $manifest[$j]["previous"] = 0;
305 $sco->previous = $manifest[$j]["previous"];
306 if (empty($manifest[$j]["continue"]))
307 $manifest[$j]["continue"] = 0;
308 $sco->next = $manifest[$j]["continue"];
309 if (scorm_remove_spaces($manifest[$j]["isvisible"]) != "false")
310 $id = insert_record("scorm_scoes",$sco);
311 if ($launch==0 && $sco->launch)
312 $launch = $id;
98ca59f6 313 }
314 return $launch;
315}
316
317function scorm_get_scoes_records($sco_user) {
318/// Gets all info required to display the table of scorm results
319/// for report.php
320 global $CFG;
321
322 return get_records_sql("SELECT su.*, u.firstname, u.lastname, u.picture
323 FROM {$CFG->prefix}scorm_sco_users su,
324 {$CFG->prefix}user u
325 WHERE su.scormid = '$sco_user->scormid'
326 AND su.userid = u.id
327 AND su.userid = $sco_user->userid
328 ORDER BY scoid");
329}
330
331function scorm_remove_spaces($sourcestr) {
332// Remove blank space from a string
333 $newstr="";
334 for( $i=0; $i<strlen($sourcestr); $i++) {
335 if ($sourcestr[$i]!=' ')
336 $newstr .=$sourcestr[$i];
337 }
338 return $newstr;
339}
340
341function scorm_string_round($stringa) {
342// Crop a string to $len character and set an anchor title to the full string
343 $len=11;
344 if ( strlen($stringa)>$len ) {
345 return "<A name=\"\" title=\"$stringa\">".substr($stringa,0,$len-4)."...".substr($stringa,strlen($stringa)-1,1)."</A>";
346 } else
347 return $stringa;
348}
349
350function scorm_external_link($link) {
351// check if a link is external
352 $result = false;
353 $link = strtolower($link);
354 if (substr($link,0,7) == "http://")
355 $result = true;
356 else if (substr($link,0,8) == "https://")
357 $result = true;
358 else if (substr($link,0,4) == "www.")
359 $result = true;
5d8790cb 360 /*else if (substr($link,0,7) == "rstp://")
98ca59f6 361 $result = true;
362 else if (substr($link,0,6) == "rtp://")
363 $result = true;
364 else if (substr($link,0,6) == "ftp://")
365 $result = true;
366 else if (substr($link,0,9) == "gopher://")
5d8790cb 367 $result = true; */
98ca59f6 368 return $result;
369}
370?>