Completed
Push — master ( 067f55...e1cb48 )
by Julito
09:39
created

otherRow()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 29
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 17
c 1
b 0
f 0
nc 5
nop 3
dl 0
loc 29
rs 9.3888
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CourseBundle\Entity\CSurveyAnswer;
5
use Chamilo\CourseBundle\Entity\CSurveyQuestionOption;
6
7
require_once __DIR__.'/../../main/inc/global.inc.php';
8
9
api_protect_course_script(true);
10
api_protect_teacher_script();
11
12
$surveyId = isset($_GET['survey']) ? (int) $_GET['survey'] : 0;
13
$surveyData = SurveyManager::get_survey($surveyId);
14
$courseId = api_get_course_int_id();
15
16
if (empty($surveyData)) {
17
    api_not_allowed(true);
18
}
19
20
$plugin = SurveyExportCsvPlugin::create();
21
$allowExportIncomplete = 'true' === $plugin->get('export_incomplete');
22
23
if ($plugin->get('enabled') !== 'true') {
24
    api_not_allowed(true);
25
}
26
27
$questionsData = SurveyManager::get_questions($surveyId, $courseId);
28
// Sort questions by their "sort" field
29
$questionsData = array_filter(
30
    $questionsData,
31
    function ($questionData) {
32
        return in_array($questionData['type'], ['yesno', 'multiplechoice', 'open']);
33
    }
34
);
35
$numberOfQuestions = count($questionsData);
36
37
usort(
38
    $questionsData,
39
    function ($qL, $qR) {
40
        if ($qL['sort'] == $qR['sort']) {
41
            return 0;
42
        }
43
44
        return $qL['sort'] < $qR['sort'] ? -1 : 1;
45
    }
46
);
47
48
$content = [];
49
$content[] = firstRow($questionsData);
50
51
$surveyAnswers = getSurveyAnswers($courseId, $surveyId);
52
53
// Process answers
54
$i = 1;
55
foreach ($surveyAnswers as $answer) {
56
    $row = otherRow($questionsData, $answer['user'], $courseId);
57
58
    if (!$allowExportIncomplete && count($row) < $numberOfQuestions) {
59
        continue;
60
    }
61
62
    array_unshift($row, $i);
63
64
    $content[] = $row;
65
    $i++;
66
}
67
68
// Generate file
69
$fileName = md5($surveyId.time());
70
71
Export::arrayToCsv($content, $fileName, false, "'");
72
73
/**
74
 * Generate the first row for file.
75
 *
76
 * @param $questions
77
 *
78
 * @return array
79
 */
80
function firstRow($questions)
81
{
82
    array_pop($questions);
83
    $positions = array_keys($questions);
84
85
    $row = ['DATID'];
86
87
    foreach ($positions as $position) {
88
        $row[] = sprintf("P%02d", $position + 1);
89
    }
90
91
    $row[] = 'DATOBS';
92
93
    return $row;
94
}
95
96
/**
97
 * Get unique answer for surveys by users.
98
 *
99
 * @param int $courseId
100
 * @param int $surveyId
101
 *
102
 * @return array
103
 */
104
function getSurveyAnswers($courseId, $surveyId)
105
{
106
    $surveyAnswers = Database::getManager()
107
        ->createQuery(
108
            'SELECT sa.user, MIN(sa.iid) AS id FROM ChamiloCourseBundle:CSurveyAnswer sa
109
            WHERE sa.cId = :course AND sa.surveyId = :survey
110
            GROUP BY sa.user ORDER BY id ASC'
111
        )
112
        ->setParameters(['course' => $courseId, 'survey' => $surveyId])
113
        ->getResult();
114
115
    return $surveyAnswers;
116
}
117
118
/**
119
 * @param string $user
120
 * @param int    $courseId
121
 * @param int    $surveyId
122
 * @param int    $questionId
123
 *
124
 * @return array
125
 */
126
function getQuestionOptions($user, $courseId, $surveyId, $questionId)
127
{
128
    $options = Database::getManager()
129
        ->createQuery(
130
            'SELECT sqo FROM ChamiloCourseBundle:CSurveyQuestionOption sqo
131
            INNER JOIN ChamiloCourseBundle:CSurveyAnswer sa
132
                WITH
133
                    sqo.cId = sa.cId
134
                    AND sqo.questionId = sa.questionId
135
                    AND sqo.surveyId = sa.surveyId
136
                    AND sqo.iid = sa.optionId
137
            WHERE sa.user = :user AND sa.cId = :course AND sa.surveyId = :survey AND sa.questionId = :question'
138
        )
139
        ->setParameters(
140
            [
141
                'user' => $user,
142
                'course' => $courseId,
143
                'survey' => $surveyId,
144
                'question' => $questionId,
145
            ]
146
        )
147
        ->getResult();
148
149
    return $options;
150
}
151
152
/**
153
 * @param int    $questionId
154
 * @param int    $surveyId
155
 * @param int    $courseId
156
 * @param string $user
157
 *
158
 * @throws \Doctrine\ORM\NonUniqueResultException
159
 *
160
 * @return CSurveyAnswer|null
161
 */
162
function getOpenAnswer($questionId, $surveyId, $courseId, $user)
163
{
164
    $answer = Database::getManager()
165
        ->createQuery(
166
            'SELECT sa FROM ChamiloCourseBundle:CSurveyAnswer sa
167
            WHERE sa.cId = :course AND sa.surveyId = :survey AND sa.questionId = :question AND sa.user = :user'
168
        )
169
        ->setParameters(['course' => $courseId, 'survey' => $surveyId, 'question' => $questionId, 'user' => $user])
170
        ->getOneOrNullResult();
171
172
    return $answer;
173
}
174
175
/**
176
 * Generate the content rows for file.
177
 *
178
 * @param array  $questions
179
 * @param string $user
180
 * @param int    $courseId
181
 *
182
 * @throws \Doctrine\ORM\NonUniqueResultException
183
 *
184
 * @return array
185
 */
186
function otherRow($questions, $user, $courseId)
187
{
188
    $row = [];
189
190
    foreach ($questions as $question) {
191
        if ('open' === $question['type']) {
192
            $answer = getOpenAnswer($question['question_id'], $question['survey_id'], $courseId, $user);
193
194
            if ($answer) {
195
                $row[] = Security::remove_XSS($answer->getOptionId());
196
            }
197
        } else {
198
            $options = getQuestionOptions(
199
                $user,
200
                $courseId,
201
                $question['survey_id'],
202
                $question['question_id']
203
            );
204
            /** @var CSurveyQuestionOption|null $option */
205
            $option = end($options);
206
207
            if ($option) {
208
                $value = $option->getSort();
209
                $row[] = '"'.$value.'"';
210
            }
211
        }
212
    }
213
214
    return $row;
215
}
216