Passed
Push — 1.11.x ( 47915c...7101db )
by Yannick
09:38
created

Cc13Quiz::getAnswersFib()   F

Complexity

Conditions 19
Paths 350

Size

Total Lines 88
Code Lines 52

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 19
eloc 52
c 1
b 0
f 0
nc 350
nop 4
dl 0
loc 88
rs 1.8083

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
class Cc13Quiz extends Cc13Entities
5
{
6
    public function generateData()
7
    {
8
        $data = [];
9
        $instances = $this->generateInstances();
10
        if (!empty($instances)) {
11
            foreach ($instances as $instance) {
12
                if ($instance['is_question_bank'] == 0) {
13
                    $data[] = $this->getQuizData($instance);
14
                }
15
            }
16
        }
17
18
        return $data;
19
    }
20
21
    public function storeQuiz($quiz)
22
    {
23
        $courseInfo = api_get_course_info();
24
        $exercise = new Exercise($courseInfo['real_id']);
25
        $title = Exercise::format_title_variable($quiz['title']);
26
        $exercise->updateTitle($title);
27
        $exercise->updateDescription('');
28
        $exercise->updateAttempts($quiz['max_attempts']);
29
        $exercise->updateFeedbackType(0);
30
31
        $exercise->setRandom(0);
32
        $exercise->updateRandomAnswers(!empty($moduleValues['shuffleanswers']));
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $moduleValues seems to never exist and therefore empty should always be true.
Loading history...
33
        $exercise->updateExpiredTime((int) $quiz['timelimit']);
34
        $exercise->updateType(1);
35
36
        // Create the new Quiz
37
        $exercise->save();
38
39
        if (!empty($quiz['questions'])) {
40
            foreach ($quiz['questions'] as $question) {
41
                $qtype = $question['type'];
42
43
                $types = ['unique_answer' => 1, 'multiple_answer' => 2];
44
                $questionType = $types[$qtype];
45
46
                $questionInstance = Question::getInstance($questionType);
47
                if (empty($questionInstance)) {
48
                    continue;
49
                }
50
51
                $questionInstance->updateTitle($question['title']);
52
                $questionText = '';
53
54
                // Replace the path from @@PLUGINFILE@@ to a correct chamilo path
55
                $questionText = str_replace(
56
                    '@@PLUGINFILE@@',
57
                    '/courses/'.$courseInfo['path'].'/document/moodle',
58
                    $questionText
59
                );
60
61
                $questionInstance->updateDescription($questionText);
62
                $questionInstance->updateLevel(1);
63
                $questionInstance->updateCategory(0);
64
65
                //Save normal question if NOT media
66
                if ($questionInstance->type != MEDIA_QUESTION) {
67
                    $questionInstance->save($exercise);
68
                    // modify the exercise
69
                    $exercise->addToList($questionInstance->iid);
70
                    $exercise->update_question_positions();
71
                }
72
73
                if ($qtype == 'unique_answer') {
74
                    $objAnswer = new Answer($questionInstance->iid);
75
                    $questionWeighting = 0;
76
                    foreach ($question['answers'] as $slot => $answerValues) {
77
                        $correct = $answerValues['score'] ? (int) $answerValues['score'] : 0;
78
                        $answer = $answerValues['title'];
79
                        $comment = $answerValues['feedback'];
80
                        $weighting = $answerValues['score'];
81
                        $weighting = abs($weighting);
82
                        if ($weighting > 0) {
83
                            $questionWeighting += $weighting;
84
                        }
85
                        $goodAnswer = $correct ? true : false;
86
87
                        $objAnswer->createAnswer(
88
                            $answer,
89
                            $goodAnswer,
90
                            $comment,
91
                            $weighting,
92
                            $slot + 1,
93
                            null,
94
                            null,
95
                            ''
96
                        );
97
                    }
98
                    // saves the answers into the data base
99
                    $objAnswer->save();
100
                    // sets the total weighting of the question
101
                    $questionInstance->updateWeighting($questionWeighting);
102
                    $questionInstance->save($exercise);
103
                } else {
104
                    $objAnswer = new Answer($questionInstance->iid);
105
                    $questionWeighting = 0;
106
                    foreach ($question['answers'] as $slot => $answerValues) {
107
                        $answer = $answerValues['title'];
108
                        $comment = $answerValues['feedback'];
109
                        $weighting = $answerValues['score'];
110
                        if ($weighting > 0) {
111
                            $questionWeighting += $weighting;
112
                        }
113
                        $goodAnswer = $weighting > 0;
114
115
                        $objAnswer->createAnswer(
116
                            $answer,
117
                            $goodAnswer,
118
                            $comment,
119
                            $weighting,
120
                            $slot + 1,
121
                            null,
122
                            null,
123
                            ''
124
                        );
125
                    }
126
127
                    // saves the answers into the data base
128
                    $objAnswer->save();
129
                    // sets the total weighting of the question
130
                    $questionInstance->updateWeighting($questionWeighting);
131
                    $questionInstance->save($exercise);
132
                }
133
            }
134
        }
135
    }
136
137
    public function storeQuizzes($quizzes)
138
    {
139
        if (!empty($quizzes)) {
140
            foreach ($quizzes as $quiz) {
141
                $this->storeQuiz($quiz);
142
            }
143
        }
144
    }
145
146
    public function getQuizData($instance)
147
    {
148
        $values = [];
149
        if (!empty($instance)) {
150
            $questions = [];
151
            if (!empty($instance['questions'])) {
152
                foreach ($instance['questions'] as $question) {
153
                    $questions[$question['id']] = [
154
                        'title' => $question['title'],
155
                        'type' => $question['qtype'],
156
                        'ponderation' => $question['defaultgrade'],
157
                        'answers' => $question['answers'],
158
                    ];
159
                }
160
            }
161
            $values = [
162
                'id' => $instance['id'],
163
                'title' => $instance['title'],
164
                'timelimit' => $instance['options']['timelimit'],
165
                'max_attempts' => $instance['options']['max_attempts'],
166
                'questions' => $questions,
167
            ];
168
        }
169
170
        return $values;
171
    }
172
173
    private function generateInstances()
174
    {
175
        $lastInstanceId = 0;
176
        $lastQuestionId = 0;
177
        $lastAnswerId = 0;
178
179
        $instances = [];
180
181
        $types = [TOOL_TYPE_QUIZ];
182
183
        foreach ($types as $type) {
184
            if (!empty(Cc1p3Convert::$instances['instances'][$type])) {
185
                foreach (Cc1p3Convert::$instances['instances'][$type] as $instance) {
186
                    if ($type == TOOL_TYPE_QUIZ) {
187
                        $is_question_bank = 0;
188
                    } else {
189
                        $is_question_bank = 1;
190
                    }
191
192
                    $assessmentFile = $this->getExternalXml($instance['resource_indentifier']);
193
194
                    if (!empty($assessmentFile)) {
195
                        $assessment = $this->loadXmlResource(Cc1p3Convert::$pathToManifestFolder.DIRECTORY_SEPARATOR.$assessmentFile);
196
197
                        if (!empty($assessment)) {
198
                            $replaceValues = ['unlimited' => 0];
199
200
                            $questions = $this->getQuestions($assessment, $lastQuestionId, $lastAnswerId, dirname($assessmentFile), $is_question_bank);
201
                            $questionCount = count($questions);
202
203
                            if (!empty($questionCount)) {
204
                                $lastInstanceId++;
205
206
                                $instances[$instance['resource_indentifier']]['questions'] = $questions;
207
                                $instances[$instance['resource_indentifier']]['id'] = $lastInstanceId;
208
                                $instances[$instance['resource_indentifier']]['title'] = $instance['title'];
209
                                $instances[$instance['resource_indentifier']]['is_question_bank'] = $is_question_bank;
210
                                $instances[$instance['resource_indentifier']]['options']['timelimit'] = $this->getGlobalConfig($assessment, 'qmd_timelimit', 0);
211
                                $instances[$instance['resource_indentifier']]['options']['max_attempts'] = $this->getGlobalConfig($assessment, 'cc_maxattempts', 0, $replaceValues);
212
                            }
213
                        }
214
                    }
215
                }
216
            }
217
        }
218
219
        return $instances;
220
    }
221
222
    private function getGlobalConfig($assessment, $option, $defaultValue, $replaceValues = '')
223
    {
224
        $xpath = Cc1p3Convert::newxPath($assessment, Cc1p3Convert::getquizns());
225
        $metadata = $xpath->query('/xmlns:questestinterop/xmlns:assessment/xmlns:qtimetadata/xmlns:qtimetadatafield');
226
227
        foreach ($metadata as $field) {
228
            $fieldLabel = $xpath->query('xmlns:fieldlabel', $field);
229
            $fieldLabel = !empty($fieldLabel->item(0)->nodeValue) ? $fieldLabel->item(0)->nodeValue : '';
230
231
            if (strtolower($fieldLabel) == strtolower($option)) {
232
                $fieldEntry = $xpath->query('xmlns:fieldentry', $field);
233
                $response = !empty($fieldEntry->item(0)->nodeValue) ? $fieldEntry->item(0)->nodeValue : '';
234
            }
235
        }
236
237
        $response = !empty($response) ? trim($response) : '';
238
239
        if (!empty($replaceValues)) {
240
            foreach ($replaceValues as $key => $value) {
241
                $response = ($key == $response) ? $value : $response;
242
            }
243
        }
244
245
        $response = empty($response) ? $defaultValue : $response;
246
247
        return $response;
248
    }
249
250
    private function getQuestions($assessment, &$lastQuestionId, &$last_answer_id, $rootPath, $is_question_bank)
251
    {
252
        $questions = [];
253
254
        $xpath = Cc1p3Convert::newxPath($assessment, Cc1p3Convert::getquizns());
255
256
        if (!$is_question_bank) {
257
            $questionsItems = $xpath->query('/xmlns:questestinterop/xmlns:assessment/xmlns:section/xmlns:item');
258
        } else {
259
            $questionsItems = $xpath->query('/xmlns:questestinterop/xmlns:objectbank/xmlns:item');
260
        }
261
262
        foreach ($questionsItems as $question_item) {
263
            $countQuestions = $xpath->evaluate('count(xmlns:presentation/xmlns:flow/xmlns:material/xmlns:mattext)', $question_item);
264
265
            if ($countQuestions == 0) {
266
                $questionTitle = $xpath->query('xmlns:presentation/xmlns:material/xmlns:mattext', $question_item);
267
            } else {
268
                $questionTitle = $xpath->query('xmlns:presentation/xmlns:flow/xmlns:material/xmlns:mattext', $question_item);
269
            }
270
271
            $questionTitle = !empty($questionTitle->item(0)->nodeValue) ? $questionTitle->item(0)->nodeValue : '';
272
273
            $questionIdentifier = $xpath->query('@ident', $question_item);
274
            $questionIdentifier = !empty($questionIdentifier->item(0)->nodeValue) ? $questionIdentifier->item(0)->nodeValue : '';
275
276
            if (!empty($questionIdentifier)) {
277
                $questionType = $this->getQuestionType($questionIdentifier, $assessment);
278
279
                if (!empty($questionType['qtype'])) {
280
                    $lastQuestionId++;
281
282
                    $questions[$questionIdentifier]['id'] = $lastQuestionId;
283
284
                    $questionTitle = $this->updateSources($questionTitle, $rootPath);
285
                    $questionTitle = !empty($questionTitle) ? str_replace("%24", "\$", $this->includeTitles($questionTitle)) : '';
286
287
                    $questionname = $xpath->query('@title', $question_item);
288
                    $questionname = !empty($questionname->item(0)->nodeValue) ? $questionname->item(0)->nodeValue : '';
289
290
                    $questions[$questionIdentifier]['title'] = $questionTitle;
291
                    $questions[$questionIdentifier]['name'] = $questionname;
292
                    $questions[$questionIdentifier]['identifier'] = $questionIdentifier;
293
                    $questions[$questionIdentifier]['qtype'] = $questionType['qtype'];
294
                    $questions[$questionIdentifier]['cc_type'] = $questionType['cc'];
295
                    $questions[$questionIdentifier]['feedback'] = $this->getGeneralFeedback($assessment, $questionIdentifier);
296
                    $questions[$questionIdentifier]['defaultgrade'] = $this->getDefaultgrade($assessment, $questionIdentifier);
297
                    $questions[$questionIdentifier]['answers'] = $this->getAnswers($questionIdentifier, $assessment, $lastAnswerId);
298
                }
299
            }
300
        }
301
302
        $questions = !empty($questions) ? $questions : '';
303
304
        return $questions;
305
    }
306
307
    private function getDefaultgrade($assessment, $questionIdentifier)
308
    {
309
        $result = 1;
310
        $xpath = Cc1p3Convert::newxPath($assessment, Cc1p3Convert::getquizns());
311
        $query = '//xmlns:item[@ident="'.$questionIdentifier.'"]';
312
        $query .= '//xmlns:qtimetadatafield[xmlns:fieldlabel="cc_weighting"]/xmlns:fieldentry';
313
        $defgrade = $xpath->query($query);
314
        if (!empty($defgrade) && ($defgrade->length > 0)) {
315
            $resp = (int) $defgrade->item(0)->nodeValue;
316
            if ($resp >= 0 && $resp <= 99) {
317
                $result = $resp;
318
            }
319
        }
320
321
        return $result;
322
    }
323
324
    private function getGeneralFeedback($assessment, $questionIdentifier)
325
    {
326
        $xpath = Cc1p3Convert::newxPath($assessment, Cc1p3Convert::getquizns());
327
328
        $respconditions = $xpath->query('//xmlns:item[@ident="'.$questionIdentifier.'"]/xmlns:resprocessing/xmlns:respcondition');
329
330
        if (!empty($respconditions)) {
331
            foreach ($respconditions as $respcondition) {
332
                $continue = $respcondition->getAttributeNode('continue');
333
                $continue = !empty($continue->nodeValue) ? strtolower($continue->nodeValue) : '';
334
335
                if ($continue == 'yes') {
336
                    $displayFeedback = $xpath->query('xmlns:displayfeedback', $respcondition);
337
338
                    if (!empty($displayFeedback)) {
339
                        foreach ($displayFeedback as $feedback) {
340
                            $feedbackIdentifier = $feedback->getAttributeNode('linkrefid');
341
                            $feedbackIdentifier = !empty($feedbackIdentifier->nodeValue) ? $feedbackIdentifier->nodeValue : '';
342
343
                            if (!empty($feedbackIdentifier)) {
344
                                $feedbackIdentifiers[] = $feedbackIdentifier;
345
                            }
346
                        }
347
                    }
348
                }
349
            }
350
        }
351
352
        $feedback = '';
353
        $feedbackIdentifiers = empty($feedbackIdentifiers) ? '' : $feedbackIdentifiers;
354
355
        if (!empty($feedbackIdentifiers)) {
356
            foreach ($feedbackIdentifiers as $feedbackIdentifier) {
357
                $feedbacks = $xpath->query('//xmlns:item[@ident="'.$questionIdentifier.'"]/xmlns:itemfeedback[@ident="'.$feedbackIdentifier.'"]/xmlns:flow_mat/xmlns:material/xmlns:mattext');
358
                $feedback .= !empty($feedbacks->item(0)->nodeValue) ? $feedbacks->item(0)->nodeValue.' ' : '';
359
            }
360
        }
361
362
        return $feedback;
363
    }
364
365
    private function getFeedback($assessment, $identifier, $itemIdentifier, $questionType)
366
    {
367
        $xpath = Cc1p3Convert::newxPath($assessment, Cc1p3Convert::getquizns());
368
369
        $resourceProcessing = $xpath->query('//xmlns:item[@ident="'.$itemIdentifier.'"]/xmlns:resprocessing/xmlns:respcondition');
370
371
        if (!empty($resourceProcessing)) {
372
            foreach ($resourceProcessing as $response) {
373
                $varequal = $xpath->query('xmlns:conditionvar/xmlns:varequal', $response);
374
                $varequal = !empty($varequal->item(0)->nodeValue) ? $varequal->item(0)->nodeValue : '';
375
376
                if (strtolower($varequal) == strtolower($identifier) || ($questionType == CC_QUIZ_ESSAY)) {
377
                    $displayFeedback = $xpath->query('xmlns:displayfeedback', $response);
378
379
                    if (!empty($displayFeedback)) {
380
                        foreach ($displayFeedback as $feedback) {
381
                            $feedbackIdentifier = $feedback->getAttributeNode('linkrefid');
382
                            $feedbackIdentifier = !empty($feedbackIdentifier->nodeValue) ? $feedbackIdentifier->nodeValue : '';
383
384
                            if (!empty($feedbackIdentifier)) {
385
                                $feedbackIdentifiers[] = $feedbackIdentifier;
386
                            }
387
                        }
388
                    }
389
                }
390
            }
391
        }
392
393
        $feedback = '';
394
        $feedbackIdentifiers = empty($feedbackIdentifiers) ? '' : $feedbackIdentifiers;
395
396
        if (!empty($feedbackIdentifiers)) {
397
            foreach ($feedbackIdentifiers as $feedbackIdentifier) {
398
                $feedbacks = $xpath->query('//xmlns:item[@ident="'.$itemIdentifier.'"]/xmlns:itemfeedback[@ident="'.$feedbackIdentifier.'"]/xmlns:flow_mat/xmlns:material/xmlns:mattext');
399
                $feedback .= !empty($feedbacks->item(0)->nodeValue) ? $feedbacks->item(0)->nodeValue.' ' : '';
400
            }
401
        }
402
403
        return $feedback;
404
    }
405
406
    private function getAnswersFib($questionIdentifier, $identifier, $assessment, &$lastAnswerId)
407
    {
408
        $xpath = Cc1p3Convert::newxPath($assessment, Cc1p3Convert::getquizns());
409
410
        $correctanswersfib = [];
411
        $incorrectanswersfib = [];
412
413
        $responseItems = $xpath->query('//xmlns:item[@ident="'.$questionIdentifier.'"]/xmlns:resprocessing/xmlns:respcondition');
414
415
        $correctrespcond = $xpath->query('//xmlns:item[@ident="'.$questionIdentifier.'"]/xmlns:resprocessing/xmlns:respcondition/xmlns:setvar[text()="100"]/..');
416
        $correctanswers = $xpath->query('xmlns:conditionvar/xmlns:varequal', $correctrespcond->item(0));
417
418
        // Correct answers.
419
        foreach ($correctanswers as $correctans) {
420
            $answertitle = !empty($correctans->nodeValue) ? $correctans->nodeValue : '';
421
            if (empty($answertitle)) {
422
                continue;
423
            }
424
425
            $lastAnswerId++;
426
427
            $correctanswersfib[$answertitle] = [
428
                'id' => $lastAnswerId,
429
                'title' => $answertitle,
430
                'score' => 1,
431
                'feedback' => '',
432
                'case' => 0, ];
433
        }
434
435
        // Handle incorrect answers and feedback for all items.
436
        foreach ($responseItems as $response_item) {
437
            $setvar = $xpath->query('xmlns:setvar', $response_item);
438
            if (!empty($setvar->length) && $setvar->item(0)->nodeValue == '100') {
439
                // Skip the correct answer responsecondition.
440
                continue;
441
            }
442
443
            $varequal = $xpath->query('xmlns:conditionvar/xmlns:varequal', $response_item);
444
            if (empty($varequal->length)) {
445
                // Skip respcondition elements that don't have varequal containing an answer
446
                continue;
447
            }
448
            $answerTitle = !empty($varequal->item(0)->nodeValue) ? $varequal->item(0)->nodeValue : '';
449
450
            $displayFeedback = $xpath->query('xmlns:displayfeedback', $response_item);
451
452
            unset($feedbackIdentifiers);
453
454
            if (!empty($displayFeedback)) {
455
                foreach ($displayFeedback as $feedback) {
456
                    $feedbackIdentifier = $feedback->getAttributeNode('linkrefid');
457
                    $feedbackIdentifier = !empty($feedbackIdentifier->nodeValue) ? $feedbackIdentifier->nodeValue : '';
458
459
                    if (!empty($feedbackIdentifier)) {
460
                        $feedbackIdentifiers[] = $feedbackIdentifier;
461
                    }
462
                }
463
            }
464
465
            $feedback = '';
466
            $feedbackIdentifiers = empty($feedbackIdentifiers) ? '' : $feedbackIdentifiers;
467
468
            if (!empty($feedbackIdentifiers)) {
469
                foreach ($feedbackIdentifiers as $feedbackIdentifier) {
470
                    $feedbacks = $xpath->query('//xmlns:item[@ident="'.$questionIdentifier.'"]/xmlns:itemfeedback[@ident="'.$feedbackIdentifier.'"]/xmlns:flow_mat/xmlns:material/xmlns:mattext');
471
                    $feedback .= !empty($feedbacks->item(0)->nodeValue) ? $feedbacks->item(0)->nodeValue.' ' : '';
472
                }
473
            }
474
475
            if (array_key_exists($answerTitle, $correctanswersfib)) {
476
                // Already a correct answer, just need the feedback for the correct answer.
477
                $correctanswerfib[$answerTitle]['feedback'] = $feedback;
478
            } else {
479
                // Need to add an incorrect answer.
480
                $lastAnswerId++;
481
                $incorrectanswersfib[] = [
482
                    'id' => $lastAnswerId,
483
                    'title' => $answerTitle,
484
                    'score' => 0,
485
                    'feedback' => $feedback,
486
                    'case' => 0, ];
487
            }
488
        }
489
490
        $answersFib = array_merge($correctanswersfib, $incorrectanswersfib);
491
        $answersFib = empty($answersFib) ? '' : $answersFib;
492
493
        return $answersFib;
494
    }
495
496
    private function getAnswersPatternMatch($questionIdentifier, $identifier, $assessment, &$lastAnswerId)
497
    {
498
        $xpath = Cc1p3Convert::newxPath($assessment, Cc1p3Convert::getquizns());
499
500
        $answersFib = [];
501
502
        $responseItems = $xpath->query('//xmlns:item[@ident="'.$questionIdentifier.'"]/xmlns:resprocessing/xmlns:respcondition');
503
504
        foreach ($responseItems as $response_item) {
505
            $setvar = $xpath->query('xmlns:setvar', $response_item);
506
            $setvar = is_object($setvar->item(0)) ? $setvar->item(0)->nodeValue : '';
507
508
            if ($setvar != '') {
509
                $lastAnswerId++;
510
511
                $answerTitle = $xpath->query('xmlns:conditionvar/xmlns:varequal[@respident="'.$identifier.'"]', $response_item);
512
                $answerTitle = !empty($answerTitle->item(0)->nodeValue) ? $answerTitle->item(0)->nodeValue : '';
513
514
                if (empty($answerTitle)) {
515
                    $answerTitle = $xpath->query('xmlns:conditionvar/xmlns:varsubstring[@respident="'.$identifier.'"]', $response_item);
516
                    $answerTitle = !empty($answerTitle->item(0)->nodeValue) ? '*'.$answerTitle->item(0)->nodeValue.'*' : '';
517
                }
518
519
                if (empty($answerTitle)) {
520
                    $answerTitle = '*';
521
                }
522
523
                $case = $xpath->query('xmlns:conditionvar/xmlns:varequal/@case', $response_item);
524
                $case = is_object($case->item(0)) ? $case->item(0)->nodeValue : 'no'
525
                                    ;
526
                $case = strtolower($case) == 'yes' ? 1 :
527
                            0;
528
529
                $displayFeedback = $xpath->query('xmlns:displayfeedback', $response_item);
530
531
                unset($feedbackIdentifiers);
532
533
                if (!empty($displayFeedback)) {
534
                    foreach ($displayFeedback as $feedback) {
535
                        $feedbackIdentifier = $feedback->getAttributeNode('linkrefid');
536
                        $feedbackIdentifier = !empty($feedbackIdentifier->nodeValue) ? $feedbackIdentifier->nodeValue : '';
537
538
                        if (!empty($feedbackIdentifier)) {
539
                            $feedbackIdentifiers[] = $feedbackIdentifier;
540
                        }
541
                    }
542
                }
543
544
                $feedback = '';
545
                $feedbackIdentifiers = empty($feedbackIdentifiers) ? '' : $feedbackIdentifiers;
546
547
                if (!empty($feedbackIdentifiers)) {
548
                    foreach ($feedbackIdentifiers as $feedbackIdentifier) {
549
                        $feedbacks = $xpath->query('//xmlns:item[@ident="'.$questionIdentifier.'"]/xmlns:itemfeedback[@ident="'.$feedbackIdentifier.'"]/xmlns:flow_mat/xmlns:material/xmlns:mattext');
550
                        $feedback .= !empty($feedbacks->item(0)->nodeValue) ? $feedbacks->item(0)->nodeValue.' ' : '';
551
                    }
552
                }
553
554
                $answersFib[] = ['id' => $lastAnswerId,
555
                                       'title' => $answerTitle,
556
                                       'score' => $setvar,
557
                                       'feedback' => $feedback,
558
                                       'case' => $case, ];
559
            }
560
        }
561
562
        $answersFib = empty($answersFib) ? '' : $answersFib;
563
564
        return $answersFib;
565
    }
566
567
    private function getAnswers($identifier, $assessment, &$lastAnswerId)
568
    {
569
        $xpath = Cc1p3Convert::newxPath($assessment, Cc1p3Convert::getquizns());
570
571
        $answers = [];
572
573
        $questionCcType = $this->getQuestionType($identifier, $assessment);
574
        $questionCcType = $questionCcType['cc'];
575
        $isMultiresponse = ($questionCcType == CC_QUIZ_MULTIPLE_RESPONSE);
576
577
        if ($questionCcType == CC_QUIZ_MULTIPLE_CHOICE || $isMultiresponse || $questionCcType == CC_QUIZ_TRUE_FALSE) {
578
            $queryAnswers = '//xmlns:item[@ident="'.$identifier.'"]/xmlns:presentation/xmlns:response_lid/xmlns:render_choice/xmlns:response_label';
579
            $queryAnswersWithFlow = '//xmlns:item[@ident="'.$identifier.'"]/xmlns:presentation/xmlns:flow/xmlns:response_lid/xmlns:render_choice/xmlns:response_label';
580
581
            $queryIndentifer = '@ident';
582
            $queryTitle = 'xmlns:material/xmlns:mattext';
583
        }
584
585
        if ($questionCcType == CC_QUIZ_ESSAY) {
586
            $queryAnswers = '//xmlns:item[@ident="'.$identifier.'"]/xmlns:presentation/xmlns:response_str';
587
            $queryAnswersWithFlow = '//xmlns:item[@ident="'.$identifier.'"]/xmlns:presentation/xmlns:flow/xmlns:response_str';
588
589
            $queryIndentifer = '@ident';
590
            $queryTitle = 'xmlns:render_fib';
591
        }
592
593
        if ($questionCcType == CC_QUIZ_FIB || $questionCcType == CC_QUIZ_PATTERN_MACHT) {
594
            $xpathQuery = '//xmlns:item[@ident="'.$identifier.'"]/xmlns:presentation/xmlns:response_str/@ident';
595
            $xpathQueryWithFlow = '//xmlns:item[@ident="'.$identifier.'"]/xmlns:presentation/xmlns:flow/xmlns:response_str/@ident';
596
597
            $countResponse = $xpath->evaluate('count('.$xpathQueryWithFlow.')');
598
599
            if ($countResponse == 0) {
600
                $answerIdentifier = $xpath->query($xpathQuery);
601
            } else {
602
                $answerIdentifier = $xpath->query($xpathQueryWithFlow);
603
            }
604
605
            $answerIdentifier = !empty($answerIdentifier->item(0)->nodeValue) ? $answerIdentifier->item(0)->nodeValue : '';
606
607
            if ($questionCcType == CC_QUIZ_FIB) {
608
                $answers = $this->getAnswersFib($identifier, $answerIdentifier, $assessment, $lastAnswerId);
609
            } else {
610
                $answers = $this->getAnswersPatternMatch($identifier, $answerIdentifier, $assessment, $lastAnswerId);
611
            }
612
        } else {
613
            $countResponse = $xpath->evaluate('count('.$queryAnswersWithFlow.')');
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $queryAnswersWithFlow does not seem to be defined for all execution paths leading up to this point.
Loading history...
614
615
            if ($countResponse == 0) {
616
                $responseItems = $xpath->query($queryAnswers);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $queryAnswers does not seem to be defined for all execution paths leading up to this point.
Loading history...
617
            } else {
618
                $responseItems = $xpath->query($queryAnswersWithFlow);
619
            }
620
621
            if (!empty($responseItems)) {
622
                if ($isMultiresponse) {
623
                    $correctAnswerScore = 0;
624
                    //get the correct answers count
625
                    $canswers_query = "//xmlns:item[@ident='{$identifier}']//xmlns:setvar[@varname='SCORE'][.=100]/../xmlns:conditionvar//xmlns:varequal[@case='Yes'][not(parent::xmlns:not)]";
626
                    $canswers = $xpath->query($canswers_query);
627
                    if ($canswers->length > 0) {
628
                        $correctAnswerScore = round(1.0 / (float) $canswers->length, 7); //weird
629
                        $correctAanswersIdent = [];
630
                        foreach ($canswers as $cnode) {
631
                            $correctAanswersIdent[$cnode->nodeValue] = true;
632
                        }
633
                    }
634
                }
635
636
                foreach ($responseItems as $response_item) {
637
                    $lastAnswerId++;
638
639
                    $answerIdentifier = $xpath->query($queryIndentifer, $response_item);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $queryIndentifer does not seem to be defined for all execution paths leading up to this point.
Loading history...
640
                    $answerIdentifier = !empty($answerIdentifier->item(0)->nodeValue) ? $answerIdentifier->item(0)->nodeValue : '';
641
642
                    $answerTitle = $xpath->query($queryTitle, $response_item);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $queryTitle does not seem to be defined for all execution paths leading up to this point.
Loading history...
643
                    $answerTitle = !empty($answerTitle->item(0)->nodeValue) ? $answerTitle->item(0)->nodeValue : '';
644
645
                    $answerFeedback = $this->getFeedback($assessment, $answerIdentifier, $identifier, $questionCcType);
646
647
                    $answer_score = $this->getScore($assessment, $answerIdentifier, $identifier);
648
649
                    if ($isMultiresponse && isset($correctAanswersIdent[$answerIdentifier])) {
650
                        $answer_score = $correctAnswerScore;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $correctAnswerScore does not seem to be defined for all execution paths leading up to this point.
Loading history...
651
                    }
652
653
                    $answers[] = ['id' => $lastAnswerId,
654
                                       'title' => $answerTitle,
655
                                       'score' => $answer_score,
656
                                       'identifier' => $answerIdentifier,
657
                                       'feedback' => $answerFeedback, ];
658
                }
659
            }
660
        }
661
662
        $answers = empty($answers) ? '' : $answers;
663
664
        return $answers;
665
    }
666
667
    private function getScore($assessment, $identifier, $questionIdentifier)
668
    {
669
        $xpath = Cc1p3Convert::newxPath($assessment, Cc1p3Convert::getquizns());
670
671
        $resourceProcessing = $xpath->query('//xmlns:item[@ident="'.$questionIdentifier.'"]/xmlns:resprocessing/xmlns:respcondition');
672
673
        if (!empty($resourceProcessing)) {
674
            foreach ($resourceProcessing as $response) {
675
                $questionCcType = $this->getQuestionType($questionIdentifier, $assessment);
676
                $questionCcType = $questionCcType['cc'];
677
678
                $varequal = $xpath->query('xmlns:conditionvar/xmlns:varequal', $response);
679
                $varequal = !empty($varequal->item(0)->nodeValue) ? $varequal->item(0)->nodeValue : '';
680
681
                if (strtolower($varequal) == strtolower($identifier)) {
682
                    $score = $xpath->query('xmlns:setvar', $response);
683
                    $score = !empty($score->item(0)->nodeValue) ? $score->item(0)->nodeValue : '';
684
                }
685
            }
686
        }
687
688
        $score = empty($score) ? "0.0000000" : '1.0000000';
689
690
        return $score;
691
    }
692
693
    private function getQuestionType($identifier, $assessment)
694
    {
695
        $xpath = Cc1p3Convert::newxPath($assessment, Cc1p3Convert::getquizns());
696
697
        $metadata = $xpath->query('//xmlns:item[@ident="'.$identifier.'"]/xmlns:itemmetadata/xmlns:qtimetadata/xmlns:qtimetadatafield');
698
699
        foreach ($metadata as $field) {
700
            $fieldLabel = $xpath->query('xmlns:fieldlabel', $field);
701
            $fieldLabel = !empty($fieldLabel->item(0)->nodeValue) ? $fieldLabel->item(0)->nodeValue : '';
702
703
            if ($fieldLabel == 'cc_profile') {
704
                $fieldEntry = $xpath->query('xmlns:fieldentry', $field);
705
                $type = !empty($fieldEntry->item(0)->nodeValue) ? $fieldEntry->item(0)->nodeValue : '';
706
            }
707
        }
708
709
        $returnType = [];
710
711
        $returnType['qtype'] = '';
712
        $returnType['cc'] = $type;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $type does not seem to be defined for all execution paths leading up to this point.
Loading history...
713
714
        if ($type == CC_QUIZ_MULTIPLE_CHOICE) {
715
            $returnType['qtype'] = 'unique_answer';
716
        }
717
        if ($type == CC_QUIZ_MULTIPLE_RESPONSE) {
718
            $returnType['qtype'] = 'multiple_answer';
719
        }
720
721
        return $returnType;
722
    }
723
}
724