Removed 'edit category' redundant button
[moodle.git] / mod / scorm / datamodels / sequencinglib.php
CommitLineData
10fd330f 1<?php // $Id$
2
3function scorm_seq_evaluate($scoid,$usertracks) {
4 return true;
5}
6
7function scorm_seq_overall ($scoid,$userid,$request) {
8 $seq = scorm_seq_navigation($scoid,$userid,$request);
9 if ($seq->navigation) {
10 if ($seq->termination != null) {
11 $seq = scorm_seq_termination($scoid,$userid,$seq);
12 }
13 if ($seq->sequencing != null) {
14 // scorm_sequencing_sequencing($scoid,$userid,$seq);
15 }
16 if ($seq->target != null) {
17 // scorm_sequencing_delivery($scoid,$userid,$seq);
18 }
19 }
20 if ($seq->exception != null) {
21 // scorm_sequencing_exception($seq);
22 }
23 return 'true';
24}
25
26function scorm_seq_navigation ($scoid,$userid,$request) {
27 /// Sequencing structure
28 $seq = new stdClass();
29 $seq->currentactivity = scorm_get_sco($scoid);
30 $seq->active = scorm_seq_is('active',$scoid,$userid);
31 $seq->suspended = scorm_seq_is('suspended',$scoid,$userid);
32 $seq->navigation = null;
33 $seq->termination = null;
34 $seq->sequencing = null;
35 $seq->target = null;
36 $seq->exception = null;
37
38 switch ($request) {
39 case 'start_':
40 if (empty($seq->currentactivity)) {
41 $seq->navigation = true;
42 $seq->sequencing = 'start';
43 } else {
44 $seq->exception = 'NB.2.1-1'; /// Sequencing session already begun
45 }
46 break;
47 case 'resumeall_':
48 if (empty($seq->currentactivity)) {
49 if ($track = get_record('scorm_scoes_track','scoid',$scoid,'userid',$userid,'name','suspendedactivity')) {
50 $seq->navigation = true;
51 $seq->sequencing = 'resumeall';
52 } else {
53 $seq->exception = 'NB.2.1-3'; /// No suspended activity found
54 }
55 } else {
56 $seq->exception = 'NB.2.1-1'; /// Sequencing session already begun
57 }
58 break;
59 case 'continue_':
60 case 'previous_':
61 if (!empty($seq->currentactivity)) {
62 $sco = $seq->currentactivity;
63 if ($sco->parent != '/') {
64 if ($parentsco = scorm_get_parent($sco)) {
65 if (isset($parentsco->flow) && ($parent->flow == true)) {
66 // Current activity is active !
67 if ($request == 'continue_') {
68 $seq->navigation = true;
69 $seq->termination = 'exit';
70 $seq->sequencing = 'continue';
71 } else {
72 if (isset($parentsco->forwardonly) && ($parent->forwardolny == false)) {
73 $seq->navigation = true;
74 $seq->termination = 'exit';
75 $seq->sequencing = 'previous';
76 } else {
77 $seq->exception = 'NB.2.1-5'; /// Violates control mode
78 }
79 }
80 }
81 }
82 }
83 } else {
84 $seq->exception = 'NB.2.1-2'; /// Current activity not defined
85 }
86 break;
87 case 'forward_':
88 case 'backward_':
89 $seq->exception = 'NB.2.1-7' ; /// None to be done, behavior not defined
90 break;
91 case 'exit_':
92 case 'abandon_':
93 if (!empty($seq->currentactivity)) {
94 // Current activity is active !
95 $seq->navigation = true;
96 $seq->termination = substr($request,0,-1);
97 $seq->sequencing = 'exit';
98 } else {
99 $seq->exception = 'NB.2.1-2'; /// Current activity not defined
100 }
101 case 'exitall_':
102 case 'abandonall_':
103 case 'suspendall_':
104 if (!empty($seq->currentactivity)) {
105 $seq->navigation = true;
106 $seq->termination = substr($request,0,-1);
107 $seq->sequencing = 'exit';
108 } else {
109 $seq->exception = 'NB.2.1-2'; /// Current activity not defined
110 }
111 break;
112 default: /// {target=<STRING>}choice
113 if ($targetsco = get_record('scorm_scoes','scorm',$sco->scorm,'identifier',$request)) {
114 if ($targetsco->parent != '/') {
115 $seq->target = $request;
116 } else {
117 if ($parentsco = scorm_get_parent($targetsco)) {
118 if (isset($parentsco->choice) && ($parent->choice == true)) {
119 $seq->target = $request;
120 }
121 }
122 }
123 if ($seq->target != null) {
124 if (empty($seq->currentactivity)) {
125 $seq->navigation = true;
126 $seq->sequencing = 'choice';
127 } else {
128 if (!$sco = scorm_get_sco($scoid)) {
129 return $seq;
130 }
131 if ($sco->parent != $target->parent) {
132 $ancestors = scorm_get_ancestors($sco);
133 $commonpos = scorm_find_common_ancestor($ancestors,$targetsco);
134 if ($commonpos !== false) {
135 if ($activitypath = array_slice($ancestors,0,$commonpos)) {
136 foreach ($activitypath as $activity) {
137 if (scorm_seq_is('active',$activity->id,$userid) && (isset($activity->choiceexit) && ($activity->choiceexit == false))) {
138 $seq->navigation = false;
139 $seq->termination = null;
140 $seq->sequencing = null;
141 $seq->target = null;
142 $seq->exception = 'NB.2.1-8'; /// Violates control mode
143 return $seq;
144 }
145 }
146 } else {
147 $seq->navigation = false;
148 $seq->termination = null;
149 $seq->sequencing = null;
150 $seq->target = null;
151 $seq->exception = 'NB.2.1-9';
152 }
153 }
154 }
155 // Current activity is active !
156 $seq->navigation = true;
157 $seq->sequencing = 'choice';
158 }
159 } else {
160 $seq->exception = 'NB.2.1-10'; /// Violates control mode
161 }
162 } else {
163 $seq->exception = 'NB.2.1-11'; /// Target activity does not exists
164 }
165 break;
166 }
167 return $seq;
168}
169
170function scorm_seq_temination ($seq,$userid) {
171 if (empty($seq->currentactivity)) {
172 $seq->termination = false;
173 $seq->exception = 'TB.2.3-1';
174 return $seq;
175 }
176
177 $sco = $seq->currentactivity;
178
179 if ((($seq->termination == 'exit') || ($seq->termination == 'abandon')) && !$seq->active) {
180 $seq->termination = false;
181 $seq->exception = 'TB.2.3-2';
182 return $seq;
183 }
184 switch ($seq->termination) {
185 case 'exit':
186 scorm_seq_end_attempt($sco,$userid);
187 $seq = scorm_seq_exit_action_rules($seq,$userid);
188 do {
189 $exit = true;
190 $seq = scorm_seq_post_cond_rules($seq,$userid);
191 if ($seq->termination == 'exitparent') {
192 if ($sco->parent != '/') {
193 $sco = scorm_get_parent($sco);
194 $seq->currentactivity = $sco;
195 $seq->active = scorm_seq_is('active',$sco->id,$userid);
196 scorm_seq_end_attempt($sco,$userid);
197 $exit = false;
198 } else {
199 $seq->termination = false;
200 $seq->exception = 'TB.2.3-4';
201 return $seq;
202 }
203 }
204 } while (($exit == false) && ($seq->termination == 'exit'));
205 if ($seq->termination == 'exit') {
206 $seq->termination = true;
207 return $seq;
208 }
209 case 'exitall':
210 if ($seq->active) {
211 scorm_seq_end_attempt($sco,$userid);
212 }
213 /// Terminate Descendent Attempts Process
214 if ($ancestors = scorm_get_ancestors($sco)) {
215 foreach ($ancestors as $ancestor) {
216 scorm_seq_end_attempt($ancestor,$userid);
217 $seq->currentactivity = $ancestor;
218 }
219 }
220 $seq->active = scorm_seq_is('active',$seq->currentactivity->id,$userid);
221 $seq->termination = true;
222 break;
223 case 'suspendall':
224 if (($seq->active) || ($seq->suspended)) {
225 scorm_seq_set('suspended',$sco->id,$userid);
226 } else {
227 if ($sco->parent != '/') {
228 $parentsco = scorm_get_parent($sco);
229 scorm_seq_set('suspended',$parentsco->id,$userid);
230 } else {
231 $seq->termination = false;
232 $seq->exception = 'TB.2.3-3';
233 // return $seq;
234 }
235 }
236 if ($ancestors = scorm_get_ancestors($sco)) {
237 foreach ($ancestors as $ancestor) {
238 scorm_seq_set('active',$ancestor->id,$userid,0,false);
239 scorm_seq_set('suspended',$ancestor->id,$userid);
240 $seq->currentactivity = $ancestor;
241 }
242 $seq->termination = true;
243 $seq->sequencing = 'exit';
244 } else {
245 $seq->termination = false;
246 $seq->exception = 'TB.2.3-5';
247 }
248 break;
249 case 'abandon':
250 scorm_seq_set('active',$sco->id,$userid,0,false);
251 $seq->active = null;
252 $seq->termination = true;
253 break;
254 case 'abandonall':
255 if ($ancestors = scorm_get_ancestors($sco)) {
256 foreach ($ancestors as $ancestor) {
257 scorm_seq_set('active',$ancestor->id,$userid,0,false);
258 $seq->currentactivity = $ancestor;
259 }
260 $seq->termination = true;
261 $seq->sequencing = 'exit';
262 } else {
263 $seq->termination = false;
264 $seq->exception = 'TB.2.3-6';
265 }
266 break;
267 default:
268 $seq->termination = false;
269 $seq->exception = 'TB.2.3-7';
270 break;
271 }
272 return $seq;
273}
274
275function scorm_seq_end_attempt($sco,$userid) {
276 if (scorm_is_leaf($sco)) {
277 if (!isset($sco->tracked) || ($sco->tracked == 1)) {
278 if (!scorm_seq_is('suspended',$sco->id,$userid)) {
279 if (!isset($sco->completionsetbycontent) || ($sco->completionsetbycontent == 0)) {
280 if (!scorm_seq_is('attemptprogressstatus',$sco->id,$userid,$attempt)) {
281 scorm_seq_set('attemptprogressstatus',$sco->id,$userid,$attempt);
282 scorm_seq_set('attemptcompletionstatus',$sco->id,$userid,$attempt);
283 }
284 }
285 if (!isset($sco->objectivesetbycontent) || ($sco->objectivesetbycontent == 0)) {
286 if ($sco->objectives) {
287 foreach ($objectives as $objective) {
288 if ($objective->primary) {
289 if (!scorm_seq_objective_progress_status($sco,$userid,$objective)) {
290 scorm_seq_set('objectiveprogressstatus',$sco->id,$userid,$attempt);
291 scorm_seq_set('objectivesatisfiedstatus',$sco->id,$userid,$attempt);
292 }
293 }
294 }
295 }
296 }
297 }
298 }
299 } else {
300 if ($children = scorm_get_children($sco)) {
301 $suspended = false;
302 foreach ($children as $child) {
303 if (scorm_seq_is('suspended',$child,$userid)) {
304 $suspended = true;
305 break;
306 }
307 }
308 if ($suspended) {
309 scorm_seq_set('suspended',$sco,$userid);
310 } else {
311 scorm_seq_set('suspended',$sco,$userid,0,false);
312 }
313 }
314 }
315 scorm_seq_set('active',$sco,$userid,0,false);
316 scorm_seq_overall_rollup($sco,$userid);
317}
318
319function scorm_seq_is($what, $scoid, $userid, $attempt=0) {
320 /// Check if passed activity $what is active
321 $active = false;
322 if ($track = get_record('scorm_scoes_track','scoid',$scoid,'userid',$userid,'element',$what)) {
323 $active = true;
324 }
325 return $active;
326}
327
328function scorm_seq_set($what, $scoid, $userid, $attempt=0, $value='true') {
329 /// set passed activity to active or not
330 if ($value == false) {
331 delete_record('scorm_scoes_track','scoid',$scoid,'userid',$userid,'element',$what);
332 } else {
333 $sco = scorm_get_sco($scoid);
334 scorm_insert_track($userid, $sco->scorm, $sco->id, 0, $what, $value);
335 }
336}
337
338function scorm_seq_exit_action_rules($seq,$userid) {
339 $sco = $seq->currentactivity;
340 $ancestors = scorm_get_ancestors($sco);
341 $exittarget = null;
342 foreach (array_reverse($ancestors) as $ancestor) {
343 if (scorm_seq_rules_check($ancestor,'exit') != null) {
344 $exittarget = $ancestor;
345 break;
346 }
347 }
348 if ($exittarget != null) {
349 $commons = array_slice($ancestors,0,scorm_find_common_ancestor($ancestors,$exittarget));
350
351 /// Terminate Descendent Attempts Process
352 if ($commons) {
353 foreach ($commons as $ancestor) {
354 scorm_seq_end_attempt($ancestor,$userid);
355 $seq->currentactivity = $ancestor;
356 }
357 }
358 }
359 return $seq;
360}
361
362function scorm_seq_post_cond_rules($seq,$userid) {
363 $sco = $seq->currentactivity;
364 if (!$seq->suspended) {
365 if ($action = scorm_seq_rules_check($sco,'post') != null) {
366 switch($action) {
367 case 'retry':
368 case 'continue':
369 case 'previous':
370 $seq->sequencing = $action;
371 break;
372 case 'exitparent':
373 case 'exitall':
374 $seq->termination = $action;
375 break;
376 case 'retryall':
377 $seq->termination = 'exitall';
378 $seq->sequencing = 'retry';
379 break;
380 }
381 }
382 }
383 return $seq;
384}
385
386?>