Fixed a problem with AICC tracking
[moodle.git] / mod / scorm / aicc.php
1 <?php
2     require_once('../../config.php');
3     require_once('lib.php');
5     $command = required_param('command', '', PARAM_ALPHA);
6     $sessionid = required_param('session_id', '', PARAM_ALPHANUM);
7     $aiccdata = optional_param('aicc_data', '', PARAM_RAW);
9     require_login();
10     
11     if (!empty($command) && confirm_sesskey($sessionid)) {
12         $command = strtolower($command);
13        
14         if (isset($SESSION->scorm_scoid)) {
15             $scoid = $SESSION->scorm_scoid;
16         } else {
17             error('Invalid script call');
18         }
19         $mode = 'normal';
20         if (isset($SESSION->scorm_mode)) {
21             $mode = $SESSION->scorm_mode;
22         }
23         $status = 'Not Initialized';
24         if (isset($SESSION->scorm_status)) {
25             $status = $SESSION->scorm_status;
26         }
27         if ($sco = get_record('scorm_scoes','id',$scoid)) {
28             if (!$scorm = get_record('scorm','id',$sco->scorm)) {
29                 error('Invalid script call');
30             }
31         } else {
32             error('Invalid script call');
33         }
35         if ($scorm = get_record('scorm','id',$sco->scorm)) {
36             switch ($command) {
37                 case 'getparam':
38                     if ($status == 'Not Initialized') {
39                         $SESSION->scorm_status = 'Running';
40                         $status = 'Running';
41                     }
42                     if ($status != 'Running') {
43                         echo "error = 101\nerror_text = Terminated\n";
44                     } else {
45                         if ($usertrack=scorm_get_tracks($scoid,$USER->id)) {
46                             $userdata = $usertrack;
47                         } else {
48                             $userdata->status = '';
49                             $userdata->score_raw = '';
50                         }
51                         $userdata->student_id = $USER->username;
52                         $userdata->student_name = $USER->lastname .', '. $USER->firstname;
53                         $userdata->mode = $mode;
54                         if ($userdata->mode == 'normal') {
55                             $userdata->credit = 'credit';
56                         } else {
57                             $userdata->credit = 'no-credit';
58                         } 
59                 
60                         if ($sco = get_record('scorm_scoes','id',$scoid)) {
61                             $userdata->course_id = $sco->identifier;
62                             $userdata->datafromlms = $sco->datafromlms;
63                             $userdata->masteryscore = $sco->masteryscore;
64                             $userdata->maxtimeallowed = $sco->maxtimeallowed;
65                             $userdata->timelimitaction = $sco->timelimitaction;
66                                
67                             echo "error = 0\nerror_text = Successful\naicc_data=\n";
68                             echo "[Core]\n";
69                             echo 'Student_ID = '.$userdata->student_id."\n";
70                             echo 'Student_Name = '.$userdata->student_name."\n";
71                             if (isset($userdata->{'cmi.core.lesson_location'})) {
72                                 echo 'Lesson_Location = '.$userdata->{'cmi.core.lesson_location'}."\n";
73                             } else {
74                                 echo 'Lesson_Location = '."\n";
75                             }
76                             echo 'Credit = '.$userdata->credit."\n";
77                             if (isset($userdata->status)) {
78                                 if ($userdata->status == '') {
79                                     $userdata->entry = ', ab-initio';
80                                 } else {
81                                     if (isset($userdata->{'cmi.core.exit'}) && ($userdata->{'cmi.core.exit'} == 'suspend')) {
82                                         $userdata->entry = ', resume';
83                                     } else {
84                                         $userdata->entry = '';
85                                     }
86                                 }
87                             }
88                             if (isset($userdata->{'cmi.core.lesson_status'})) {
89                                 echo 'Lesson_Status = '.$userdata->{'cmi.core.lesson_status'}.$userdata->entry."\n";
90                                 $SESSION->scorm_lessonstatus = $userdata->{'cmi.core.lesson_status'};
91                             } else {
92                                 echo 'Lesson_Status = not attempted'.$userdata->entry."\n";
93                                 $SESSION->scorm_lessonstatus = 'not attempted';
94                             }
95                             if (isset($userdata->{'cmi.core.score.raw'})) {
96                                 $max = '';
97                                 $min = '';
98                                 if (isset($userdata->{'cmi.core.score.max'}) && !empty($userdata->{'cmi.core.score.max'})) {
99                                     $max = ', '.$userdata->{'cmi.core.score.max'};
100                                     if (isset($userdata->{'cmi.core.score.min'}) && !empty($userdata->{'cmi.core.score.min'})) {
101                                         $min = ', '.$userdata->{'cmi.core.score.min'};
102                                     }
103                                 }
104                                 echo 'Score = '.$userdata->{'cmi.core.score.raw'}.$max.$min."\n";
105                             } else {
106                                 echo 'Score = '."\n";
107                             }
108                             if (isset($userdata->{'cmi.core.total_time'})) {
109                                 echo 'Time = '.$userdata->{'cmi.core.total_time'}."\n";
110                             } else {
111                                 echo 'Time = '.'00:00:00'."\n";
112                             }
113                             echo 'Lesson_Mode = '.$userdata->mode."\n";
114                             if (isset($userdata->{'cmi.suspend_data'})) {
115                                 echo "[Core_Lesson]\n".$userdata->{'cmi.suspend_data'}."\n";
116                             } else {
117                                 echo "[Core_Lesson]\n"."\n";
118                             }
119                             echo "[Core_Vendor]\n".$userdata->datafromlms."\n";
120                             echo "[Evaluation]\nCourse_ID = {".$userdata->course_id."}\n";
121                             echo "[Student_Data]\n";
122                             echo 'Mastery_Score = '.$userdata->masteryscore."\n";
123                             echo 'Max_Time_Allowed = '.$userdata->maxtimeallowed."\n";
124                             echo 'Time_Limit_Action = '.$userdata->timelimitaction."\n";
125                         } else {
126                             error('Sco not found');
127                         }
128                     }
129                 break;
130                 case 'putparam':
131                     if ($status == 'Running') {
132                         if (!empty($aiccdata)) {
133                             $initlessonstatus = 'not attempted';
134                             $lessonstatus = 'not attempted';
135                             if (isset($SESSION->scorm_lessonstatus)) {
136                                 $initlessonstatus = $SESSION->scorm_lessonstatus;
137                             }
138                             $score = '';
139                             $datamodel['lesson_location'] = 'cmi.core.lesson_location';
140                             $datamodel['lesson_status'] = 'cmi.core.lesson_status';
141                             $datamodel['score'] = 'cmi.core.score.raw';
142                             $datamodel['time'] = 'cmi.core.session_time';
143                             $datamodel['[core_lesson]'] = 'cmi.suspend_data';
144                             $datamodel['[comments]'] = 'cmi.comments';
145                             $datarows = explode("\n",$aiccdata);
146                             reset($datarows);
147                             while ((list(,$datarow) = each($datarows)) !== false) {
148                                 if (($equal = strpos($datarow, '=')) !== false) {
149                                     $element = strtolower(trim(substr($datarow,0,$equal)));
150                                     $value = trim(substr($datarow,$equal+1));
151                                     if (isset($datamodel[$element])) {
152                                         $element = $datamodel[$element];
153                                         switch ($element) {
154                                             case 'cmi.core.lesson_location':
155                                                 $id = scorm_insert_track($USER->id, $scorm->id, $sco->id, $element, $value);
156                                             break;
157                                             case 'cmi.core.lesson_status':
158                                                 $statuses = array(
159                                                            'passed' => 'passed',
160                                                            'completed' => 'completed',
161                                                            'failed' => 'failed',
162                                                            'incomplete' => 'incomplete',
163                                                            'browsed' => 'browsed',
164                                                            'not attempted' => 'not attempted',
165                                                            'p' => 'passed',
166                                                            'c' => 'completed',
167                                                            'f' => 'failed',
168                                                            'i' => 'incomplete',
169                                                            'b' => 'browsed',
170                                                            'n' => 'not attempted'
171                                                            );
172                                                 $exites = array(
173                                                            'logout' => 'logout',
174                                                            'time-out' => 'time-out',
175                                                            'suspend' => 'suspend',
176                                                            'l' => 'logout',
177                                                            't' => 'time-out',
178                                                            's' => 'suspend',
179                                                            );
180                                                 $values = explode(',',$value);
181                                                 $value = '';
182                                                 if (count($values) > 1) {
183                                                     $value = trim(strtolower($values[1]));
184                                                     if (isset($exites[$value])) {
185                                                         $value = $exites[$value];
186                                                     }
187                                                 }
188                                                 if (empty($value) || isset($exites[$value])) {
189                                                     $subelement = 'cmi.core.exit';
190                                                     $id = scorm_insert_track($USER->id, $scorm->id, $sco->id, $subelement, $value);
191                                                 }
192                                                 $value = trim(strtolower($values[0]));
193                                                 if (isset($statuses[$value]) && ($mode == 'normal')) {
194                                                     $value = $statuses[$value];
195                                                     $id = scorm_insert_track($USER->id, $scorm->id, $sco->id, $element, $value);
196                                                 }
197                                                 $lessonstatus = $value;
198                                             break;
199                                             case 'cmi.core.score.raw':
200                                                  $values = explode(',',$value);
201                                                  if ((count($values) > 1) && ($values[1] >= $values[0]) && is_numeric($values[1])) {
202                                                      $subelement = 'cmi.core.score.max';
203                                                      $value = trim($values[1]);
204                                                      $id = scorm_insert_track($USER->id, $scorm->id, $sco->id, $subelement, $value);
205                                                      if ((count($values) == 3) && ($values[2] <= $values[0]) && is_numeric($values[2])) {
206                                                          $subelement = 'cmi.core.score.min';
207                                                          $value = trim($values[2]);
208                                                          $id = scorm_insert_track($USER->id, $scorm->id, $sco->id, $subelement, $value);
209                                                      }
210                                                  }
211                                               
212                                                  $value = '';
213                                                  if (is_numeric($values[0])) {
214                                                      $value = trim($values[0]);
215                                                      $id = scorm_insert_track($USER->id, $scorm->id, $sco->id, $element, $value);
216                                                  }
217                                                  $score = $value;
218                                             break;
219                                             case 'cmi.core.session_time':
220                                                  $SESSION->scorm_session_time = $value;
221                                             break;
222                                         }
223                                     }
224                                 } else {
225                                     if (isset($datamodel[strtolower(trim($datarow))])) {
226                                         $element = $datamodel[strtolower(trim($datarow))];
227                                         $value = '';
228                                         while ((($datarow = current($datarows)) !== false) && (substr($datarow,0,1) != '[')) {
229                                             $value .= $datarow;
230                                             next($datarows);
231                                         }
232                                         $id = scorm_insert_track($USER->id, $scorm->id, $sco->id, $element, $value);
233                                     }
234                                 }                               
235                             }
236                             if (($mode == 'browse') && ($initlessonstatus == 'not attempted')){
237                                 $lessonstatus = 'browsed';
238                                 $id = scorm_insert_track($USER->id, $scorm->id, $sco->id, 'cmi.core.lesson_status', 'browsed');
239                             }
240                             if ($mode == 'normal') {
241                                 if ($lessonstatus == 'completed') {
242                                     if (!empty($sco->masteryscore) && !empty($score) && ($score >= $sco->masteryscore)) {
243                                         $lessonstatus = 'passed';
244                                     } else {
245                                         $lessonstatus = 'failed';
246                                     }
247                                     $id = scorm_insert_track($USER->id, $scorm->id, $sco->id, 'cmi.core.lesson_status', $lessonstatus);
248                                 }
249                             }                  
250                         }
251                         echo "error = 0\nerror_text = Successful\n";
252                     } else if ($status == 'Terminated') {
253                         echo "error = 1\nerror_text = Terminated\n";
254                     } else {
255                         echo "error = 1\nerror_text = Not Initialized\n";
256                     }
257                 break;
258                 case 'putcomments':
259                     if ($status == 'Running') {
260                         echo "error = 0\nerror_text = Successful\n";
261                     } else if ($status == 'Terminated') {
262                         echo "error = 1\nerror_text = Terminated\n";
263                     } else {
264                         echo "error = 1\nerror_text = Not Initialized\n";
265                     }
266                 break;
267                 case 'putinteractions':
268                     if ($status == 'Running') {
269                         echo "error = 0\nerror_text = Successful\n";
270                     } else if ($status == 'Terminated') {
271                         echo "error = 1\nerror_text = Terminated\n";
272                     } else {
273                         echo "error = 1\nerror_text = Not Initialized\n";
274                     }
275                 break;
276                 case 'putobjectives':
277                     if ($status == 'Running') {
278                         echo "error = 0\nerror_text = Successful\n";
279                     } else if ($status == 'Terminated') {
280                         echo "error = 1\nerror_text = Terminated\n";
281                     } else {
282                         echo "error = 1\nerror_text = Not Initialized\n";
283                     }
284                 break;
285                 case 'putpath':
286                     if ($status == 'Running') {
287                         echo "error = 0\nerror_text = Successful\n";
288                     } else if ($status == 'Terminated') {
289                         echo "error = 1\nerror_text = Terminated\n";
290                     } else {
291                         echo "error = 1\nerror_text = Not Initialized\n";
292                     }
293                 break;
294                 case 'putperformance':
295                     if ($status == 'Running') {
296                         echo "error = 0\nerror_text = Successful\n";
297                     } else if ($status == 'Terminated') {
298                         echo "error = 1\nerror_text = Terminated\n";
299                     } else {
300                         echo "error = 1\nerror_text = Not Initialized\n";
301                     }
302                 break;
303                 case 'exitau':
304                     if ($status == 'Running') {
305                         if (isset($SESSION->scorm_session_time) && ($SESSION->scorm_session_time != '')) {
306                             if ($track = get_record_select('scorm_scoes_track',"userid='$USER->id' AND scormid='$scorm->id' AND scoid='$sco->id' AND element='cmi.core.total_time'")) {
307                                 // Add session_time to total_time
308                                 $value = scorm_add_time($track->value, $SESSION->scorm_session_time);
309                                 $track->value = $value;
310                                 $track->timemodified = time();
311                                 $id = update_record('scorm_scoes_track',$track);
312                             } else {
313                                 $track->userid = $USER->id;
314                                 $track->scormid = $scorm->id;
315                                 $track->scoid = $sco->id;
316                                 $track->element = 'cmi.core.total_time';
317                                 $track->value = $SESSION->scorm_session_time;
318                                 $track->timemodified = time();
319                                 $id = insert_record('scorm_scoes_track',$track);
320                             }
321                         }
322                         
323                         $SESSION->scorm_status = 'Terminated';
324                         $SESSION->scorm_session_time = '';
325                         echo "error = 0\nerror_text = Successful\n";
326                     } else if ($status == 'Terminated') {
327                         echo "error = 1\nerror_text = Terminated\n";
328                     } else {
329                         echo "error = 1\nerror_text = Not Initialized\n";
330                     }
331                 break;
332                 default:
333                     echo "error = 1\nerror_text = Invalid Command\n";
334                 break;
335             }
336         }
337     } else {
338         if (empty($command)) {
339             echo "error = 1\nerror_text = Invalid Command\n";
340         } else {
341             echo "error = 3\nerror_text = Invalid Session ID\n";
342         }
343     }
344 ?>