Passed
Pull Request — 1.11.x (#7042)
by
unknown
11:02
created

getNbrQuestions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 4
c 1
b 0
f 1
dl 0
loc 9
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\ExtraField as ExtraFieldEntity;
6
use ChamiloSession as Session;
7
use Knp\Component\Pager\Paginator;
8
use Twig\Cache\NullCache;
9
10
/**
11
 * Extended Question Pool
12
 * This script adds some extra features to the original question pool.
13
 * One question can be in several exercises.
14
 *
15
 * @author Olivier Brouckaert
16
 * @author Julio Montoya adding support to query all questions from all session, courses, exercises
17
 * @author Modify by hubert borderiou 2011-10-21 Question's category
18
 * @author Modify by Nosolored 2025-10-20 (extended features)
19
 */
20
require_once __DIR__.'/../inc/global.inc.php';
21
22
api_protect_course_script(true);
23
24
$this_section = SECTION_COURSES;
25
26
$is_allowedToEdit = api_is_allowed_to_edit(null, true);
27
28
$extended = api_get_plugin_setting('extendedquestionpool', 'enable_plugin');
29
30
if ($extended != 'true') {
31
    $query = $_SERVER['QUERY_STRING'] ?? '';
32
    $urlDest = 'question_pool.php';
33
34
    if (!empty($query)) {
35
        $urlDest .= '?' . $query;
36
    }
37
    header('Location: ' . $urlDest);
38
    exit;
39
}
40
require_once api_get_path(SYS_PLUGIN_PATH).'extendedquestionpool/src/extendedquestionpool_plugin.class.php';
41
require_once api_get_path(SYS_PLUGIN_PATH).'extendedquestionpool/src/extendedquestionpool.lib.php';
42
$extendedQuestionPoolPlugin = ExtendedQuestionPoolPlugin::create();
43
44
$delete = isset($_GET['delete']) ? (int) $_GET['delete'] : null;
45
$recup = isset($_GET['recup']) ? (int) $_GET['recup'] : null;
46
$fromExercise = isset($_REQUEST['fromExercise']) ? (int) $_REQUEST['fromExercise'] : null;
47
$exerciseId = isset($_REQUEST['exerciseId']) ? (int) $_REQUEST['exerciseId'] : null;
48
$courseCategoryId = isset($_REQUEST['courseCategoryId']) ? (int) $_REQUEST['courseCategoryId'] : null;
49
$exerciseLevel = isset($_REQUEST['exerciseLevel']) ? (int) $_REQUEST['exerciseLevel'] : -1;
50
$answerType = isset($_REQUEST['answerType']) ? (int) $_REQUEST['answerType'] : null;
51
$question_copy = isset($_REQUEST['question_copy']) ? (int) $_REQUEST['question_copy'] : 0;
52
$session_id = isset($_REQUEST['session_id']) ? (int) $_REQUEST['session_id'] : null;
53
$selected_course = isset($_GET['selected_course']) ? (int) $_GET['selected_course'] : null;
54
// save the id of the previous course selected by user to reset menu if we detect that user change course hub 13-10-2011
55
$course_id_changed = isset($_GET['course_id_changed']) ? (int) $_GET['course_id_changed'] : null;
56
// save the id of the previous exercise selected by user to reset menu if we detect that user change course hub 13-10-2011
57
$exercise_id_changed = isset($_GET['exercise_id_changed']) ? (int) $_GET['exercise_id_changed'] : null;
58
$questionId = isset($_GET['question_id']) && !empty($_GET['question_id']) ? (int) $_GET['question_id'] : '';
59
$description = isset($_GET['description']) ? Database::escape_string($_GET['description']) : '';
60
$page = isset($_GET['page']) ? (int) $_GET['page'] : 1;
61
62
// by default when we go to the page for the first time, we select the current course
63
if (!isset($_GET['selected_course']) && !isset($_GET['exerciseId'])) {
64
    $selected_course = api_get_course_int_id();
65
}
66
67
$_course = api_get_course_info();
68
$objExercise = new Exercise();
69
if (!empty($fromExercise)) {
70
    $objExercise->read($fromExercise, false);
71
}
72
73
$nameTools = get_lang('QuestionPool');
74
$interbreadcrumb[] = ['url' => 'exercise.php?'.api_get_cidreq(), 'name' => get_lang('Exercises')];
75
76
if (!empty($objExercise->iid)) {
77
    $interbreadcrumb[] = [
78
        'url' => 'admin.php?exerciseId='.$objExercise->iid.'&'.api_get_cidreq(),
79
        'name' => $objExercise->selectTitle(true),
80
    ];
81
}
82
83
// message to be displayed if actions successful
84
$displayMessage = '';
85
if ($is_allowedToEdit) {
86
    // Duplicating a Question
87
    if (!isset($_POST['recup']) && $question_copy != 0 && isset($fromExercise)) {
88
        $origin_course_id = (int) $_GET['course_id'];
89
        $origin_course_info = api_get_course_info_by_id($origin_course_id);
90
        $current_course = api_get_course_info();
91
        $old_question_id = $question_copy;
92
        // Reading the source question
93
        $old_question_obj = Question::read($old_question_id, $origin_course_info);
94
        $courseId = $current_course['real_id'];
95
        if ($old_question_obj) {
96
            $old_question_obj->updateTitle($old_question_obj->selectTitle().' - '.get_lang('Copy'));
97
            //Duplicating the source question, in the current course
98
            $new_id = $old_question_obj->duplicate($current_course);
99
            //Reading new question
100
            $new_question_obj = Question::read($new_id);
101
            $new_question_obj->addToList($fromExercise);
102
            //Reading Answers obj of the current course
103
            $new_answer_obj = new Answer($old_question_id, $origin_course_id);
104
            $new_answer_obj->read();
105
            //Duplicating the Answers in the current course
106
            $new_answer_obj->duplicate($new_question_obj, $current_course);
107
            // destruction of the Question object
108
            unset($new_question_obj);
109
            unset($old_question_obj);
110
111
            $objExercise = new Exercise($courseId);
112
            $objExercise->read($fromExercise);
113
            Session::write('objExercise', $objExercise);
114
        }
115
                    
116
        $nQuestions = $objExercise->getQuestionCount();
117
        $displayMessage = get_lang('ItemAdded').' ('.$nQuestions.' '.get_lang('Questions').')';
118
        
119
    }
120
121
    // Deletes a question from the database and all exercises
122
    if ($delete) {
123
        $limitTeacherAccess = api_get_configuration_value('limit_exercise_teacher_access');
124
        if ($limitTeacherAccess && !api_is_platform_admin()) {
125
            api_not_allowed(true);
126
        }
127
        // Construction of the Question object
128
        $objQuestionTmp = isQuestionInActiveQuiz($delete) ? false : Question::read($delete);
129
        // if the question exists
130
        if ($objQuestionTmp) {
131
            // deletes the question from all exercises
132
            $objQuestionTmp->delete();
133
134
            // solving the error that when deleting a question from the question pool it is not displaying all questions
135
            $exerciseId = null;
136
        }
137
        // destruction of the Question object
138
        unset($objQuestionTmp);
139
    } elseif ($recup && $fromExercise) {
140
        // gets an existing question and copies it into a new exercise
141
        $objQuestionTmp = Question::read($recup);
142
        // if the question exists
143
        if ($objQuestionTmp) {
144
            /* Adds the exercise ID represented by $fromExercise into the list
145
            of exercises for the current question */
146
            $objQuestionTmp->addToList($fromExercise);
147
        }
148
        // destruction of the Question object
149
        unset($objQuestionTmp);
150
151
        if (!$objExercise instanceof Exercise) {
152
            $objExercise = new Exercise();
153
            $objExercise->read($fromExercise);
154
        }
155
        // Adds the question ID represented by $recup into the list of questions for the current exercise
156
        $objExercise->addToList($recup);
157
        Session::write('objExercise', $objExercise);
158
        $nQuestions = $objExercise->getQuestionCount();
159
        //Display::addFlash(Display::return_message(get_lang('ItemAdded'), 'success'));
160
        Display::addFlash(Display::return_message(get_lang('ItemAdded').' ('.$nQuestions.' '.get_lang('Questions').')', 'success'));
161
    } elseif (isset($_POST['recup']) && is_array($_POST['recup']) && $fromExercise) {
162
        $list_recup = $_POST['recup'];
163
        foreach ($list_recup as $course_id => $question_data) {
164
            $origin_course_id = (int) $course_id;
165
            $origin_course_info = api_get_course_info_by_id($origin_course_id);
166
            $current_course = api_get_course_info();
167
            foreach ($question_data as $old_question_id) {
168
                // Reading the source question
169
                $old_question_obj = Question::read($old_question_id, $origin_course_info);
170
                if ($old_question_obj) {
171
                    $old_question_obj->updateTitle(
172
                        $old_question_obj->selectTitle().' - '.get_lang('Copy')
173
                    );
174
175
                    // Duplicating the source question, in the current course
176
                    $new_id = $old_question_obj->duplicate($current_course);
177
178
                    // Reading new question
179
                    $new_question_obj = Question::read($new_id);
180
                    $new_question_obj->addToList($fromExercise);
181
182
                    //Reading Answers obj of the current course
183
                    $new_answer_obj = new Answer($old_question_id, $origin_course_id);
184
                    $new_answer_obj->read();
185
186
                    //Duplicating the Answers in the current course
187
                    $new_answer_obj->duplicate($new_question_obj, $current_course);
188
189
                    // destruction of the Question object
190
                    unset($new_question_obj);
191
                    unset($old_question_obj);
192
193
                    if (!$objExercise instanceof Exercise) {
194
                        $objExercise = new Exercise();
195
                        $objExercise->read($fromExercise);
196
                    }
197
                }
198
            }
199
        }
200
        Session::write('objExercise', $objExercise);
201
        $nQuestions = $objExercise->getQuestionCount();
202
        Display::addFlash(Display::return_message(get_lang('Done').' ('.$nQuestions.' '.get_lang('Questions').')', 'success'));
203
    }
204
}
205
206
if (api_is_in_gradebook()) {
207
    $interbreadcrumb[] = [
208
        'url' => Category::getUrl(),
209
        'name' => get_lang('ToolGradebook'),
210
    ];
211
}
212
213
// if admin of course
214
if (!$is_allowedToEdit) {
215
    api_not_allowed(true);
216
}
217
218
$confirmYourChoice = addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES, $charset));
219
$htmlHeadXtra[] = "
220
<script>
221
    function submit_form(obj) {
222
        document.question_pool.submit();
223
    }
224
225
    function mark_course_id_changed() {
226
        $('#course_id_changed').val('1');
227
    }
228
229
    function mark_exercise_id_changed() {
230
        $('#exercise_id_changed').val('1');
231
    }
232
233
    function confirm_your_choice(confirmMessage) {
234
        return confirm(confirmMessage);
235
    }
236
</script>";
237
238
$url = api_get_self().'?'.api_get_cidreq().'&'.http_build_query(
239
    [
240
        'fromExercise' => $fromExercise,
241
        'session_id' => $session_id,
242
        'selected_course' => $selected_course,
243
        'courseCategoryId' => $courseCategoryId,
244
        'exerciseId' => $exerciseId,
245
        'exerciseLevel' => $exerciseLevel,
246
        'answerType' => $answerType,
247
        'question_id' => $questionId,
248
        'description' => Security::remove_XSS($description),
249
        'course_id_changed' => $course_id_changed,
250
        'exercise_id_changed' => $exercise_id_changed,
251
    ]
252
);
253
254
if (isset($_REQUEST['action'])) {
255
    switch ($_REQUEST['action']) {
256
        case 'score':
257
            if (!empty($_REQUEST['questions'])) {
258
                $txtError = '';
259
                $questions = $_REQUEST['questions'];
260
                $correctScore = api_get_plugin_setting('extendedquestionpool', 'correct_score');
261
                $errorScore = api_get_plugin_setting('extendedquestionpool', 'error_score');
262
                if (!is_numeric($correctScore) || $correctScore<=0) {
263
                    Display::addFlash(Display::return_message('Debe definir correctamente las puntuaciones en la configuración del plugin', 'error'));
264
                } elseif (!empty($errorScore) && !is_numeric($errorScore)) {
265
                    Display::addFlash(Display::return_message('Debe definir correctamente las puntuaciones en la configuración del plugin', 'error'));
266
                } elseif (count($questions) > 0) {
267
                    foreach ($questions as $questionId) {
268
                        $objQuestionTmp = Question::read($questionId);
269
                        if ($objQuestionTmp) {
270
                            if ($objQuestionTmp->selectType()==UNIQUE_ANSWER) {
271
                                $table = Database::get_course_table(TABLE_QUIZ_ANSWER);
272
                                $query1 = "UPDATE $table SET ponderation = $correctScore
273
                                    WHERE question_id=$questionId AND correct = 1";
274
                                $query2 = "UPDATE $table SET ponderation = $errorScore
275
                                    WHERE question_id=$questionId AND correct = 0";
276
                                $tableQ = Database::get_course_table(TABLE_QUIZ_QUESTION);
277
                                $query3 = "UPDATE $tableQ SET ponderation = $correctScore
278
                                    WHERE iid=$questionId";
279
                                Database::query($query1);
280
                                Database::query($query2);
281
                                Database::query($query3);
282
                            }
283
                        }
284
                    }
285
                }
286
                header('Location: '.$url);
287
                exit;
288
            }
289
            break;
290
        case 'reuse':
291
            if (!empty($_REQUEST['questions']) && !empty($fromExercise)) {
292
                $questions = $_REQUEST['questions'];
293
                $objExercise = new Exercise();
294
                $objExercise->read($fromExercise, false);
295
296
                if (count($questions) > 0) {
297
                    foreach ($questions as $questionId) {
298
                        // gets an existing question and copies it into a new exercise
299
                        $objQuestionTmp = Question::read($questionId);
300
                        // if the question exists
301
                        if ($objQuestionTmp) {
302
                            if (false === $objExercise->hasQuestion($questionId)) {
303
                                $objExercise->addToList($questionId);
304
                                $objQuestionTmp->addToList($fromExercise);
305
                            }
306
                        }
307
                    }
308
                }
309
                
310
                $nQuestions = $objExercise->getQuestionCount();
311
                Display::addFlash(Display::return_message(get_lang('Added').' ('.$nQuestions.' '.get_lang('Questions').')', 'success'));
312
                
313
                header('Location: '.$url);
314
                exit;
315
            }
316
            break;
317
        case 'clone':
318
            if (!empty($_REQUEST['questions']) && !empty($fromExercise)) {
319
                $questions = $_REQUEST['questions'];
320
                $origin_course_id = (int) $_GET['course_id'];
321
322
                $origin_course_info = api_get_course_info_by_id($origin_course_id);
323
                $current_course = api_get_course_info();
324
325
                if (count($questions) > 0) {
326
                    foreach ($questions as $questionId) {
327
                        // gets an existing question and copies it into a new exercise
328
                        // Reading the source question
329
                        $old_question_obj = Question::read($questionId, $origin_course_info);
330
                        $courseId = $current_course['real_id'];
331
                        if ($old_question_obj) {
332
                            $old_question_obj->updateTitle($old_question_obj->selectTitle().' - '.get_lang('Copy'));
333
                            // Duplicating the source question, in the current course
334
                            $new_id = $old_question_obj->duplicate($current_course);
335
                            // Reading new question
336
                            $new_question_obj = Question::read($new_id);
337
                            $new_question_obj->addToList($fromExercise);
338
                            //Reading Answers obj of the current course
339
                            $new_answer_obj = new Answer($questionId, $origin_course_id);
340
                            $new_answer_obj->read();
341
                            //Duplicating the Answers in the current course
342
                            $new_answer_obj->duplicate($new_question_obj, $current_course);
343
                            // destruction of the Question object
344
                            unset($new_question_obj);
345
                            unset($old_question_obj);
346
                        }
347
                    }
348
                }
349
350
                Display::addFlash(Display::return_message(get_lang('Added')));
351
                header('Location: '.$url);
352
                exit;
353
            }
354
            break;
355
    }
356
}
357
358
Display::display_header($nameTools, 'Exercise');
359
360
// Menu
361
echo '<div class="actions">';
362
if (isset($fromExercise) && $fromExercise > 0) {
363
    echo '<a href="admin.php?'.api_get_cidreq().'&exerciseId='.$fromExercise.'">'.
364
            Display::return_icon('back.png', get_lang('GoBackToQuestionList'), '', ICON_SIZE_MEDIUM).'</a>';
365
    $titleAdd = get_lang('AddQuestionToTest');
366
} else {
367
    echo '<a href="exercise.php?'.api_get_cidreq().'">'.
368
        Display::return_icon('back.png', get_lang('BackToExercisesList'), '', ICON_SIZE_MEDIUM).'</a>';
369
    echo "<a href='question_create.php?".api_get_cidreq()."'>".
370
        Display::return_icon('add_question.gif', get_lang('NewQu'), '', ICON_SIZE_MEDIUM).'</a>';
371
    $titleAdd = get_lang('ManageAllQuestions');
372
}
373
echo '</div>';
374
375
if ('' != $displayMessage) {
376
    echo Display::return_message($displayMessage, 'confirm');
377
}
378
379
// Session list, if sessions are used.
380
$sessionList = SessionManager::get_sessions_by_user(api_get_user_id(), api_is_platform_admin());
381
$session_select_list = ['-1' => get_lang('Select')];
382
foreach ($sessionList as $item) {
383
    $session_select_list[$item['session_id']] = $item['session_name'];
384
}
385
386
// Course list, get course list of session, or for course where user is admin
387
$course_list = [];
388
389
// Course list, get course list of session, or for course where user is admin
390
if (!empty($session_id) && $session_id != '-1' && !empty($sessionList)) {
391
    $sessionInfo = [];
392
    foreach ($sessionList as $session) {
393
        if ($session['session_id'] == $session_id) {
394
            $sessionInfo = $session;
395
        }
396
    }
397
    $course_list = $sessionInfo['courses'];
398
} else {
399
    if (api_is_platform_admin()) {
400
        $course_list = CourseManager::get_courses_list(0, 0, 'title');
401
    } else {
402
        $course_list = CourseManager::get_course_list_of_user_as_course_admin(api_get_user_id());
403
    }
404
405
    // Admin fix, add the current course in the question pool.
406
    if (api_is_platform_admin()) {
407
        $courseInfo = api_get_course_info();
408
        if (!empty($course_list)) {
409
            if (!in_array($courseInfo['real_id'], $course_list)) {
410
                $course_list = array_merge($course_list, [$courseInfo]);
411
            }
412
        } else {
413
            $course_list = [$courseInfo];
414
        }
415
    }
416
}
417
418
$course_select_list = ['-1' => get_lang('Select')];
419
foreach ($course_list as $item) {
420
    $courseItemId = $item['real_id'];
421
    $courseInfo = api_get_course_info_by_id($courseItemId);
422
    $course_select_list[$courseItemId] = '';
423
    if ($courseItemId == api_get_course_int_id()) {
424
        $course_select_list[$courseItemId] = '>&nbsp;&nbsp;&nbsp;&nbsp;';
425
    }
426
    $course_select_list[$courseItemId] .= $courseInfo['title'];
427
}
428
429
if (empty($selected_course) || $selected_course == '-1') {
430
    $course_info = api_get_course_info();
431
    // no course selected, reset menu test / difficult� / type de reponse
432
    reset_menu_exo_lvl_type();
433
} else {
434
    $course_info = api_get_course_info_by_id($selected_course);
435
}
436
// If course has changed, reset the menu default
437
if ($course_id_changed) {
438
    reset_menu_exo_lvl_type();
439
}
440
441
// Get category list for the course $selected_course
442
$categoryList = TestCategory::getCategoriesIdAndName($selected_course);
443
444
// Get exercise list for this course
445
$exercise_list = ExerciseLib::get_all_exercises_for_course_id(
446
    $course_info,
447
    $session_id,
448
    $selected_course,
449
    false
450
);
451
452
if (1 == $exercise_id_changed) {
453
    reset_menu_lvl_type();
454
}
455
456
// Exercise List
457
$my_exercise_list = [];
458
$my_exercise_list['0'] = get_lang('AllExercises');
459
$my_exercise_list['-1'] = get_lang('OrphanQuestions');
460
$titleSavedAsHtml = api_get_configuration_value('save_titles_as_html');
461
if (is_array($exercise_list)) {
462
    foreach ($exercise_list as $row) {
463
        $my_exercise_list[$row['iid']] = '';
464
        if ($row['iid'] == $fromExercise && $selected_course == api_get_course_int_id()) {
465
            $my_exercise_list[$row['iid']] = ">&nbsp;&nbsp;&nbsp;&nbsp;";
466
        }
467
468
        $exerciseTitle = $row['title'];
469
        if ($titleSavedAsHtml) {
470
            $exerciseTitle = strip_tags(api_html_entity_decode(trim($exerciseTitle)));
471
        }
472
        $my_exercise_list[$row['iid']] .= $exerciseTitle;
473
    }
474
}
475
476
// Difficulty list (only from 0 to 5)
477
$levels = [
478
    -1 => get_lang('All'),
479
    0 => 0,
480
    1 => 1,
481
    2 => 2,
482
    3 => 3,
483
    4 => 4,
484
    5 => 5,
485
];
486
487
// Answer type
488
$question_list = Question::getQuestionTypeList();
489
490
$new_question_list = [];
491
$new_question_list['-1'] = get_lang('All');
492
if (!empty($_course)) {
493
    foreach ($question_list as $key => $item) {
494
        if (in_array(
495
            $objExercise->getFeedbackType(),
496
            [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP]
497
        )) {
498
            if (!in_array($key, [HOT_SPOT_DELINEATION, UNIQUE_ANSWER])) {
499
                continue;
500
            }
501
            $new_question_list[$key] = get_lang($item[1]);
502
        } else {
503
            if (HOT_SPOT_DELINEATION == $key) {
504
                continue;
505
            }
506
            $new_question_list[$key] = get_lang($item[1]);
507
        }
508
    }
509
}
510
511
// Form
512
$form = new FormValidator('question_pool', 'GET', $url);
513
$form->addHeader($nameTools.' - '.$titleAdd);
514
$form->addHidden('fromExercise', $fromExercise);
515
$form
516
    ->addSelect(
517
        'session_id',
518
        get_lang('Session'),
519
        $session_select_list,
520
        ['onchange' => 'submit_form(this)', 'id' => 'session_id']
521
    )
522
    ->setSelected($session_id);
523
$form
524
    ->addSelect(
525
        'selected_course',
526
        get_lang('Course'),
527
        $course_select_list,
528
        ['onchange' => 'mark_course_id_changed(); submit_form(this);', 'id' => 'selected_course']
529
    )
530
    ->setSelected($selected_course);
531
$form
532
    ->addSelect(
533
        'courseCategoryId',
534
        get_lang('QuestionCategory'),
535
        $categoryList,
536
        ['onchange' => 'submit_form(this);', 'id' => 'courseCategoryId']
537
    )
538
    ->setSelected($courseCategoryId);
539
$form
540
    ->addSelect(
541
        'exerciseId',
542
        get_lang('Exercise'),
543
        $my_exercise_list,
544
        ['onchange' => 'mark_exercise_id_changed(); submit_form(this);', 'id' => 'exerciseId']
545
    )
546
    ->setSelected($exerciseId);
547
$form
548
    ->addSelect(
549
        'exerciseLevel',
550
        get_lang('Difficulty'),
551
        $levels,
552
        ['onchange' => 'submit_form(this);', 'id' => 'exerciseLevel']
553
    )
554
    ->setSelected($exerciseLevel);
555
$form
556
    ->addSelect(
557
        'answerType',
558
        get_lang('AnswerType'),
559
        $new_question_list,
560
        ['onchange' => 'submit_form(this);', 'id' => 'answerType']
561
    )
562
    ->setSelected($answerType);
563
$form
564
    ->addText('question_id', get_lang('Id'), false)
565
    ->setValue($questionId);
566
$form
567
    ->addText('description', get_lang('Description'), false)
568
    ->setValue(Security::remove_XSS($description));
569
570
$form->addHidden('course_id_changed', '0');
571
$form->addHidden('exercise_id_changed', '0');
572
573
$extraField = new ExtraField('question');
574
575
$jsForExtraFields = $extraField->addElements($form, 0, [], true);
576
577
$form->addButtonFilter(get_lang('Filter'), 'name');
578
579
echo $form->display();
580
581
echo '<script>$(function () {
582
        '.$jsForExtraFields['jquery_ready_content'].'
583
    })</script>';
584
?>
585
<div class="clear"></div>
586
<?php
587
$formValues = $form->validate() ? $form->exportValues() : [];
588
/**
589
 * @return array
590
 */
591
function getExtraFieldConditions(array $formValues, $queryType = 'from')
592
{
593
    $extraField = new ExtraField('question');
594
    $fields = $extraField->get_all(
595
        ['visible_to_self = ? AND filter = ?' => [1, 1]],
596
        'display_text'
597
    );
598
599
    $from = '';
600
    $where = '';
601
602
    foreach ($fields as $field) {
603
        $variable = $field['variable'];
604
605
        if (empty($formValues["extra_$variable"])) {
606
            continue;
607
        }
608
609
        $value = $formValues["extra_$variable"];
610
611
        switch ($field['field_type']) {
612
            case ExtraField::FIELD_TYPE_CHECKBOX:
613
                $value = $value["extra_$variable"];
614
                break;
615
            case ExtraField::FIELD_TYPE_DOUBLE_SELECT:
616
                if (!isset($value["extra_{$variable}_second"])) {
617
                    $value = null;
618
                    break;
619
                }
620
621
                $value = $value["extra_$variable"].'::'.$value["extra_{$variable}_second"];
622
                break;
623
        }
624
625
        if (empty($value)) {
626
            continue;
627
        }
628
629
        if ($queryType === 'from') {
630
            $from .= ", extra_field_values efv_$variable, extra_field ef_$variable";
631
            $where .= "AND (
632
                    qu.iid = efv_$variable.item_id
633
                    AND efv_$variable.field_id = ef_$variable.id
634
                    AND ef_$variable.extra_field_type = ".ExtraFieldEntity::QUESTION_FIELD_TYPE."
635
                    AND ef_$variable.variable = '$variable'
636
                    AND efv_$variable.value = '$value'
637
                )";
638
        } elseif ($queryType === 'join') {
639
            $from .= " INNER JOIN extra_field_values efv_$variable ON qu.iid = efv_$variable.item_id
640
                INNER JOIN extra_field ef_$variable ON efv_$variable.field_id = ef_$variable.id";
641
            $where .= "AND (
642
                    ef_$variable.extra_field_type = ".ExtraFieldEntity::QUESTION_FIELD_TYPE."
643
                    AND ef_$variable.variable = '$variable'
644
                    AND efv_$variable.value = '$value'
645
                )";
646
        }
647
    }
648
649
    return [
650
        'from' => $from,
651
        'where' => $where,
652
    ];
653
}
654
/**
655
 * get question list for sortable table
656
 */
657
function getQuestions($from, $number_of_items, $column, $direction, $getCount = false) {
658
    $start = (int) $from;
659
    $length = (int) $number_of_items;
660
    if (empty($length)) {
661
        $length = 20;
662
    }
663
    global $exerciseId,
664
            $courseCategoryId,
665
            $selected_course,
666
            $session_id,
667
            $exerciseLevel,
668
            $answerType,
669
            $questionId,
670
            $description,
671
            $fromExercise,
672
            $formValues,
673
            $objExercise,
674
            $actionIcon1,
675
            $actionIcon2,
676
            $questionTagA;
677
678
    $TBL_EXERCISE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
679
    $TBL_EXERCISES = Database::get_course_table(TABLE_QUIZ_TEST);
680
    $TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
681
    $TBL_COURSE_REL_CATEGORY = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY);
682
683
    $currentExerciseCondition = '';
684
    if (!empty($fromExercise)) {
685
        $currentCourseId = api_get_course_int_id();
686
        $currentExerciseCondition = "
687
            AND qu.iid NOT IN (
688
                SELECT question_id FROM $TBL_EXERCISE_QUESTION
689
                WHERE exercice_id = $fromExercise AND c_id = $currentCourseId
690
            )";
691
    }
692
693
    // if we have selected an exercise in the list-box 'Filter'
694
    if ($exerciseId > 0) {
695
        $efConditions = getExtraFieldConditions($formValues, 'from');
696
697
        $where = '';
698
        $from = '';
699
        if (isset($courseCategoryId) && $courseCategoryId > 0) {
700
            $from = ", $TBL_COURSE_REL_CATEGORY crc ";
701
            $where .= " AND
702
                    crc.c_id = $selected_course AND
703
                    crc.question_id = qu.iid AND
704
                    crc.category_id = $courseCategoryId";
705
        }
706
        if (isset($exerciseLevel) && -1 != $exerciseLevel) {
707
            $where .= ' AND level = '.$exerciseLevel;
708
        }
709
        if (isset($answerType) && $answerType > 0) {
710
            $where .= ' AND type = '.$answerType;
711
        }
712
713
        if (!empty($questionId)) {
714
            $where .= ' AND qu.iid = '.$questionId;
715
        }
716
717
        if (!empty($description)) {
718
            $where .= " AND qu.description LIKE '%$description%'";
719
        }
720
721
        $select = 'DISTINCT
722
                    qu.iid,
723
                    qu.question,
724
                    qu.type,
725
                    qu.level,
726
                    qt.exercice_id exerciseId';
727
        if ($getCount) {
728
            //$select = 'count(qu.iid) as count';
729
        }
730
        $sql = "SELECT $select
731
                FROM
732
                    $TBL_EXERCISE_QUESTION qt
733
                    INNER JOIN $TBL_QUESTIONS qu
734
                    ON qt.question_id = qu.iid
735
                    $from
736
                    {$efConditions['from']}
737
                WHERE
738
                    qt.exercice_id = $exerciseId AND
739
                    qt.c_id = $selected_course
740
                    $where
741
                    $currentExerciseCondition
742
                    {$efConditions['where']}
743
                ORDER BY BINARY qu.question ASC
744
                ";
745
    } elseif ($exerciseId == -1) {
746
        $efConditions = getExtraFieldConditions($formValues, 'join');
747
        // If we have selected the option 'Orphan questions' in the list-box 'Filter'
748
        $level_where = '';
749
        $from = '';
750
        if (isset($courseCategoryId) && $courseCategoryId > 0) {
751
            $from = " INNER JOIN $TBL_COURSE_REL_CATEGORY crc
752
                    ON crc.question_id = ex.iid ";
753
            $level_where .= " AND
754
                    crc.c_id = $selected_course AND
755
                    crc.category_id = $courseCategoryId";
756
        }
757
        if (isset($exerciseLevel) && -1 != $exerciseLevel) {
758
            $level_where = ' AND level='.$exerciseLevel;
759
        }
760
        $answer_where = '';
761
        if (isset($answerType) && $answerType > 0 - 1) {
762
            $answer_where = ' AND qu.type='.$answerType;
763
        }
764
765
        if (!empty($questionId)) {
766
            $answer_where .= ' AND ex.iid = '.$questionId;
767
        }
768
769
        if (!empty($description)) {
770
            $answer_where .= " AND ex.description LIKE '%$description%'";
771
        }
772
773
        $select = ' qu.*, r.exercice_id exerciseId  ';
774
775
        $sql = " (
776
                    SELECT $select
777
                    FROM $TBL_QUESTIONS qu
778
                    INNER JOIN $TBL_EXERCISE_QUESTION r
779
                    ON qu.iid = r.question_id
780
                    INNER JOIN $TBL_EXERCISES ex
781
                    ON ex.iid = r.exercice_id
782
                    $from
783
                    {$efConditions['from']}
784
                    WHERE
785
                        ex.c_id = $selected_course AND
786
                        ex.active = '-1'
787
                        $level_where
788
                        $answer_where
789
                        {$efConditions['where']}
790
                )
791
                UNION
792
                (
793
                    SELECT $select
794
                    FROM $TBL_QUESTIONS qu
795
                    LEFT OUTER JOIN $TBL_EXERCISE_QUESTION r
796
                    ON qu.iid = r.question_id
797
                    $from
798
                    {$efConditions['from']}
799
                    WHERE
800
                        qu.c_id = $selected_course AND
801
                        r.question_id is null
802
                        $level_where
803
                        $answer_where
804
                        {$efConditions['where']}
805
                )
806
                UNION
807
                (
808
                        SELECT $select
809
                        FROM $TBL_QUESTIONS qu
810
                        INNER JOIN $TBL_EXERCISE_QUESTION r
811
                        ON qu.iid = r.question_id
812
                        $from
813
                        {$efConditions['from']}
814
                        WHERE
815
                            r.c_id = $selected_course AND
816
                            (r.exercice_id = '-1' OR r.exercice_id = '0')
817
                            $level_where
818
                            $answer_where
819
                            {$efConditions['where']}
820
                    )
821
                ";
822
    } else {
823
        $efConditions = getExtraFieldConditions($formValues, 'from');
824
        // All tests for selected course
825
        // If we have not selected any option in the list-box 'Filter'
826
        $filter = '';
827
        $from = '';
828
        if (isset($courseCategoryId) && $courseCategoryId > 0) {
829
            $from = ", $TBL_COURSE_REL_CATEGORY crc ";
830
            $filter .= " AND
831
                        crc.c_id = $selected_course AND
832
                        crc.question_id = qu.iid AND
833
                        crc.category_id = $courseCategoryId";
834
        }
835
        if (isset($exerciseLevel) && -1 != $exerciseLevel) {
836
            $filter .= ' AND level = '.$exerciseLevel.' ';
837
        }
838
        if (isset($answerType) && $answerType > 0) {
839
            $filter .= ' AND qu.type = '.$answerType.' ';
840
        }
841
842
        if (!empty($questionId)) {
843
            $filter .= ' AND qu.iid = '.$questionId;
844
        }
845
846
        if (!empty($description)) {
847
            $filter .= " AND qu.description LIKE '%$description%'";
848
        }
849
850
        if (-1 == $session_id || empty($session_id)) {
851
            $session_id = 0;
852
        }
853
        $sessionCondition = api_get_session_condition($session_id, true, 'ex.session_id');
854
855
        $select = 'qu.iid, question, qu.type, level, ex.session_id, qt.exercice_id exerciseId  ';
856
857
        // All tests for the course selected, not in session
858
        $sql = "SELECT DISTINCT
859
                    $select
860
                FROM
861
                $TBL_QUESTIONS as qu
862
                INNER JOIN $TBL_EXERCISE_QUESTION as qt
863
                ON qu.iid = qt.question_id
864
                INNER JOIN $TBL_EXERCISES as ex
865
                ON ex.iid = qt.exercice_id
866
                {$efConditions['from']}
867
                $from
868
                WHERE
869
                    qt.c_id = $selected_course AND
870
                    ex.c_id = $selected_course
871
                    $sessionCondition
872
                    $filter
873
                    $currentExerciseCondition
874
                    {$efConditions['where']}
875
                GROUP BY qu.iid
876
                ORDER BY BINARY qu.question ASC
877
                ";
878
    }
879
880
    if ($getCount) {
881
        $result = Database::query($sql);
882
        return Database::num_rows($result);
883
    }
884
    //$sql .= " LIMIT $start, $length";
885
    $result = Database::query($sql);
886
887
    $mainQuestionList = [];
888
    while ($row = Database::fetch_array($result, 'ASSOC')) {
889
        if ($exerciseId == -1 && isQuestionInActiveQuiz($row['iid'])) {
890
            continue;
891
        }
892
893
        $mainQuestionList[] = $row;
894
    }
895
896
    $QList = [];
897
    foreach ($mainQuestionList as $question) {
898
        $row = [];
899
        // This function checks if the question can be read
900
        $question_type = get_question_type_for_question($selected_course, $question['iid']);
901
902
        if (empty($question_type)) {
903
            continue;
904
        }
905
        $sessionId = isset($question['session_id']) ? $question['session_id'] : null;
906
        if (!$objExercise->hasQuestion($question['iid'])) {
907
            $row[0] = Display::input(
908
                'checkbox',
909
                'questions[]',
910
                $question['iid'],
911
                ['class' => 'question_checkbox']
912
            );
913
        } else {
914
            $row[1] = '';
915
        }
916
        $row[1] = $question['iid'];
917
918
        $row[2] = getLinkForQuestion(
919
            $questionTagA,
920
            $fromExercise,
921
            $question['iid'],
922
            $question['type'],
923
            $question['question'],
924
            $sessionId,
925
            $question['exerciseId']
926
        );
927
    
928
        $row[3] = $question_type;
929
        $row[4] = TestCategory::getCategoryNameForQuestion($question['iid'], $selected_course);
930
        $row[5] = $question['level'];
931
932
        $row[6] = getQuestionOcurrences($question['iid']);
933
        $row[7] = getQuestionFailures($question['iid']);
934
        $row[8] = getQuestionSuccesses($question['iid']);
935
936
        $row[9] = get_action_icon_for_question(
937
            $actionIcon1,
938
            $fromExercise,
939
            $question['iid'],
940
            $question['type'],
941
            $question['question'],
942
            $selected_course,
943
            $courseCategoryId,
944
            $exerciseLevel,
945
            $answerType,
946
            $session_id,
947
            $question['exerciseId'],
948
            $objExercise
949
        ).'&nbsp;'.
950
        get_action_icon_for_question(
951
            $actionIcon2,
952
            $fromExercise,
953
            $question['iid'],
954
            $question['type'],
955
            $question['question'],
956
            $selected_course,
957
            $courseCategoryId,
958
            $exerciseLevel,
959
            $answerType,
960
            $session_id,
961
            $question['exerciseId'],
962
            $objExercise
963
        );
964
        $QList[] = $row;
965
    }
966
    if(!empty($column)) {
967
        $asc = $direction =='ASC' ? 1 : 0;
968
        $QList = sortByCol($QList, $column, $asc);
969
    }
970
    $x = 0;
971
    if (!empty($length)) {
972
        $questionList = [];
973
        $end = $start+$length;
974
        foreach($QList as $question) {
975
            if ($x>=$start && $x<$end) {
976
                $questionList[] = $question;
977
            }
978
            $x++;
979
        }
980
        return $questionList;
981
    }
982
    return $QList;
983
984
}
985
/**
986
 * get number total of questions
987
 */
988
function getNbrQuestions() {
989
    $res = getQuestions(
990
            0,
991
            0,
992
            0,
993
            null,
994
            true
995
        );
996
    return $res;
997
}
998
999
1000
$nbrQuestions = getQuestions(
1001
        0,
1002
        0,
1003
        0,
1004
        null,
1005
        true
1006
    );  
1007
1008
1009
$length = api_get_configuration_value('question_pagination_length');
1010
if (empty($length)) {
1011
    $length = 20;
1012
}
1013
1014
$start = ($page - 1) * $length;
1015
1016
$paginator = new Paginator();
1017
$pagination = $paginator->paginate([]);
1018
$pagination->setTotalItemCount($nbrQuestions);
1019
$pagination->setItemNumberPerPage($length);
1020
$pagination->setCurrentPageNumber($page);
1021
1022
$pagination->renderer = function ($data) use ($url) {
1023
    $render = '';
1024
    if ($data['pageCount'] > 1) {
1025
        $render = '<ul class="pagination">';
1026
        for ($i = 1; $i <= $data['pageCount']; $i++) {
1027
            $pageContent = '<li><a href="'.$url.'&page='.$i.'">'.$i.'</a></li>';
1028
            if ($data['current'] == $i) {
1029
                $pageContent = '<li class="active"><a href="#" >'.$i.'</a></li>';
1030
            }
1031
            $render .= $pageContent;
1032
        }
1033
        $render .= '</ul>';
1034
    }
1035
1036
    return $render;
1037
};
1038
1039
// build the line of the array to display questions
1040
// Actions are different if you launch the question_pool page
1041
// They are different too if you have displayed questions from your course
1042
// Or from another course you are the admin(or session admin)
1043
// from a test or not
1044
/*
1045
+--------------------------------------------+--------------------------------------------+
1046
|   NOT IN A TEST                            |         IN A TEST                          |
1047
+----------------------+---------------------+---------------------+----------------------+
1048
|IN THE COURSE (*)  "x | NOT IN THE COURSE o | IN THE COURSE    +  | NOT IN THE COURSE  o |
1049
+----------------------+---------------------+---------------------+----------------------+
1050
|Edit the question     | Do nothing          | Add question to test|Clone question in test|
1051
|Delete the question   |                     |                     |                      |
1052
|(true delete)         |                     |                     |                      |
1053
+----------------------+---------------------+---------------------+----------------------+
1054
(*) this is the only way to delete or modify orphan questions
1055
*/
1056
1057
if ($fromExercise <= 0) {
1058
    // NOT IN A TEST - NOT IN THE COURSE
1059
    $actionLabel = get_lang('Reuse');
1060
    $actionIcon1 = get_lang('MustBeInATest');
1061
    $actionIcon2 = '';
1062
    // We are not in this course, to messy if we link to the question in another course
1063
    $questionTagA = 0;
1064
    if ($selected_course == api_get_course_int_id()) {
1065
        // NOT IN A TEST - IN THE COURSE
1066
        $actionLabel = get_lang('Modify');
1067
        $actionIcon1 = 'edit';
1068
        $actionIcon2 = 'delete';
1069
        // We are in the course, question title can be a link to the question edit page
1070
        $questionTagA = 1;
1071
    }
1072
} else {
1073
    // IN A TEST - NOT IN THE COURSE
1074
    $actionLabel = get_lang('ReUseACopyInCurrentTest');
1075
    $actionIcon1 = 'clone';
1076
    $actionIcon2 = '';
1077
    $questionTagA = 0;
1078
1079
    if ($selected_course == api_get_course_int_id()) {
1080
        // IN A TEST - IN THE COURSE
1081
        $actionLabel = get_lang('Reuse');
1082
        $actionIcon1 = 'add';
1083
        $actionIcon2 = '';
1084
        $questionTagA = 1;
1085
    } elseif (true === api_get_configuration_value('quiz_question_allow_inter_course_linking')) {
1086
        $actionIcon2 = 'add';
1087
    }
1088
}
1089
1090
1091
$headers = [];  
1092
1093
//echo $pagination;
1094
1095
$tableId = 'question_pool_id';
1096
echo '<form id="'.$tableId.'" method="get" action="'.$url.'">';
1097
echo '<input type="hidden" name="fromExercise" value="'.$fromExercise.'">';
1098
echo '<input type="hidden" name="cidReq" value="'.$_course['code'].'">';
1099
echo '<input type="hidden" name="selected_course" value="'.$selected_course.'">';
1100
echo '<input type="hidden" name="course_id" value="'.$selected_course.'">';
1101
echo '<input type="hidden" name="action">';
1102
1103
//$parameters = [];
1104
/*$vals = getQuestionsList(0,20,2, 'ASC');
1105
echo '<pre>';
1106
echo var_dump($vals);
1107
echo '</pre>';
1108
echo '<pre>';
1109
echo var_dump(getNbrQuestions());
1110
echo '</pre>';*/
1111
1112
$table = new SortableTable(
1113
            'question-list',
1114
            'getNbrQuestions',
1115
            'getQuestions',
1116
            2,
1117
            20,
1118
            'ASC'
1119
        );
1120
//$table->set_additional_parameters($parameters);
1121
$row = 0;
1122
$column = 0;
1123
$table->set_header(0, '', false, 'width="8px"');
1124
$table->set_header(1, 'Id', true, 'width="60px"');
1125
$table->set_header(2, get_lang('QuestionUpperCaseFirstLetter'), true, null, ['class' => 'title']);
1126
$table->set_header(3, get_lang('Type'), false);
1127
$table->set_header(4, get_lang('QuestionCategory'), true);
1128
$table->set_header(5, get_lang('Difficulty'), true);
1129
$table->set_header(6, get_plugin_lang('Occurrences', ExtendedQuestionPoolPlugin::class), true);
1130
$table->set_header(7, get_plugin_lang('Failures', ExtendedQuestionPoolPlugin::class), true);
1131
$table->set_header(8, get_plugin_lang('Successes', ExtendedQuestionPoolPlugin::class), true);
1132
$table->set_header(9, $actionLabel, false, 'width="70px"');
1133
1134
echo $table->return_table();
1135
1136
echo '</form>';
1137
1138
$html = '<div class="btn-toolbar">';
1139
$html .= '<div class="btn-group">';
1140
$html .= '<a
1141
        class="btn btn-default"
1142
        href="?'.$url.'selectall=1"
1143
        onclick="javascript: setCheckbox(true, \''.$tableId.'\'); return false;">
1144
        '.get_lang('SelectAll').'</a>';
1145
$html .= '<a
1146
            class="btn btn-default"
1147
            href="?'.$url.'"
1148
            onclick="javascript: setCheckbox(false, \''.$tableId.'\'); return false;">
1149
            '.get_lang('UnSelectAll').'</a> ';
1150
$html .= '</div>';
1151
$html .= '<div class="btn-group">
1152
            <button class="btn btn-default" onclick="javascript:return false;">'.get_lang('Actions').'</button>
1153
            <button class="btn btn-default dropdown-toggle" data-toggle="dropdown">
1154
                <span class="caret"></span>
1155
            </button>
1156
            <ul class="dropdown-menu">';
1157
1158
$actionLabel = get_lang('ReUseACopyInCurrentTest');
1159
$actions = ['clone' => get_lang('ReUseACopyInCurrentTest')];
1160
if ($selected_course == api_get_course_int_id()) {
1161
    $actions = [
1162
        'reuse' => get_lang('ReuseQuestion'),
1163
        'score' => get_plugin_lang('setDefaultScore', ExtendedQuestionPoolPlugin::class)
1164
    ];
1165
}
1166
1167
foreach ($actions as $action => &$label) {
1168
    $html .= '<li>
1169
            <a
1170
                data-action ="'.$action.'"
1171
                href="#"
1172
                onclick="javascript:action_click(this, \''.$tableId.'\');">'.
1173
                $label.'
1174
            </a>
1175
        </li>';
1176
}
1177
$html .= '</ul>';
1178
$html .= '</div>'; //btn-group
1179
$html .= '</div>'; //toolbar
1180
1181
echo $html;
1182
1183
Display::display_footer();
1184
1185
/**
1186
 * Put the menu entry for level and type to default "Choice"
1187
 * It is useful if you change the exercise, you need to reset the other menus.
1188
 *
1189
 * @author hubert.borderiou 13-10-2011
1190
 */
1191
function reset_menu_lvl_type()
1192
{
1193
    global $exerciseLevel, $answerType;
1194
    $answerType = -1;
1195
    $exerciseLevel = -1;
1196
}
1197
1198
/**
1199
 * Put the menu entry for exercise and level and type to default "Choice"
1200
 * It is useful if you change the course, you need to reset the other menus.
1201
 *
1202
 * @author hubert.borderiou 13-10-2011
1203
 */
1204
function reset_menu_exo_lvl_type()
1205
{
1206
    global $exerciseId, $courseCategoryId;
1207
    reset_menu_lvl_type();
1208
    $exerciseId = 0;
1209
    $courseCategoryId = 0;
1210
}
1211
1212
/**
1213
 * return the <a> link to admin question, if needed.
1214
 *
1215
 * @param int    $in_addA
1216
 * @param int    $fromExercise
1217
 * @param int    $questionId
1218
 * @param int    $questionType
1219
 * @param string $questionName
1220
 * @param int    $sessionId
1221
 * @param int    $exerciseId
1222
 *
1223
 * @return string
1224
 *
1225
 * @author hubert.borderiou
1226
 */
1227
function getLinkForQuestion(
1228
    $in_addA,
1229
    $fromExercise,
1230
    $questionId,
1231
    $questionType,
1232
    $questionName,
1233
    $sessionId,
1234
    $exerciseId
1235
) {
1236
    $result = $questionName;
1237
    if ($in_addA) {
1238
        $sessionIcon = '';
1239
        if (!empty($sessionId) && -1 != $sessionId) {
1240
            $sessionIcon = ' '.Display::return_icon('star.png', get_lang('Session'));
1241
        }
1242
        $exerciseId = (int) $exerciseId;
1243
        $questionId = (int) $questionId;
1244
        $questionType = (int) $questionType;
1245
        $fromExercise = (int) $fromExercise;
1246
        $qOptions = getQuestionAnswers($questionId);
1247
        $result = Display::url(
1248
            $questionName.$sessionIcon,
1249
            'admin.php?'.api_get_cidreq().
1250
            "&exerciseId=$exerciseId&editQuestion=$questionId&type=$questionType&fromExercise=$fromExercise",
1251
            ['title' => $qOptions]
1252
        );
1253
    }
1254
1255
    return $result;
1256
}
1257
1258
/**
1259
    Return the <a> html code for delete, add, clone, edit a question
1260
    in_action = the code of the action triggered by the button
1261
    from_exercise = the id of the current exercise from which we click on question pool
1262
    in_questionid = the id of the current question
1263
    in_questiontype = the code of the type of the current question
1264
    in_questionname = the name of the question
1265
    in_selected_course = the if of the course chosen in the FILTERING MENU
1266
    in_courseCategoryId = the id of the category chosen in the FILTERING MENU
1267
    in_exerciseLevel = the level of the exercise chosen in the FILTERING MENU
1268
    in_answerType = the code of the type of the question chosen in the FILTERING MENU
1269
    in_session_id = the id of the session_id chosen in the FILTERING MENU
1270
    in_exercise_id = the id of the exercise chosen in the FILTERING MENU
1271
*/
1272
function get_action_icon_for_question(
1273
    $in_action,
1274
    $from_exercise,
1275
    $in_questionid,
1276
    $in_questiontype,
1277
    $in_questionname,
1278
    $in_selected_course,
1279
    $in_courseCategoryId,
1280
    $in_exerciseLevel,
1281
    $in_answerType,
1282
    $in_session_id,
1283
    $in_exercise_id,
1284
    Exercise $myObjEx
1285
) {
1286
    $limitTeacherAccess = api_get_configuration_value('limit_exercise_teacher_access');
1287
    $getParams = "&selected_course=$in_selected_course&courseCategoryId=$in_courseCategoryId&exerciseId=$in_exercise_id&exerciseLevel=$in_exerciseLevel&answerType=$in_answerType&session_id=$in_session_id";
1288
    $res = '';
1289
    switch ($in_action) {
1290
        case 'delete':
1291
            if ($limitTeacherAccess && !api_is_platform_admin()) {
1292
                break;
1293
            }
1294
1295
            if (isQuestionInActiveQuiz($in_questionid)) {
1296
                $res = Display::return_icon('delete_na.png', get_lang('ThisQuestionExistsInAnotherExercisesWarning'));
1297
            } else {
1298
                $res = "<a href='".api_get_self()."?".
1299
                    api_get_cidreq().$getParams."&delete=$in_questionid' onclick='return confirm_your_choice(\'Por favor, confirme la eliminación\')'>";
1300
                $res .= Display::return_icon('delete.png', get_lang('Delete'));
1301
                $res .= "</a>";
1302
            }
1303
1304
            break;
1305
        case 'edit':
1306
            $res = getLinkForQuestion(
1307
                1,
1308
                $from_exercise,
1309
                $in_questionid,
1310
                $in_questiontype,
1311
                Display::return_icon('edit.png', get_lang('Modify')),
1312
                $in_session_id,
1313
                $in_exercise_id
1314
            );
1315
            break;
1316
        case 'add':
1317
            $res = '-';
1318
            if (!$myObjEx->hasQuestion($in_questionid)) {
1319
                $res = "<a href='".api_get_self().'?'.
1320
                    api_get_cidreq().$getParams."&recup=$in_questionid&fromExercise=$from_exercise'>";
1321
                $res .= Display::return_icon('view_more_stats.gif', get_lang('InsertALinkToThisQuestionInTheExercise'));
1322
                $res .= '</a>';
1323
            }
1324
            break;
1325
        case 'clone':
1326
            $url = api_get_self().'?'.api_get_cidreq().$getParams.
1327
                "&question_copy=$in_questionid&course_id=$in_selected_course&fromExercise=$from_exercise";
1328
            $res = Display::url(
1329
                Display::return_icon('cd.png', get_lang('ReUseACopyInCurrentTest')),
1330
                $url
1331
            );
1332
            break;
1333
        default:
1334
            $res = $in_action;
1335
            break;
1336
    }
1337
1338
    return $res;
1339
}
1340
1341
/**
1342
 * @param int $questionId
1343
 *
1344
 * @return bool
1345
 */
1346
function isQuestionInActiveQuiz($questionId)
1347
{
1348
    $tblQuizRelQuestion = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
1349
    $tblQuiz = Database::get_course_table(TABLE_QUIZ_TEST);
1350
1351
    $questionId = (int) $questionId;
1352
1353
    if (empty($questionId)) {
1354
        return false;
1355
    }
1356
1357
    $result = Database::fetch_assoc(
1358
        Database::query(
1359
            "SELECT COUNT(qq.question_id) count
1360
                    FROM $tblQuizRelQuestion qq
1361
                    INNER JOIN $tblQuiz ex
1362
                    ON qq.exercice_id = ex.iid
1363
                    WHERE
1364
                        ex.active = 1 AND
1365
                        qq.question_id = $questionId"
1366
        )
1367
    );
1368
1369
    return $result['count'] > 0;
1370
}
1371
1372
/**
1373
 * Return the icon for the question type.
1374
 *
1375
 * @author hubert.borderiou 13-10-2011
1376
 */
1377
function get_question_type_for_question($in_selectedcourse, $in_questionid)
1378
{
1379
    $courseInfo = api_get_course_info_by_id($in_selectedcourse);
1380
    $question = Question::read($in_questionid, $courseInfo);
1381
    $questionType = null;
1382
    if (!empty($question)) {
1383
        $typeImg = $question->getTypePicture();
1384
        $typeExpl = $question->getExplanation();
1385
1386
        $questionType = Display::tag('div', Display::return_icon($typeImg, $typeExpl, [], 32), []);
1387
    }
1388
1389
    return $questionType;
1390
}
1391