Skip to content

Commit b39662d

Browse files
authored
Merge pull request #6379 from christianbeeznest/aix-21977-1
Course: Improve export of quiz questions, assignments in LP, and images in introduction page with mzb format - refs BT#21977
2 parents 056f3fa + 221e6d8 commit b39662d

File tree

8 files changed

+109
-19
lines changed

8 files changed

+109
-19
lines changed

main/coursecopy/export_moodle.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@
138138
$exportDir = 'moodle_export_'.$courseId;
139139

140140
try {
141-
$moodleVersion = isset($values['moodle_version']) ? $values['moodle_version'] : '3';
141+
$moodleVersion = $values['moodle_version'] ?? '3';
142142
$mbzFile = $exporter->export($courseId, $exportDir, $moodleVersion);
143143
echo Display::return_message(get_lang('MoodleExportCreated'), 'confirm');
144144
echo '<br />';

main/inc/lib/moodleexport/ActivityExport.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public function getSectionIdForActivity(int $activityId, string $itemType): int
3333
{
3434
foreach ($this->course->resources[RESOURCE_LEARNPATH] as $learnpath) {
3535
foreach ($learnpath->items as $item) {
36+
$item['item_type'] = $item['item_type'] === 'student_publication' ? 'work' : $item['item_type'];
3637
if ($item['item_type'] == $itemType && $item['path'] == $activityId) {
3738
return $learnpath->source_id;
3839
}

main/inc/lib/moodleexport/AssignExport.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ public function getData(int $assignId, int $sectionId): ?array
4949
{
5050
$work = $this->course->resources[RESOURCE_WORK][$assignId];
5151

52+
if (empty($work->params['id']) || empty($work->params['title'])) {
53+
return null;
54+
}
55+
56+
$sentDate = !empty($work->params['sent_date']) ? strtotime($work->params['sent_date']) : time();
57+
5258
$workFiles = getAllDocumentToWork($assignId, $this->course->info['real_id']);
5359
$files = [];
5460
if (!empty($workFiles)) {
@@ -73,11 +79,11 @@ public function getData(int $assignId, int $sectionId): ?array
7379
'contextid' => $this->course->info['real_id'],
7480
'sectionid' => $sectionId,
7581
'sectionnumber' => 0,
76-
'name' => htmlspecialchars($work->params['title']),
77-
'intro' => $work->params['description'],
78-
'duedate' => strtotime($work->params['sent_date']),
79-
'gradingduedate' => strtotime($work->params['sent_date']) + 86400 * 7,
80-
'allowsubmissionsfromdate' => strtotime($work->params['sent_date']),
82+
'name' => htmlspecialchars($work->params['title'], ENT_QUOTES),
83+
'intro' => htmlspecialchars($work->params['description'], ENT_QUOTES),
84+
'duedate' => $sentDate,
85+
'gradingduedate' => $sentDate + 7 * 86400,
86+
'allowsubmissionsfromdate' => $sentDate,
8187
'timemodified' => time(),
8288
'grade_item_id' => 0,
8389
'files' => $files,

main/inc/lib/moodleexport/FileExport.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,14 @@ private function createFileXmlEntry(array $file): string
186186
*/
187187
private function processDocument(array $filesData, object $document): array
188188
{
189+
if (
190+
$document->file_type === 'file' &&
191+
isset($this->course->used_page_doc_ids) &&
192+
in_array($document->source_id, $this->course->used_page_doc_ids)
193+
) {
194+
return $filesData;
195+
}
196+
189197
if (
190198
$document->file_type === 'file' &&
191199
pathinfo($document->path, PATHINFO_EXTENSION) === 'html' &&
@@ -296,7 +304,7 @@ private function ensureTrailingSlash(string $path): string
296304
/**
297305
* Get MIME type based on the file extension.
298306
*/
299-
private function getMimeType($filePath): string
307+
public function getMimeType($filePath): string
300308
{
301309
$extension = pathinfo($filePath, PATHINFO_EXTENSION);
302310
$mimeTypes = $this->getMimeTypes();

main/inc/lib/moodleexport/MoodleExport.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,15 @@ public function export(string $courseId, string $exportDir, int $version)
6969
$courseExport->exportCourse($tempDir);
7070

7171
// Export files-related data and actual files
72+
$pageExport = new PageExport($this->course);
73+
$pageFiles = [];
74+
$pageData = $pageExport->getData(0, 1);
75+
if (!empty($pageData['files'])) {
76+
$pageFiles = $pageData['files'];
77+
}
7278
$fileExport = new FileExport($this->course);
7379
$filesData = $fileExport->getFilesData();
80+
$filesData['files'] = array_merge($filesData['files'], $pageFiles);
7481
$fileExport->exportFiles($filesData, $tempDir);
7582

7683
// Export sections of the course
@@ -98,8 +105,12 @@ public function exportQuestionsXml(array $questionsData, string $exportDir): voi
98105
$xmlContent .= '<question_categories>'.PHP_EOL;
99106

100107
foreach ($questionsData as $quiz) {
101-
$categoryId = $quiz['questions'][0]['questioncategoryid'] ?? '0';
102-
108+
$categoryId = $quiz['questions'][0]['questioncategoryid'] ?? '1';
109+
$hash = md5($categoryId . $quiz['name']);
110+
if (isset($categoryHashes[$hash])) {
111+
continue;
112+
}
113+
$categoryHashes[$hash] = true;
103114
$xmlContent .= ' <question_category id="'.$categoryId.'">'.PHP_EOL;
104115
$xmlContent .= ' <name>Default for '.htmlspecialchars($quiz['name'] ?? 'Unknown').'</name>'.PHP_EOL;
105116
$xmlContent .= ' <contextid>'.($quiz['contextid'] ?? '0').'</contextid>'.PHP_EOL;

main/inc/lib/moodleexport/PageExport.php

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,25 +46,64 @@ public function getData(int $pageId, int $sectionId): ?array
4646
{
4747
$contextid = $this->course->info['real_id'];
4848
if ($pageId === 0) {
49-
if (
50-
isset($this->course->resources[RESOURCE_TOOL_INTRO]['course_homepage']) &&
51-
is_object($this->course->resources[RESOURCE_TOOL_INTRO]['course_homepage']) &&
52-
!empty($this->course->resources[RESOURCE_TOOL_INTRO]['course_homepage']->intro_text)
53-
) {
49+
$introText = trim($this->course->resources[RESOURCE_TOOL_INTRO]['course_homepage']->intro_text ?? '');
50+
51+
if (!empty($introText)) {
52+
$files = [];
53+
$resources = \DocumentManager::get_resources_from_source_html($introText);
54+
$courseInfo = api_get_course_info($this->course->code);
55+
$adminId = MoodleExport::getAdminUserData()['id'];
56+
57+
foreach ($resources as [$src]) {
58+
if (preg_match('#/document(/[^"\']+)#', $src, $matches)) {
59+
$path = $matches[1];
60+
$docId = \DocumentManager::get_document_id($courseInfo, $path);
61+
if ($docId) {
62+
$this->course->used_page_doc_ids[] = $docId;
63+
$document = \DocumentManager::get_document_data_by_id($docId, $this->course->code);
64+
if ($document) {
65+
$contenthash = hash('sha1', basename($document['path']));
66+
$mimetype = (new FileExport($this->course))->getMimeType($document['path']);
67+
68+
$files[] = [
69+
'id' => $document['id'],
70+
'contenthash' => $contenthash,
71+
'contextid' => $contextid,
72+
'component' => 'mod_page',
73+
'filearea' => 'content',
74+
'itemid' => 1,
75+
'filepath' => '/Documents/',
76+
'documentpath' => 'document' . $document['path'],
77+
'filename' => basename($document['path']),
78+
'userid' => $adminId,
79+
'filesize' => $document['size'],
80+
'mimetype' => $mimetype,
81+
'status' => 0,
82+
'timecreated' => time() - 3600,
83+
'timemodified' => time(),
84+
'source' => $document['title'],
85+
'author' => 'Unknown',
86+
'license' => 'allrightsreserved',
87+
];
88+
}
89+
}
90+
}
91+
}
92+
5493
return [
5594
'id' => 0,
5695
'moduleid' => 0,
5796
'modulename' => 'page',
5897
'contextid' => $contextid,
5998
'name' => get_lang('Introduction'),
6099
'intro' => '',
61-
'content' => trim($this->course->resources[RESOURCE_TOOL_INTRO]['course_homepage']->intro_text),
100+
'content' => $this->normalizeContent($introText),
62101
'sectionid' => $sectionId,
63102
'sectionnumber' => 1,
64103
'display' => 0,
65104
'timemodified' => time(),
66105
'users' => [],
67-
'files' => [],
106+
'files' => $files,
68107
];
69108
}
70109
}
@@ -79,7 +118,7 @@ public function getData(int $pageId, int $sectionId): ?array
79118
'contextid' => $contextid,
80119
'name' => $page->title,
81120
'intro' => $page->comment ?? '',
82-
'content' => $this->getPageContent($page),
121+
'content' => $this->normalizeContent($this->getPageContent($page)),
83122
'sectionid' => $sectionId,
84123
'sectionnumber' => 1,
85124
'display' => 0,
@@ -117,6 +156,24 @@ private function createPageXml(array $pageData, string $pageDir): void
117156
$this->createXmlFile('page', $xmlContent, $pageDir);
118157
}
119158

159+
private function normalizeContent(string $html): string
160+
{
161+
return preg_replace_callback(
162+
'#<img[^>]+src=["\'](?<url>[^"\']+)["\']#i',
163+
function ($match) {
164+
$src = $match['url'];
165+
166+
if (preg_match('#/courses/[^/]+/document/(.+)$#', $src, $parts)) {
167+
$filename = basename($parts[1]);
168+
return str_replace($src, '@@PLUGINFILE@@/Documents/' . $filename, $match[0]);
169+
}
170+
171+
return $match[0];
172+
},
173+
$html
174+
);
175+
}
176+
120177
/**
121178
* Retrieves the content of the page.
122179
*/

main/inc/lib/moodleexport/QuizExport.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,13 @@ private function getQuestionsForQuiz(int $quizId): array
172172

173173
foreach ($quizResources as $questionId => $questionData) {
174174
if (in_array($questionId, $this->course->resources[RESOURCE_QUIZ][$quizId]->obj->question_ids)) {
175+
$categoryId = $questionData->question_category ?? 0;
176+
$categoryId = $categoryId > 0 ? $categoryId : $this->getDefaultCategoryId();
175177
$questions[] = [
176178
'id' => $questionData->source_id,
177179
'questiontext' => $questionData->question,
178180
'qtype' => $this->mapQuestionType($questionData->quiz_type),
179-
'questioncategoryid' => $questionData->question_category ?? 0,
181+
'questioncategoryid' => $categoryId,
180182
'answers' => $this->getAnswersForQuestion($questionData->source_id),
181183
'maxmark' => $questionData->ponderation ?? 1,
182184
];
@@ -246,6 +248,11 @@ private function getFeedbacksForQuiz(int $quizId): array
246248
return $feedbacks;
247249
}
248250

251+
private function getDefaultCategoryId(): int
252+
{
253+
return 1;
254+
}
255+
249256
/**
250257
* Creates the quiz.xml file.
251258
*/

main/inc/lib/moodleexport/SectionExport.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ private function addActivityToList(array $item, int $sectionId, array &$activiti
255255
}
256256

257257
$itemType = $item['item_type'] === 'link' ? 'url' :
258-
($item['item_type'] === 'work' ? 'assign' :
258+
($item['item_type'] === 'work' || $item['item_type'] === 'student_publication' ? 'assign' :
259259
($item['item_type'] === 'survey' ? 'feedback' : $item['item_type']));
260260

261261
switch ($itemType) {

0 commit comments

Comments
 (0)