Completed
Push — master ( 6c6efe...024a20 )
by Julito
09:28
created

Answer::createAnswer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 10
nc 1
nop 8
dl 0
loc 20
rs 9.9332
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CourseBundle\Entity\CQuizAnswer;
6
7
/**
8
 * Class Answer
9
 * Allows to instantiate an object of type Answer
10
 * 5 arrays are created to receive the attributes of each answer belonging to a specified question.
11
 *
12
 * @author Olivier Brouckaert
13
 */
14
class Answer
15
{
16
    public $questionId;
17
18
    // these are arrays
19
    public $answer;
20
    public $correct;
21
    public $comment;
22
    public $weighting;
23
    public $position;
24
    public $hotspot_coordinates;
25
    public $hotspot_type;
26
    public $destination;
27
    // these arrays are used to save temporarily new answers
28
    // then they are moved into the arrays above or deleted in the event of cancellation
29
    public $new_answer;
30
    public $new_correct;
31
    public $new_comment;
32
    public $new_weighting;
33
    public $new_position;
34
    public $new_hotspot_coordinates;
35
    public $new_hotspot_type;
36
    public $autoId;
37
    /** @var int Number of answers in the question */
38
    public $nbrAnswers;
39
    public $new_nbrAnswers;
40
    public $new_destination; // id of the next question if feedback option is set to Directfeedback
41
    public $course; //Course information
42
    public $iid;
43
    public $questionJSId;
44
    public $standalone;
45
    /** @var Exercise|null */
46
    private $exercise;
47
48
    /**
49
     * constructor of the class.
50
     *
51
     * @author Olivier Brouckaert
52
     *
53
     * @param int      $questionId that answers belong to
54
     * @param int      $course_id
55
     * @param Exercise $exercise
56
     * @param bool     $readAnswer
57
     */
58
    public function __construct($questionId, $course_id = 0, $exercise = null, $readAnswer = true)
59
    {
60
        $this->questionId = (int) $questionId;
61
        $this->answer = [];
62
        $this->correct = [];
63
        $this->comment = [];
64
        $this->weighting = [];
65
        $this->position = [];
66
        $this->hotspot_coordinates = [];
67
        $this->hotspot_type = [];
68
        $this->destination = [];
69
        // clears $new_* arrays
70
        $this->cancel();
71
72
        if (!empty($course_id)) {
73
            $courseInfo = api_get_course_info_by_id($course_id);
74
        } else {
75
            $courseInfo = api_get_course_info();
76
        }
77
78
        $this->course = $courseInfo;
79
        $this->course_id = $courseInfo['real_id'];
80
81
        if (empty($exercise)) {
82
            // fills arrays
83
            $objExercise = new Exercise($this->course_id);
84
            $exerciseId = isset($_REQUEST['exerciseId']) ? $_REQUEST['exerciseId'] : null;
85
            $objExercise->read($exerciseId, false);
86
        } else {
87
            $objExercise = $exercise;
88
        }
89
        $this->exercise = $objExercise;
90
91
        if ($readAnswer) {
92
            if ('1' == $objExercise->random_answers && CALCULATED_ANSWER != $this->getQuestionType()) {
93
                $this->readOrderedBy('rand()', ''); // randomize answers
94
            } else {
95
                $this->read(); // natural order
96
            }
97
        }
98
    }
99
100
    /**
101
     * Clears $new_* arrays.
102
     *
103
     * @author Olivier Brouckaert
104
     */
105
    public function cancel()
106
    {
107
        $this->new_answer = [];
108
        $this->new_correct = [];
109
        $this->new_comment = [];
110
        $this->new_weighting = [];
111
        $this->new_position = [];
112
        $this->new_hotspot_coordinates = [];
113
        $this->new_hotspot_type = [];
114
        $this->new_nbrAnswers = 0;
115
        $this->new_destination = [];
116
    }
117
118
    /**
119
     * Reads answer information from the database.
120
     *
121
     * @author Olivier Brouckaert
122
     */
123
    public function read()
124
    {
125
        $table = Database::get_course_table(TABLE_QUIZ_ANSWER);
126
        $questionId = $this->questionId;
127
128
        $sql = "SELECT * FROM $table
129
                WHERE
130
                    c_id = {$this->course_id} AND
131
                    question_id ='".$questionId."'
132
                ORDER BY position";
133
134
        $result = Database::query($sql);
135
        $i = 1;
136
137
        // while a record is found
138
        while ($object = Database::fetch_object($result)) {
139
            $this->id[$i] = $object->id;
140
            $this->answer[$i] = $object->answer;
141
            $this->correct[$i] = $object->correct;
142
            $this->comment[$i] = $object->comment;
143
            $this->weighting[$i] = $object->ponderation;
144
            $this->position[$i] = $object->position;
145
            $this->hotspot_coordinates[$i] = $object->hotspot_coordinates;
146
            $this->hotspot_type[$i] = $object->hotspot_type;
147
            $this->destination[$i] = $object->destination;
148
            $this->autoId[$i] = $object->id_auto;
149
            $this->iid[$i] = $object->iid;
150
            $i++;
151
        }
152
        $this->nbrAnswers = $i - 1;
153
    }
154
155
    /**
156
     * Get answers already added to question.
157
     *
158
     * @return array
159
     */
160
    public function getAnswers()
161
    {
162
        $table = Database::get_course_table(TABLE_QUIZ_ANSWER);
163
        $questionId = $this->questionId;
164
165
        $sql = "SELECT * FROM $table
166
                WHERE c_id = {$this->course_id}
167
                    AND question_id = $questionId
168
                ORDER BY position";
169
170
        $result = Database::query($sql);
171
172
        $answers = [];
173
174
        // while a record is found
175
        while ($answer = Database::fetch_assoc($result)) {
176
            $answers[] = $answer;
177
        }
178
179
        return $answers;
180
    }
181
182
    /**
183
     * @param int $id
184
     *
185
     * @return array
186
     */
187
    public function getAnswerByAutoId($id)
188
    {
189
        foreach ($this->autoId as $key => $autoId) {
190
            if ($autoId == $id) {
191
                return [
192
                    'answer' => $this->answer[$key],
193
                    'correct' => $this->correct[$key],
194
                    'comment' => $this->comment[$key],
195
                ];
196
            }
197
        }
198
199
        return [];
200
    }
201
202
    /**
203
     * returns all answer ids from this question Id.
204
     *
205
     * @author Yoselyn Castillo
206
     *
207
     * @return array - $id (answer ids)
208
     */
209
    public function selectAnswerId()
210
    {
211
        $table = Database::get_course_table(TABLE_QUIZ_ANSWER);
212
        $questionId = $this->questionId;
213
214
        $sql = "SELECT id FROM
215
              $table
216
              WHERE c_id = {$this->course_id} AND question_id ='".$questionId."'";
217
218
        $result = Database::query($sql);
219
        $id = [];
220
        // while a record is found
221
        if (Database::num_rows($result) > 0) {
222
            while ($object = Database::fetch_array($result)) {
223
                $id[] = $object['id'];
224
            }
225
        }
226
227
        return $id;
228
    }
229
230
    /**
231
     * Reads answer information from the data base ordered by parameter.
232
     *
233
     * @param string $field Field we want to order by
234
     * @param string $order DESC or ASC
235
     *
236
     * @return bool
237
     *
238
     * @author Frederic Vauthier
239
     */
240
    public function readOrderedBy($field, $order = 'ASC')
241
    {
242
        $field = Database::escape_string($field);
243
        if (empty($field)) {
244
            $field = 'position';
245
        }
246
247
        if ('ASC' != $order && 'DESC' != $order) {
248
            $order = 'ASC';
249
        }
250
251
        $TBL_ANSWER = Database::get_course_table(TABLE_QUIZ_ANSWER);
252
        $TBL_QUIZ = Database::get_course_table(TABLE_QUIZ_QUESTION);
253
        $questionId = (int) $this->questionId;
254
255
        $sql = "SELECT type FROM $TBL_QUIZ
256
                WHERE c_id = {$this->course_id} AND id = $questionId";
257
        $result_question = Database::query($sql);
258
        $questionType = Database::fetch_array($result_question);
259
260
        if (DRAGGABLE == $questionType['type']) {
261
            // Random is done by submit.js.tpl
262
            $this->read();
263
264
            return true;
265
        }
266
267
        $sql = "SELECT
268
                    answer,
269
                    correct,
270
                    comment,
271
                    ponderation,
272
                    position,
273
                    hotspot_coordinates,
274
                    hotspot_type,
275
                    destination,
276
                    id_auto,
277
                    iid
278
                FROM $TBL_ANSWER
279
                WHERE
280
                    c_id = {$this->course_id} AND
281
                    question_id='".$questionId."'
282
                ORDER BY $field $order";
283
        $result = Database::query($sql);
284
285
        $i = 1;
286
        // while a record is found
287
        $doubt_data = null;
288
        while ($object = Database::fetch_object($result)) {
289
            if (UNIQUE_ANSWER_NO_OPTION == $questionType['type'] && 666 == $object->position) {
290
                $doubt_data = $object;
291
292
                continue;
293
            }
294
            $this->answer[$i] = $object->answer;
295
            $this->correct[$i] = $object->correct;
296
            $this->comment[$i] = $object->comment;
297
            $this->weighting[$i] = $object->ponderation;
298
            $this->position[$i] = $object->position;
299
            $this->hotspot_coordinates[$i] = $object->hotspot_coordinates;
300
            $this->hotspot_type[$i] = $object->hotspot_type;
301
            $this->destination[$i] = $object->destination;
302
            $this->autoId[$i] = $object->id_auto;
303
            $this->iid[$i] = $object->iid;
304
            $i++;
305
        }
306
307
        if (UNIQUE_ANSWER_NO_OPTION == $questionType['type'] && !empty($doubt_data)) {
308
            $this->answer[$i] = $doubt_data->answer;
309
            $this->correct[$i] = $doubt_data->correct;
310
            $this->comment[$i] = $doubt_data->comment;
311
            $this->weighting[$i] = $doubt_data->ponderation;
312
            $this->position[$i] = $doubt_data->position;
313
            $this->hotspot_coordinates[$i] = isset($object->hotspot_coordinates) ? $object->hotspot_coordinates : 0;
314
            $this->hotspot_type[$i] = isset($object->hotspot_type) ? $object->hotspot_type : 0;
315
            $this->destination[$i] = $doubt_data->destination;
316
            $this->autoId[$i] = $doubt_data->id_auto;
317
            $this->iid[$i] = $doubt_data->iid;
318
            $i++;
319
        }
320
        $this->nbrAnswers = $i - 1;
321
322
        return true;
323
    }
324
325
    /**
326
     * returns the autoincrement id.
327
     *
328
     * @author Juan Carlos Ra�a
329
     *
330
     * @return int - answer num
331
     */
332
    public function selectAutoId($id)
333
    {
334
        return isset($this->autoId[$id]) ? $this->autoId[$id] : 0;
335
    }
336
337
    /**
338
     * returns the number of answers in this question.
339
     *
340
     * @author Olivier Brouckaert
341
     *
342
     * @return int - number of answers
343
     */
344
    public function selectNbrAnswers()
345
    {
346
        return $this->nbrAnswers;
347
    }
348
349
    /**
350
     * returns the question ID which the answers belong to.
351
     *
352
     * @author Olivier Brouckaert
353
     *
354
     * @return int - the question ID
355
     */
356
    public function selectQuestionId()
357
    {
358
        return $this->questionId;
359
    }
360
361
    /**
362
     * returns the question ID of the destination question.
363
     *
364
     * @author Julio Montoya
365
     *
366
     * @param int $id
367
     *
368
     * @return int - the question ID
369
     */
370
    public function selectDestination($id)
371
    {
372
        return isset($this->destination[$id]) ? $this->destination[$id] : null;
373
    }
374
375
    /**
376
     * returns the answer title.
377
     *
378
     * @author Olivier Brouckaert
379
     *
380
     * @param - integer $id - answer ID
381
     *
382
     * @return string - answer title
383
     */
384
    public function selectAnswer($id)
385
    {
386
        return isset($this->answer[$id]) ? $this->answer[$id] : null;
387
    }
388
389
    /**
390
     * return array answer by id else return a bool.
391
     *
392
     * @param int $auto_id
393
     *
394
     * @return array
395
     */
396
    public function selectAnswerByAutoId($auto_id)
397
    {
398
        $table = Database::get_course_table(TABLE_QUIZ_ANSWER);
399
        $auto_id = (int) $auto_id;
400
        $sql = "SELECT id, answer, id_auto FROM $table
401
                WHERE c_id = {$this->course_id} AND id_auto='$auto_id'";
402
        $rs = Database::query($sql);
403
404
        if (Database::num_rows($rs) > 0) {
405
            return Database::fetch_array($rs, 'ASSOC');
406
        }
407
408
        return false;
409
    }
410
411
    /**
412
     * returns the answer title from an answer's position.
413
     *
414
     * @author Yannick Warnier
415
     *
416
     * @param - integer $pos - answer ID
417
     *
418
     * @return bool - answer title
419
     */
420
    public function selectAnswerIdByPosition($pos)
421
    {
422
        foreach ($this->position as $k => $v) {
423
            if ($v != $pos) {
424
                continue;
425
            }
426
427
            return $k;
428
        }
429
430
        return false;
431
    }
432
433
    /**
434
     * Returns a list of answers.
435
     *
436
     * @author Yannick Warnier <[email protected]>
437
     *
438
     * @param bool $decode
439
     *
440
     * @return array List of answers where each answer is an array
441
     *               of (id, answer, comment, grade) and grade=weighting
442
     */
443
    public function getAnswersList($decode = false)
444
    {
445
        $list = [];
446
        for ($i = 1; $i <= $this->nbrAnswers; $i++) {
447
            if (!empty($this->answer[$i])) {
448
                //Avoid problems when parsing elements with accents
449
                if ($decode) {
450
                    $this->answer[$i] = api_html_entity_decode(
451
                        $this->answer[$i],
452
                        ENT_QUOTES,
453
                        api_get_system_encoding()
454
                    );
455
                    $this->comment[$i] = api_html_entity_decode(
456
                        $this->comment[$i],
457
                        ENT_QUOTES,
458
                        api_get_system_encoding()
459
                    );
460
                }
461
462
                $list[] = [
463
                    'id' => $i,
464
                    'answer' => $this->answer[$i],
465
                    'comment' => $this->comment[$i],
466
                    'grade' => $this->weighting[$i],
467
                    'hotspot_coord' => $this->hotspot_coordinates[$i],
468
                    'hotspot_type' => $this->hotspot_type[$i],
469
                    'correct' => $this->correct[$i],
470
                    'destination' => $this->destination[$i],
471
                ];
472
            }
473
        }
474
475
        return $list;
476
    }
477
478
    /**
479
     * Returns a list of grades.
480
     *
481
     * @author Yannick Warnier <[email protected]>
482
     *
483
     * @return array List of grades where grade=weighting (?)
484
     */
485
    public function getGradesList()
486
    {
487
        $list = [];
488
        for ($i = 0; $i < $this->nbrAnswers; $i++) {
489
            if (!empty($this->answer[$i])) {
490
                $list[$i] = $this->weighting[$i];
491
            }
492
        }
493
494
        return $list;
495
    }
496
497
    /**
498
     * Returns the question type.
499
     *
500
     * @author    Yannick Warnier <[email protected]>
501
     *
502
     * @return int The type of the question this answer is bound to
503
     */
504
    public function getQuestionType()
505
    {
506
        $table = Database::get_course_table(TABLE_QUIZ_QUESTION);
507
        $sql = "SELECT type FROM $table
508
                WHERE c_id = {$this->course_id} AND id = '".$this->questionId."'";
509
        $res = Database::query($sql);
510
        if (Database::num_rows($res) <= 0) {
511
            return null;
512
        }
513
        $row = Database::fetch_array($res);
514
515
        return (int) $row['type'];
516
    }
517
518
    /**
519
     * tells if answer is correct or not.
520
     *
521
     * @author Olivier Brouckaert
522
     *
523
     * @param - integer $id - answer ID
524
     *
525
     * @return int - 0 if bad answer, not 0 if good answer
526
     */
527
    public function isCorrect($id)
528
    {
529
        return isset($this->correct[$id]) ? $this->correct[$id] : null;
530
    }
531
532
    /**
533
     * returns answer comment.
534
     *
535
     * @author Olivier Brouckaert
536
     *
537
     * @param - integer $id - answer ID
538
     *
539
     * @return string - answer comment
540
     */
541
    public function selectComment($id)
542
    {
543
        return isset($this->comment[$id]) ? $this->comment[$id] : null;
544
    }
545
546
    /**
547
     * returns answer weighting.
548
     *
549
     * @author Olivier Brouckaert
550
     *
551
     * @param - integer $id - answer ID
552
     *
553
     * @return int - answer weighting
554
     */
555
    public function selectWeighting($id)
556
    {
557
        return isset($this->weighting[$id]) ? $this->weighting[$id] : null;
558
    }
559
560
    /**
561
     * returns answer position.
562
     *
563
     * @author Olivier Brouckaert
564
     *
565
     * @param - integer $id - answer ID
566
     *
567
     * @return int - answer position
568
     */
569
    public function selectPosition($id)
570
    {
571
        return isset($this->position[$id]) ? $this->position[$id] : null;
572
    }
573
574
    /**
575
     * returns answer hotspot coordinates.
576
     *
577
     * @author Olivier Brouckaert
578
     *
579
     * @param int $id Answer ID
580
     *
581
     * @return int Answer position
582
     */
583
    public function selectHotspotCoordinates($id)
584
    {
585
        return isset($this->hotspot_coordinates[$id]) ? $this->hotspot_coordinates[$id] : null;
586
    }
587
588
    /**
589
     * returns answer hotspot type.
590
     *
591
     * @author Toon Keppens
592
     *
593
     * @param int $id Answer ID
594
     *
595
     * @return int Answer position
596
     */
597
    public function selectHotspotType($id)
598
    {
599
        return isset($this->hotspot_type[$id]) ? $this->hotspot_type[$id] : null;
600
    }
601
602
    /**
603
     * Creates a new answer.
604
     *
605
     * @author Olivier Brouckaert
606
     *
607
     * @param string $answer                  answer title
608
     * @param int    $correct                 0 if bad answer, not 0 if good answer
609
     * @param string $comment                 answer comment
610
     * @param int    $weighting               answer weighting
611
     * @param int    $position                answer position
612
     * @param array  $new_hotspot_coordinates Coordinates for hotspot exercises (optional)
613
     * @param int    $new_hotspot_type        Type for hotspot exercises (optional)
614
     * @param string $destination
615
     */
616
    public function createAnswer(
617
        $answer,
618
        $correct,
619
        $comment,
620
        $weighting,
621
        $position,
622
        $new_hotspot_coordinates = null,
623
        $new_hotspot_type = null,
624
        $destination = ''
625
    ) {
626
        $this->new_nbrAnswers++;
627
        $id = $this->new_nbrAnswers;
628
        $this->new_answer[$id] = $answer;
629
        $this->new_correct[$id] = $correct;
630
        $this->new_comment[$id] = $comment;
631
        $this->new_weighting[$id] = $weighting;
632
        $this->new_position[$id] = $position;
633
        $this->new_hotspot_coordinates[$id] = $new_hotspot_coordinates;
634
        $this->new_hotspot_type[$id] = $new_hotspot_type;
635
        $this->new_destination[$id] = $destination;
636
    }
637
638
    /**
639
     * Updates an answer.
640
     *
641
     * @author Toon Keppens
642
     *
643
     * @param int    $iid
644
     * @param string $answer
645
     * @param string $comment
646
     * @param string $correct
647
     * @param string $weighting
648
     * @param string $position
649
     * @param string $destination
650
     * @param string $hotSpotCoordinates
651
     * @param string $hotSpotType
652
     *
653
     * @return CQuizAnswer
654
     */
655
    public function updateAnswers(
656
        $iid,
657
        $answer,
658
        $comment,
659
        $correct,
660
        $weighting,
661
        $position,
662
        $destination,
663
        $hotSpotCoordinates,
664
        $hotSpotType
665
    ) {
666
        $em = Database::getManager();
667
668
        /** @var CQuizAnswer $quizAnswer */
669
        $quizAnswer = $em->find('ChamiloCourseBundle:CQuizAnswer', $iid);
670
        if ($quizAnswer) {
0 ignored issues
show
introduced by
$quizAnswer is of type Chamilo\CourseBundle\Entity\CQuizAnswer, thus it always evaluated to true.
Loading history...
671
            $quizAnswer
672
                ->setAnswer($answer)
673
                ->setComment($comment)
674
                ->setCorrect($correct)
675
                ->setPonderation($weighting)
676
                ->setPosition($position)
677
                ->setDestination($destination)
678
                ->setHotspotCoordinates($hotSpotCoordinates)
679
                ->setHotspotType($hotSpotType);
680
681
            $em->persist($quizAnswer);
682
            $em->flush();
683
684
            return $quizAnswer;
685
        }
686
687
        return false;
688
    }
689
690
    /**
691
     * Records answers into the data base.
692
     *
693
     * @author Olivier Brouckaert
694
     */
695
    public function save()
696
    {
697
        $answerTable = Database::get_course_table(TABLE_QUIZ_ANSWER);
698
        $em = Database::getManager();
699
        $questionId = (int) $this->questionId;
700
701
        $courseId = $this->course['real_id'];
702
        $answerList = [];
703
704
        for ($i = 1; $i <= $this->new_nbrAnswers; $i++) {
705
            $answer = $this->new_answer[$i];
706
            $correct = isset($this->new_correct[$i]) ? $this->new_correct[$i] : '';
707
            $comment = isset($this->new_comment[$i]) ? $this->new_comment[$i] : '';
708
            $weighting = isset($this->new_weighting[$i]) ? $this->new_weighting[$i] : '';
709
            $position = isset($this->new_position[$i]) ? $this->new_position[$i] : '';
710
            $hotspot_coordinates = isset($this->new_hotspot_coordinates[$i]) ? $this->new_hotspot_coordinates[$i] : '';
711
            $hotspot_type = isset($this->new_hotspot_type[$i]) ? $this->new_hotspot_type[$i] : '';
712
            $destination = isset($this->new_destination[$i]) ? $this->new_destination[$i] : '';
713
            $autoId = $this->selectAutoId($i);
714
            $iid = isset($this->iid[$i]) ? $this->iid[$i] : 0;
715
716
            if (!isset($this->position[$i])) {
717
                $quizAnswer = new CQuizAnswer();
718
                $quizAnswer
719
                    ->setIdAuto($autoId)
720
                    ->setCId($courseId)
721
                    ->setQuestionId($questionId)
722
                    ->setAnswer($answer)
723
                    ->setCorrect($correct)
724
                    ->setComment($comment)
725
                    ->setPonderation($weighting)
726
                    ->setPosition($position)
727
                    ->setHotspotCoordinates($hotspot_coordinates)
728
                    ->setHotspotType($hotspot_type)
729
                    ->setDestination($destination);
730
731
                $em->persist($quizAnswer);
732
                $em->flush();
733
734
                $iid = $quizAnswer->getIid();
735
736
                if ($iid) {
737
                    $quizAnswer
738
                        ->setId($iid)
739
                        ->setIdAuto($iid);
740
741
                    $questionType = $this->getQuestionType();
742
743
                    if (in_array(
744
                        $questionType,
745
                        [MATCHING, MATCHING_DRAGGABLE]
746
                    )) {
747
                        $answer = new self($this->questionId, $courseId, $this->exercise, false);
748
                        $answer->read();
749
                        $correctAnswerId = $answer->selectAnswerIdByPosition($correct);
750
751
                        // Continue to avoid matching question bug if $correctAnswerId returns false
752
                        // See : https://support.chamilo.org/issues/8334
753
                        if (MATCHING == $questionType && !$correctAnswerId) {
754
                            continue;
755
                        }
756
                        $correctAnswerAutoId = $answer->selectAutoId($correct);
757
                        $quizAnswer->setCorrect($correctAnswerAutoId ?: 0);
758
                    }
759
760
                    $em->persist($quizAnswer);
761
                    $em->flush();
762
                }
763
            } else {
764
                // https://support.chamilo.org/issues/6558
765
                // function updateAnswers already escape_string, error if we do it twice.
766
                // Feed function updateAnswers with none escaped strings
767
                $this->updateAnswers(
768
                    $iid,
769
                    $this->new_answer[$i],
770
                    $this->new_comment[$i],
771
                    $this->new_correct[$i],
772
                    $this->new_weighting[$i],
773
                    $this->new_position[$i],
774
                    $this->new_destination[$i],
775
                    $this->new_hotspot_coordinates[$i],
776
                    $this->new_hotspot_type[$i]
777
                );
778
            }
779
780
            $answerList[$i] = $iid;
781
        }
782
783
        $questionType = $this->getQuestionType();
784
785
        switch ($questionType) {
786
            case MATCHING_DRAGGABLE:
787
                foreach ($this->new_correct as $value => $status) {
788
                    if (!empty($status)) {
789
                        if (isset($answerList[$status])) {
790
                            $correct = $answerList[$status];
791
                        } else {
792
                            $correct = $status;
793
                        }
794
                        $myAutoId = $answerList[$value];
795
                        $sql = "UPDATE $answerTable
796
                            SET correct = '$correct'
797
                            WHERE
798
                                id_auto = $myAutoId
799
                            ";
800
                        Database::query($sql);
801
                    }
802
                }
803
804
                break;
805
            case DRAGGABLE:
806
                foreach ($this->new_correct as $value => $status) {
807
                    if (!empty($status)) {
808
                        $correct = $answerList[$status];
809
                        $myAutoId = $answerList[$value];
810
                        $sql = "UPDATE $answerTable
811
                            SET correct = '$correct'
812
                            WHERE
813
                                id_auto = $myAutoId
814
                            ";
815
                        Database::query($sql);
816
                    }
817
                }
818
819
                break;
820
        }
821
822
        if (count($this->position) > $this->new_nbrAnswers) {
823
            $i = $this->new_nbrAnswers + 1;
824
            while ($this->position[$i]) {
825
                $position = $this->position[$i];
826
                $sql = "DELETE FROM $answerTable
827
                        WHERE
828
                            c_id = {$this->course_id} AND
829
                            question_id = '".$questionId."' AND
830
                            position ='$position'";
831
                Database::query($sql);
832
                $i++;
833
            }
834
        }
835
836
        // moves $new_* arrays
837
        $this->answer = $this->new_answer;
838
        $this->correct = $this->new_correct;
839
        $this->comment = $this->new_comment;
840
        $this->weighting = $this->new_weighting;
841
        $this->position = $this->new_position;
842
        $this->hotspot_coordinates = $this->new_hotspot_coordinates;
843
        $this->hotspot_type = $this->new_hotspot_type;
844
        $this->nbrAnswers = $this->new_nbrAnswers;
845
        $this->destination = $this->new_destination;
846
847
        $this->cancel();
848
    }
849
850
    /**
851
     * Duplicates answers by copying them into another question.
852
     *
853
     * @author Olivier Brouckaert
854
     *
855
     * @param Question $newQuestion
856
     * @param array    $course_info destination course info (result of the function api_get_course_info() )
857
     */
858
    public function duplicate($newQuestion, $course_info = null)
859
    {
860
        $newQuestionId = $newQuestion->id;
861
862
        if (empty($course_info)) {
863
            $course_info = $this->course;
864
        }
865
866
        $fixed_list = [];
867
        $tableAnswer = Database::get_course_table(TABLE_QUIZ_ANSWER);
868
869
        if (MULTIPLE_ANSWER_TRUE_FALSE == self::getQuestionType() ||
870
            MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY == self::getQuestionType()
871
        ) {
872
            // Selecting origin options
873
            $origin_options = Question::readQuestionOption(
874
                $this->selectQuestionId(),
875
                $this->course['real_id']
876
            );
877
878
            if (!empty($origin_options)) {
879
                foreach ($origin_options as $item) {
880
                    $new_option_list[] = $item['id'];
881
                }
882
            }
883
884
            $destination_options = Question::readQuestionOption(
885
                $newQuestionId,
886
                $course_info['real_id']
887
            );
888
            $i = 0;
889
            if (!empty($destination_options)) {
890
                foreach ($destination_options as $item) {
891
                    $fixed_list[$new_option_list[$i]] = $item['id'];
892
                    $i++;
893
                }
894
            }
895
        }
896
897
        // if at least one answer
898
        if ($this->nbrAnswers) {
899
            // inserts new answers into data base
900
            $courseId = $course_info['real_id'];
901
            $correctAnswers = [];
902
            $onlyAnswers = [];
903
            $allAnswers = [];
904
905
            $em = Database::getManager();
906
907
            if (in_array($newQuestion->type, [MATCHING, MATCHING_DRAGGABLE])) {
908
                $temp = [];
909
                for ($i = 1; $i <= $this->nbrAnswers; $i++) {
910
                    $answer = [
911
                        'id' => $this->id[$i],
912
                        'answer' => $this->answer[$i],
913
                        'correct' => $this->correct[$i],
914
                        'comment' => $this->comment[$i],
915
                        'weighting' => $this->weighting[$i],
916
                        'ponderation' => $this->weighting[$i],
917
                        'position' => $this->position[$i],
918
                        'hotspot_coordinates' => $this->hotspot_coordinates[$i],
919
                        'hotspot_type' => $this->hotspot_type[$i],
920
                        'destination' => $this->destination[$i],
921
                    ];
922
                    $temp[$answer['position']] = $answer;
923
                    $allAnswers[$this->id[$i]] = $this->answer[$i];
924
                }
925
926
                foreach ($temp as $answer) {
927
                    if ($this->course['id'] != $course_info['id']) {
928
                        // check resources inside html from ckeditor tool and copy correct urls into recipient course
929
                        $answer['answer'] = DocumentManager::replaceUrlWithNewCourseCode(
930
                            $answer['answer'],
931
                            $this->course['id'],
932
                            $course_info['id']
933
                        );
934
935
                        $answer['comment'] = DocumentManager::replaceUrlWithNewCourseCode(
936
                            $answer['comment'],
937
                            $this->course['id'],
938
                            $course_info['id']
939
                        );
940
                    }
941
942
                    $quizAnswer = new CQuizAnswer();
943
                    $quizAnswer
944
                        ->setCId($courseId)
945
                        ->setQuestionId($newQuestionId)
946
                        ->setAnswer($answer['answer'])
947
                        ->setCorrect($answer['correct'])
948
                        ->setComment($answer['comment'])
949
                        ->setPonderation($answer['ponderation'])
950
                        ->setPosition($answer['position'])
951
                        ->setHotspotCoordinates($answer['hotspot_coordinates'])
952
                        ->setHotspotType($answer['hotspot_type'])
953
                        ->setIdAuto(0);
954
955
                    $em->persist($quizAnswer);
956
                    $em->flush();
957
958
                    $answerId = $quizAnswer->getIid();
959
960
                    if ($answerId) {
961
                        $quizAnswer
962
                            ->setId($answerId)
963
                            ->setIdAuto($answerId);
964
965
                        $em->persist($quizAnswer);
966
                        $em->flush();
967
968
                        $correctAnswers[$answerId] = $answer['correct'];
969
                        $onlyAnswers[$answerId] = $answer['answer'];
970
                    }
971
                }
972
            } else {
973
                for ($i = 1; $i <= $this->nbrAnswers; $i++) {
974
                    if ($this->course['id'] != $course_info['id']) {
975
                        $this->answer[$i] = DocumentManager::replaceUrlWithNewCourseCode(
976
                            $this->answer[$i],
977
                            $this->course['id'],
978
                            $course_info['id']
979
                        );
980
                        $this->comment[$i] = DocumentManager::replaceUrlWithNewCourseCode(
981
                            $this->comment[$i],
982
                            $this->course['id'],
983
                            $course_info['id']
984
                        );
985
                    }
986
987
                    $correct = $this->correct[$i];
988
                    if (MULTIPLE_ANSWER_TRUE_FALSE == $newQuestion->type ||
989
                        MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY == $newQuestion->type
990
                    ) {
991
                        $correct = $fixed_list[(int) $correct];
992
                    }
993
994
                    $quizAnswer = new CQuizAnswer();
995
                    $quizAnswer
996
                        ->setCId($courseId)
997
                        ->setQuestionId($newQuestionId)
998
                        ->setAnswer($this->answer[$i])
999
                        ->setCorrect($correct)
1000
                        ->setComment($this->comment[$i])
1001
                        ->setPonderation($this->weighting[$i])
1002
                        ->setPosition($this->position[$i])
1003
                        ->setHotspotCoordinates($this->hotspot_coordinates[$i])
1004
                        ->setHotspotType($this->hotspot_type[$i])
1005
                        ->setDestination($this->destination[$i]);
1006
1007
                    $em->persist($quizAnswer);
1008
                    $em->flush();
1009
1010
                    $answerId = $quizAnswer->getIid();
1011
                    $quizAnswer
1012
                        ->setId($answerId)
1013
                        ->setIdAuto($answerId);
1014
1015
                    $em->persist($quizAnswer);
1016
                    $em->flush();
1017
1018
                    $correctAnswers[$answerId] = $correct;
1019
                    $onlyAnswers[$answerId] = $this->answer[$i];
1020
                    $allAnswers[$this->id[$i]] = $this->answer[$i];
1021
                }
1022
            }
1023
1024
            // Fix correct answers
1025
            if (in_array($newQuestion->type, [DRAGGABLE, MATCHING, MATCHING_DRAGGABLE])) {
1026
                $onlyAnswersFlip = array_flip($onlyAnswers);
1027
                foreach ($correctAnswers as $answer_id => $correct_answer) {
1028
                    $params = [];
1029
                    if (isset($allAnswers[$correct_answer]) &&
1030
                        isset($onlyAnswersFlip[$allAnswers[$correct_answer]])
1031
                    ) {
1032
                        $params['correct'] = $onlyAnswersFlip[$allAnswers[$correct_answer]];
1033
                        Database::update(
1034
                            $tableAnswer,
1035
                            $params,
1036
                            [
1037
                                'id = ? AND c_id = ? AND question_id = ? ' => [
1038
                                    $answer_id,
1039
                                    $courseId,
1040
                                    $newQuestionId,
1041
                                ],
1042
                            ]
1043
                        );
1044
                    }
1045
                }
1046
            }
1047
        }
1048
    }
1049
1050
    /**
1051
     * Get the necessary JavaScript for some answers.
1052
     *
1053
     * @return string
1054
     */
1055
    public function getJs()
1056
    {
1057
        return "<script>
1058
                $(window).on('load', function() {
1059
                    jsPlumb.ready(function() {
1060
                        if ($('#drag{$this->questionId}_question').length > 0) {
1061
                            MatchingDraggable.init('{$this->questionId}');
1062
                        }
1063
                    });
1064
                });
1065
            </script>";
1066
    }
1067
1068
    /**
1069
     * Check if a answer is correct by an answer auto id.
1070
     *
1071
     * @param int $needle The answer auto id
1072
     *
1073
     * @return bool
1074
     */
1075
    public function isCorrectByAutoId($needle)
1076
    {
1077
        $key = 0;
1078
        if (is_array($this->autoId)) {
1079
            foreach ($this->autoId as $autoIdKey => $autoId) {
1080
                if ($autoId == $needle) {
1081
                    $key = $autoIdKey;
1082
                }
1083
            }
1084
        }
1085
1086
        if (!$key) {
1087
            return false;
1088
        }
1089
1090
        return $this->isCorrect($key) ? true : false;
1091
    }
1092
}
1093