SCORM MDL-22951 New player for SCORM fixes major regression that prevents some SCORM...
[moodle.git] / mod / scorm / datamodels / scorm_13lib.php
1 <?php
3 function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='normal',$attempt='',$play=false) {
4     global $CFG, $DB, $PAGE, $OUTPUT;
6     $strexpand = get_string('expcoll','scorm');
7     $modestr = '';
8     if ($mode == 'browse') {
9         $modestr = '&amp;mode='.$mode;
10     }
12     $result = new stdClass();
13     $result->toc = '<div id="scorm_layout">';
14     $result->toc .= '<div id="scorm_toc">';
15     $result->toc .= '<div id="scorm_tree"><ul>';
16     $tocmenus = array();
17     $result->prerequisites = true;
18     $incomplete = false;
20     //
21     // Get the current organization infos
22     //
23     if (!empty($currentorg)) {
24         if (($organizationtitle = $DB->get_field('scorm_scoes', 'title', array('scorm'=>$scorm->id,'identifier'=>$currentorg))) != '') {
25             if ($play) {
26             $result->toctitle = "$organizationtitle";
27             }
28             else {
29                 $result->toc .= "\t<li>$organizationtitle</li>\n";
30             }
31             $tocmenus[] = $organizationtitle;
32         }
33     }
34     //
35     // If not specified retrieve the last attempt number
36     //
37     if (empty($attempt)) {
38         $attempt = scorm_get_last_attempt($scorm->id, $user->id);
39     }
40     $result->attemptleft = $scorm->maxattempt - $attempt;
41     if ($scoes = scorm_get_scoes($scorm->id, $currentorg)){
42         //
43         // Retrieve user tracking data for each learning object
44         //
46         $usertracks = array();
47         foreach ($scoes as $sco) {
48             if (!empty($sco->launch)) {
49                 if ($usertrack = scorm_get_tracks($sco->id,$user->id,$attempt)) {
50                     if ($usertrack->status == '') {
51                         $usertrack->status = 'notattempted';
52                     }
53                     $usertracks[$sco->identifier] = $usertrack;
54                 }
55             }
56         }
58         $level=0;
59         $sublist=1;
60         $previd = 0;
61         $nextid = 0;
62         $findnext = false;
63         $parents[$level]='/';
64         foreach ($scoes as $pos => $sco) {
65             $isvisible = false;
66             $sco->title = $sco->title;
67             if (!isset($sco->isvisible) || (isset($sco->isvisible) && ($sco->isvisible == 'true'))) {
68                 $isvisible = true;
69             }
70             if ($parents[$level]!=$sco->parent) {
71                 if ($newlevel = array_search($sco->parent,$parents)) {
72                     for ($i=0; $i<($level-$newlevel); $i++) {
73                         $result->toc .= "\t\t</ul></li>\n";
74                     }
75                     $level = $newlevel;
76                 } else {
77                     $i = $level;
78                     $closelist = '';
79                     while (($i > 0) && ($parents[$level] != $sco->parent)) {
80                         $closelist .= "\t\t</ul></li>\n";
81                         $i--;
82                     }
83                     if (($i == 0) && ($sco->parent != $currentorg)) {
84                         $style = '';
85                         if (isset($_COOKIE['hide:SCORMitem'.$sco->id])) {
86                             $style = ' style="display: none;"';
87                         }
88                         //$result->toc .= "\t\t<li><ul id='s$sublist' class='$liststyle'$style>\n";
89                         $result->toc .= "\t\t><ul>\n";
90                         $level++;
91                     } else {
92                         $result->toc .= $closelist;
93                         $level = $i;
94                     }
95                     $parents[$level]=$sco->parent;
96                 }
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                 $icon = 'minus';
111                 if (isset($_COOKIE['hide:SCORMitem'.$nextsco->id])) {
112                     $icon = 'plus';
113                 }
114 //                $result->toc .= "\t\t".'<li><a href="javascript:expandCollide(\'img'.$sublist.'\',\'s'.$sublist.'\','.$nextsco->id.');">'.
115 //                                '<img id="img'.$sublist.'" src="'.$OUTPUT->pix_url($icon, 'scorm').'" alt="'.$strexpand.'" title="'.$strexpand.'"/></a>';
116             } else if ($isvisible) {
117 //                $result->toc .= "\t\t".'<li><img src="'.$OUTPUT->pix_url('spacer', 'scorm').'" alt="" />';
118             }
119             if (empty($sco->title)) {
120                 $sco->title = $sco->identifier;
121             }
122             if (!empty($sco->launch)) {
123                 if ($isvisible) {
124                     $startbold = '';
125                     $endbold = '';
126                     $score = '';
127                     if (empty($scoid) && ($mode != 'normal')) {
128                         $scoid = $sco->id;
129                     }
130                     if (isset($usertracks[$sco->identifier])) {
131                         $usertrack = $usertracks[$sco->identifier];
132                         $strstatus = get_string($usertrack->status,'scorm');
133                         if ($sco->scormtype == 'sco') {
134                             $statusicon = '<img src="'.$OUTPUT->pix_url($usertrack->status, 'scorm').'" alt="'.$strstatus.'" title="'.$strstatus.'" />';
135                         } else {
136                             $statusicon = '<img src="'.$OUTPUT->pix_url('assetc', 'scorm').'" alt="'.get_string('assetlaunched','scorm').'" title="'.get_string('assetlaunched','scorm').'" />';
137                         }
139                         if (($usertrack->status == 'notattempted') || ($usertrack->status == 'incomplete') || ($usertrack->status == 'browsed')) {
140                             $incomplete = true;
141                             if ($play && empty($scoid)) {
142                                 $scoid = $sco->id;
143                             }
144                         }
145                         if ($usertrack->score_raw != '') {
146                             $score = '('.get_string('score','scorm').':&nbsp;'.$usertrack->score_raw.')';
147                         }
148                         $strsuspended = get_string('suspended','scorm');
149                         if (isset($usertrack->{'cmi.core.exit'}) && ($usertrack->{'cmi.core.exit'} == 'suspend')) {
150                             if($usertrack->status !='completed') {
151                                 $statusicon = '<img src="'.$OUTPUT->pix_url('suspend', 'scorm').'" alt="'.$strstatus.' - '.$strsuspended.'" title="'.$strstatus.' - '.$strsuspended.'" />';
152                             }
153                         }
154                     } else {
155                         if ($play && empty($scoid)) {
156                             $scoid = $sco->id;
157                         }
158                         if ($sco->scormtype == 'sco') {
159                             $statusicon = '<img src="'.$OUTPUT->pix_url('notattempted', 'scorm').'" alt="'.get_string('notattempted','scorm').'" title="'.get_string('notattempted','scorm').'" />';
160                             $incomplete = true;
161                         } else {
162                             $statusicon = '<img src="'.$OUTPUT->pix_url('asset', 'scorm').'" alt="'.get_string('asset','scorm').'" title="'.get_string('asset','scorm').'" />';
163                         }
164                     }
166                     if ($sco->id == $scoid) {
167                         $startbold = '<b>';
168                         $endbold = '</b>';
169                         $findnext = true;
170                         $shownext = isset($sco->next) ? $sco->next : 0;
171                         $showprev = isset($sco->prev) ? $sco->prev : 0;
172                     }
174                     if (($nextid == 0) && (scorm_count_launchable($scorm->id,$currentorg) > 1) && ($nextsco!==false) && (!$findnext)) {
175                         if (!empty($sco->launch)) {
176                             $previd = $sco->id;
177                         }
178                     }
179                     require_once($CFG->dirroot.'/mod/scorm/datamodels/sequencinglib.php');
180                     if (scorm_seq_evaluate($sco->id,$usertracks)) {
181                         if ($sco->id == $scoid) {
182                             $result->prerequisites = true;
183                         }
184                             $url = $CFG->wwwroot.'/mod/scorm/player.php?a='.$scorm->id.'&amp;currentorg='.$currentorg.$modestr.'&amp;scoid='.$sco->id;
185                             $thisscoidstr = '&scoid='.$sco->id;
186                             $link = $CFG->wwwroot.'/mod/scorm/loadSCO.php?a='.$scorm->id.$thisscoidstr.$modestr;
187                             //$result->toc .= $statusicon.'&nbsp;'.$startbold.'<a href="'.$url.'">'.format_string($sco->title).'</a>'.$score.$endbold."</li>\n";
188                             $result->toc .= '<li><a title="'.$link.'">'.$statusicon.'&nbsp;'.format_string($sco->title).'&nbsp;'.$score.'</a>'."</li>\n";
189                             $tocmenus[$sco->id] = scorm_repeater('&minus;',$level) . '&gt;' . format_string($sco->title);
190                     } else {
191                         if ($sco->id == $scoid) {
192                             $result->prerequisites = false;
193                         }
194                         $result->toc .= $statusicon.'&nbsp;'.format_string($sco->title)."\n";
195                     }
196                 }
197             } else {
198                 $result->toc .= '&nbsp;'.format_string($sco->title)."</li>\n";
199             }
200             if (($nextsco !== false) && ($nextid == 0) && ($findnext)) {
201                 if (!empty($nextsco->launch)) {
202                     $nextid = $nextsco->id;
203                 }
204             }
205         }
206         for ($i=0;$i<$level;$i++) {
207             $result->toc .= "\t\t</ul></li>\n";
208         }
210         if ($play) {
211             $sco = $DB->get_record('scorm_scoes', array('id'=>$scoid));
212             $sco->previd = $previd;
213             $sco->nextid = $nextid;
214             $result->sco = $sco;
215             $result->incomplete = $incomplete;
216         } else {
217             $result->incomplete = $incomplete;
218         }
219     }
220 //    $result->toc .= "\t</ul>\n";
223     // NEW IMS TOC
224     $result->toc .= '</ul></div></div>';
225     $result->toc .= '</div>';
226     $result->toc .= '<div id="scorm_navpanel"></div>';
230     if ($scorm->hidetoc == 0) {
231         $PAGE->requires->data_for_js('scormdata', array(
232                 'plusicon' => $OUTPUT->pix_url('plus', 'scorm'),
233                 'minusicon' => $OUTPUT->pix_url('minus', 'scorm')));
234         $PAGE->requires->js('/lib/cookies.js');
235         $PAGE->requires->js('/mod/scorm/datamodels/scorm_datamodels.js');
236     }
238     $url = new moodle_url('/mod/scorm/player.php?a='.$scorm->id.'&currentorg='.$currentorg.$modestr);
239     $result->tocmenu = $OUTPUT->single_select($url, 'scoid', $tocmenus, $sco->id, null, "tocmenu");
241     return $result;