Merge branch 'MDL-25708' of git://github.com/stronk7/moodle
[moodle.git] / mod / scorm / datamodels / scorm_13lib.php
1 <?php
3 function scorm_get_toc($user,$scorm,$cmid,$toclink=TOCJSLINK,$currentorg='',$scoid='',$mode='normal',$attempt='',$play=false, $tocheader=false) {
4     global $CFG, $DB, $PAGE, $OUTPUT;
6     $modestr = '';
7     if ($mode == 'browse') {
8         $modestr = '&amp;mode='.$mode;
9     }
11     $result = new stdClass();
12     if ($tocheader) {
13         $result->toc = '<div id="scorm_layout">';
14         $result->toc .= '<div id="scorm_toc">';
15         $result->toc .= '<div id="scorm_tree">';
16     }
17     $result->toc .= '<ul>';
18     $tocmenus = array();
19     $result->prerequisites = true;
20     $incomplete = false;
22     //
23     // Get the current organization infos
24     //
25     if (!empty($currentorg)) {
26         if (($organizationtitle = $DB->get_field('scorm_scoes', 'title', array('scorm'=>$scorm->id,'identifier'=>$currentorg))) != '') {
27             if ($play) {
28             $result->toctitle = "$organizationtitle";
29             }
30             else {
31                 $result->toc .= "\t<li>$organizationtitle</li>\n";
32             }
33             $tocmenus[] = $organizationtitle;
34         }
35     }
36     //
37     // If not specified retrieve the last attempt number
38     //
39     if (empty($attempt)) {
40         $attempt = scorm_get_last_attempt($scorm->id, $user->id);
41     }
42     $result->attemptleft = $scorm->maxattempt - $attempt;
43     if ($scoes = scorm_get_scoes($scorm->id, $currentorg)){
44         //
45         // Retrieve user tracking data for each learning object
46         //
48         $usertracks = array();
49         foreach ($scoes as $sco) {
50             if (!empty($sco->launch)) {
51                 if ($usertrack = scorm_get_tracks($sco->id,$user->id,$attempt)) {
52                     if ($usertrack->status == '') {
53                         $usertrack->status = 'notattempted';
54                     }
55                     $usertracks[$sco->identifier] = $usertrack;
56                 }
57             }
58         }
60         $level=0;
61         $sublist=1;
62         $previd = 0;
63         $nextid = 0;
64         $findnext = false;
65         $parents[$level]='/';
66         foreach ($scoes as $pos => $sco) {
67             $isvisible = false;
68             $sco->title = $sco->title;
69             if (!isset($sco->isvisible) || (isset($sco->isvisible) && ($sco->isvisible == 'true'))) {
70                 $isvisible = true;
71             }
72             if ($parents[$level]!=$sco->parent) {
73                 if ($newlevel = array_search($sco->parent,$parents)) {
74                     for ($i=0; $i<($level-$newlevel); $i++) {
75                         $result->toc .= "\t\t</li></ul></li>\n";
76                     }
77                     $level = $newlevel;
78                 } else {
79                     $i = $level;
80                     $closelist = '';
81                     while (($i > 0) && ($parents[$level] != $sco->parent)) {
82                         $closelist .= "\t\t</li></ul></li>\n";
83                         $i--;
84                     }
85                     if (($i == 0) && ($sco->parent != $currentorg)) {
86                         $result->toc .= "\t\t><ul>\n";
87                         $level++;
88                     } else {
89                         $result->toc .= $closelist;
90                         $level = $i;
91                     }
92                     $parents[$level]=$sco->parent;
93                 }
94             }
95             if ($isvisible) {
96                 $result->toc .= "<li>";
97             }
98             if (isset($scoes[$pos+1])) {
99                 $nextsco = $scoes[$pos+1];
100             } else {
101                 $nextsco = false;
102             }
103             $nextisvisible = false;
104             if (!isset($nextsco->isvisible) || (isset($nextsco->isvisible) && ($nextsco->isvisible == 'true'))) {
105                 $nextisvisible = true;
106             }
107             if ($nextisvisible && ($nextsco !== false) && ($sco->parent != $nextsco->parent) &&
108                (($level==0) || (($level>0) && ($nextsco->parent == $sco->identifier)))) {
109                 $sublist++;
110             }
111             if (empty($sco->title)) {
112                 $sco->title = $sco->identifier;
113             }
114             if (!empty($sco->launch)) {
115                 if ($isvisible) {
116                     $score = '';
117                     if (empty($scoid) && ($mode != 'normal')) {
118                         $scoid = $sco->id;
119                     }
120                     if (isset($usertracks[$sco->identifier])) {
121                         $usertrack = $usertracks[$sco->identifier];
122                         $strstatus = get_string($usertrack->status,'scorm');
123                         if ($sco->scormtype == 'sco') {
124                             $statusicon = '<img src="'.$OUTPUT->pix_url($usertrack->status, 'scorm').'" alt="'.$strstatus.'" title="'.$strstatus.'" />';
125                         } else {
126                             $statusicon = '<img src="'.$OUTPUT->pix_url('assetc', 'scorm').'" alt="'.get_string('assetlaunched','scorm').'" title="'.get_string('assetlaunched','scorm').'" />';
127                         }
129                         if (($usertrack->status == 'notattempted') || ($usertrack->status == 'incomplete') || ($usertrack->status == 'browsed')) {
130                             $incomplete = true;
131                             if ($play && empty($scoid)) {
132                                 $scoid = $sco->id;
133                             }
134                         }
135                         if ($usertrack->score_raw != '' && has_capability('mod/scorm:viewscores', get_context_instance(CONTEXT_MODULE,$cmid))) {
136                             $score = '('.get_string('score','scorm').':&nbsp;'.$usertrack->score_raw.')';
137                         }
138                         $strsuspended = get_string('suspended','scorm');
139                         if ($incomplete && isset($usertrack->{'cmi.exit'}) && ($usertrack->{'cmi.exit'} == 'suspend')) {
140                             $statusicon = '<img src="'.$OUTPUT->pix_url('suspend', 'scorm').'" alt="'.$strstatus.' - '.$strsuspended.'" title="'.$strstatus.' - '.$strsuspended.'" />';
141                         }
142                     } else {
143                         if ($play && empty($scoid)) {
144                             $scoid = $sco->id;
145                         }
146                         if ($sco->scormtype == 'sco') {
147                             $statusicon = '<img src="'.$OUTPUT->pix_url('notattempted', 'scorm').'" alt="'.get_string('notattempted','scorm').'" title="'.get_string('notattempted','scorm').'" />';
148                             $incomplete = true;
149                         } else {
150                             $statusicon = '<img src="'.$OUTPUT->pix_url('asset', 'scorm').'" alt="'.get_string('asset','scorm').'" title="'.get_string('asset','scorm').'" />';
151                         }
152                     }
154                     if ($sco->id == $scoid) {
155                         $findnext = true;
156                     }
158                     if (($nextid == 0) && (scorm_count_launchable($scorm->id,$currentorg) > 1) && ($nextsco!==false) && (!$findnext)) {
159                         if (!empty($sco->launch)) {
160                             $previd = $sco->id;
161                         }
162                     }
163                     require_once($CFG->dirroot.'/mod/scorm/datamodels/sequencinglib.php');
164                     if (scorm_seq_evaluate($sco->id,$usertracks)) {
165                         if ($sco->id == $scoid) {
166                             $result->prerequisites = true;
167                         }
169                         if ($toclink == TOCFULLURL) { //display toc with urls for structure page
170                             $url = $CFG->wwwroot.'/mod/scorm/player.php?a='.$scorm->id.'&amp;currentorg='.$currentorg.$modestr.'&amp;scoid='.$sco->id;
171                             $result->toc .= $statusicon.'&nbsp;<a href="'.$url.'">'.format_string($sco->title).'</a>'.$score."\n";
172                         } else {
173                             if ($sco->launch) {
174                                 $link = 'a='.$scorm->id.'&scoid='.$sco->id.'&currentorg='.$currentorg.$modestr.'&attempt='.$attempt;
175                                 $result->toc .= '<a title="'.$link.'">'.$statusicon.'&nbsp;'.format_string($sco->title).'&nbsp;'.$score.'</a>';
176                             } else {
177                                 $result->toc .= '<span>'.$statusicon.'&nbsp;'.format_string($sco->title).'</span>';
178                             }
179                         }
180                         $tocmenus[$sco->id] = scorm_repeater('&minus;',$level) . '&gt;' . format_string($sco->title);
181                     } else {
182                         if ($sco->id == $scoid) {
183                             $result->prerequisites = false;
184                         }
185                         if ($play) {
186                             // should be disabled
187                             $result->toc .= '<span>'.$statusicon.'&nbsp;'.format_string($sco->title).'</span>';
188                         } else {
189                             $result->toc .= $statusicon.'&nbsp;'.format_string($sco->title)."\n";
190                         }
191                     }
192                     if (($nextsco === false) || $nextsco->parent == $sco->parent) {
193                         $result->toc .= '</li>';
194                     }
195                 }
196             } else {
197                 $result->toc .= '&nbsp;'.format_string($sco->title)."</li>\n";
198             }
199             if (($nextsco !== false) && ($nextid == 0) && ($findnext)) {
200                 if (!empty($nextsco->launch)) {
201                     $nextid = $nextsco->id;
202                 }
203             }
204         }
205         for ($i=0;$i<$level;$i++) {
206             $result->toc .= "\t\t</ul></li>\n";
207         }
209         if ($play) {
210             $sco = $DB->get_record('scorm_scoes', array('id'=>$scoid));
211             $sco->previd = $previd;
212             $sco->nextid = $nextid;
213             $result->sco = $sco;
214             $result->incomplete = $incomplete;
215         } else {
216             $result->incomplete = $incomplete;
217         }
218     }
219     $result->toc .= '</ul>';
222     // NEW IMS TOC
223     if ($tocheader) {
224         $result->toc .= '</div></div></div>';
225         $result->toc .= '<div id="scorm_navpanel"></div>';
226     }
229     if ($scorm->hidetoc == 0) {
230         $PAGE->requires->data_for_js('scormdata', array(
231                 'plusicon' => $OUTPUT->pix_url('plus', 'scorm'),
232                 'minusicon' => $OUTPUT->pix_url('minus', 'scorm')));
233         $PAGE->requires->js('/lib/cookies.js');
234         $PAGE->requires->js('/mod/scorm/datamodels/scorm_datamodels.js');
235     }
237     $url = new moodle_url('/mod/scorm/player.php?a='.$scorm->id.'&currentorg='.$currentorg.$modestr);
238     $result->tocmenu = $OUTPUT->single_select($url, 'scoid', $tocmenus, $sco->id, null, "tocmenu");
240     return $result;