Passed
Pull Request — 1.11.x (#5783)
by Yannick
08:32
created

FeedbackExport   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 179
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 16
eloc 111
c 1
b 0
f 0
dl 0
loc 179
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A createQuestionXml() 0 22 2
B getPresentation() 0 20 7
A getData() 0 36 3
A export() 0 20 1
A createFeedbackXml() 0 32 2
A mapQuestionType() 0 13 1
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
namespace moodleexport;
6
7
/**
8
 * Class FeedbackExport.
9
 *
10
 * Handles the export of surveys from Chamilo to Moodle Feedback.
11
 */
12
class FeedbackExport extends ActivityExport
13
{
14
    /**
15
     * Export a survey to Moodle Feedback format.
16
     *
17
     * @param int $activityId The ID of the survey.
18
     * @param string $exportDir The directory where the feedback will be exported.
19
     * @param int $moduleId The ID of the module.
20
     * @param int $sectionId The ID of the section.
21
     */
22
    public function export($activityId, $exportDir, $moduleId, $sectionId): void
23
    {
24
        // Prepare the directory for export
25
        $feedbackDir = $this->prepareActivityDirectory($exportDir, 'feedback', $moduleId);
26
27
        // Get survey data from Chamilo
28
        $surveyData = $this->getData($activityId, $sectionId);
29
30
        // Create XML files for the survey
31
        $this->createFeedbackXml($surveyData, $feedbackDir);
32
        $this->createModuleXml($surveyData, $feedbackDir);
33
        $this->createInforefXml($surveyData, $feedbackDir);
34
        $this->createCalendarXml($surveyData, $feedbackDir);
35
        $this->createCommentsXml($surveyData, $feedbackDir);
36
        $this->createCompetenciesXml($surveyData, $feedbackDir);
37
        $this->createCompletionXml($surveyData, $feedbackDir);
38
        $this->createFiltersXml($surveyData, $feedbackDir);
39
        $this->createGradeHistoryXml($surveyData, $feedbackDir);
40
        $this->createGradesXml($surveyData, $feedbackDir);
41
        $this->createRolesXml($surveyData, $feedbackDir);
42
    }
43
44
    /**
45
     * Create the feedback.xml file for the Moodle feedback activity.
46
     */
47
    private function createFeedbackXml(array $surveyData, string $feedbackDir): void
48
    {
49
        $xmlContent = '<?xml version="1.0" encoding="UTF-8"?>' . PHP_EOL;
50
        $xmlContent .= '<activity id="' . $surveyData['id'] . '" moduleid="' . $surveyData['moduleid'] . '" modulename="feedback" contextid="' . $surveyData['contextid'] . '">' . PHP_EOL;
51
        $xmlContent .= '  <feedback id="' . $surveyData['id'] . '">' . PHP_EOL;
52
        $xmlContent .= '    <name>' . htmlspecialchars($surveyData['name']) . '</name>' . PHP_EOL;
53
        $xmlContent .= '    <intro>' . htmlspecialchars($surveyData['intro']) . '</intro>' . PHP_EOL;
54
        $xmlContent .= '    <introformat>1</introformat>' . PHP_EOL;
55
        $xmlContent .= '    <anonymous>1</anonymous>' . PHP_EOL;
56
        $xmlContent .= '    <email_notification>0</email_notification>' . PHP_EOL;
57
        $xmlContent .= '    <multiple_submit>0</multiple_submit>' . PHP_EOL;
58
        $xmlContent .= '    <autonumbering>1</autonumbering>' . PHP_EOL;
59
        $xmlContent .= '    <site_after_submit></site_after_submit>' . PHP_EOL;
60
        $xmlContent .= '    <page_after_submit></page_after_submit>' . PHP_EOL;
61
        $xmlContent .= '    <page_after_submitformat>1</page_after_submitformat>' . PHP_EOL;
62
        $xmlContent .= '    <publish_stats>0</publish_stats>' . PHP_EOL;
63
        $xmlContent .= '    <timeopen>0</timeopen>' . PHP_EOL;
64
        $xmlContent .= '    <timeclose>0</timeclose>' . PHP_EOL;
65
        $xmlContent .= '    <timemodified>' . $surveyData['timemodified'] . '</timemodified>' . PHP_EOL;
66
        $xmlContent .= '    <completionsubmit>0</completionsubmit>' . PHP_EOL;
67
        $xmlContent .= '    <items>' . PHP_EOL;
68
69
        // Map Chamilo questions to Moodle Feedback format
70
        foreach ($surveyData['questions'] as $question) {
71
            $xmlContent .= $this->createQuestionXml($question);
72
        }
73
74
        $xmlContent .= '    </items>' . PHP_EOL;
75
        $xmlContent .= '  </feedback>' . PHP_EOL;
76
        $xmlContent .= '</activity>';
77
78
        $this->createXmlFile('feedback', $xmlContent, $feedbackDir);
79
    }
80
81
    /**
82
     * Create the XML for a single question in Moodle Feedback format.
83
     */
84
    private function createQuestionXml(array $question): string
85
    {
86
        $name = htmlspecialchars(strip_tags($question['text']), ENT_XML1 | ENT_QUOTES, 'UTF-8');
87
        $label = htmlspecialchars(strip_tags($question['label']), ENT_XML1 | ENT_QUOTES, 'UTF-8');
88
        $presentation = $this->getPresentation($question);
89
        $hasValue = ($question['type'] === 'pagebreak') ? '0' : '1';
90
91
        $xmlContent = '<item id="' . $question['id'] . '">' . PHP_EOL;
92
        $xmlContent .= '  <template>0</template>' . PHP_EOL;
93
        $xmlContent .= '  <name>' . $name . '</name>' . PHP_EOL;
94
        $xmlContent .= '  <label>' . $label . '</label>' . PHP_EOL;
95
        $xmlContent .= '  <presentation>' . $presentation . '</presentation>' . PHP_EOL;
96
        $xmlContent .= '  <typ>' . $this->mapQuestionType($question['type']) . '</typ>' . PHP_EOL;
97
        $xmlContent .= '  <hasvalue>' . $hasValue . '</hasvalue>' . PHP_EOL;
98
        $xmlContent .= '  <position>' . $question['position'] . '</position>' . PHP_EOL;
99
        $xmlContent .= '  <required>0</required>' . PHP_EOL;
100
        $xmlContent .= '  <dependitem>0</dependitem>' . PHP_EOL;
101
        $xmlContent .= '  <dependvalue></dependvalue>' . PHP_EOL;
102
        $xmlContent .= '  <options>h</options>' . PHP_EOL;
103
        $xmlContent .= '</item>' . PHP_EOL;
104
105
        return $xmlContent;
106
    }
107
108
    /**
109
     * Get presentation for different question types.
110
     */
111
    private function getPresentation(array $question): string
112
    {
113
        $options = array_map('strip_tags', $question['options']);
114
        $sanitizedOptions = array_map(function ($option) {
115
            return htmlspecialchars($option, ENT_XML1 | ENT_QUOTES, 'UTF-8');
116
        }, $options);
117
118
        switch ($question['type']) {
119
            case 'yesno':
120
            case 'multiplechoice':
121
            case 'multiplechoiceother':
122
                return 'r&gt;&gt;&gt;&gt;&gt;' . implode(PHP_EOL . '|', $sanitizedOptions);
123
            case 'multipleresponse':
124
                return 'c&gt;&gt;&gt;&gt;&gt;' . implode(PHP_EOL . '|', $sanitizedOptions);
125
            case 'dropdown':
126
                return 'd&gt;&gt;&gt;&gt;&gt;' . implode(PHP_EOL . '|', $sanitizedOptions);
127
            case 'open':
128
                return '30|5'; // Textarea with rows and cols
129
            default:
130
                return '';
131
        }
132
    }
133
134
    /**
135
     * Map Chamilo question type to Moodle Feedback type.
136
     */
137
    private function mapQuestionType(string $chamiloType): string
138
    {
139
        $typeMap = [
140
            'yesno' => 'multichoice',
141
            'multiplechoice' => 'multichoice',
142
            'multipleresponse' => 'multichoice',
143
            'dropdown' => 'multichoice',
144
            'multiplechoiceother' => 'multichoice',
145
            'open' => 'textarea',
146
            'pagebreak' => 'pagebreak',
147
        ];
148
149
        return $typeMap[$chamiloType] ?? 'unknown';
150
    }
151
152
    /**
153
     * Get survey data including questions and answers from Chamilo.
154
     */
155
    public function getData(int $surveyId, int $sectionId): array
156
    {
157
        $adminData = MoodleExport::getAdminUserData();
158
        $adminId = $adminData['id'];
159
160
        $survey = $this->course->resources['survey'][$surveyId];
161
        $questions = [];
162
        foreach ($this->course->resources['survey_question'] as $question) {
163
            if ((int) $question->survey_id === $surveyId) {
164
                // Debugging
165
                $questions[] = [
166
                    'id' => $question->id,
167
                    'text' => $question->survey_question,
168
                    'type' => $question->survey_question_type,
169
                    'options' => array_map(function ($answer) {
170
                        return $answer['option_text'];
171
                    }, $question->answers),
172
                    'position' => $question->sort,
173
                    'label' => '', // Default empty label
174
                ];
175
            }
176
        }
177
178
        return [
179
            'id' => $surveyId,
180
            'moduleid' => $surveyId,
181
            'modulename' => 'feedback',
182
            'contextid' => $this->course->info['real_id'],
183
            'sectionid' => $sectionId,
184
            'sectionnumber' => 0,
185
            'name' => $survey->title,
186
            'intro' => $survey->intro,
187
            'timemodified' => time(),
188
            'questions' => $questions,
189
            'users' => [$adminId],
190
            'files' => [],
191
        ];
192
    }
193
}
194