Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion main/coursecopy/export_moodle.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
$exportDir = 'moodle_export_'.$courseId;

try {
$moodleVersion = isset($values['moodle_version']) ? $values['moodle_version'] : '3';
$moodleVersion = $values['moodle_version'] ?? '3';
$mbzFile = $exporter->export($courseId, $exportDir, $moodleVersion);
echo Display::return_message(get_lang('MoodleExportCreated'), 'confirm');
echo '<br />';
Expand Down
1 change: 1 addition & 0 deletions main/inc/lib/moodleexport/ActivityExport.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public function getSectionIdForActivity(int $activityId, string $itemType): int
{
foreach ($this->course->resources[RESOURCE_LEARNPATH] as $learnpath) {
foreach ($learnpath->items as $item) {
$item['item_type'] = $item['item_type'] === 'student_publication' ? 'work' : $item['item_type'];
if ($item['item_type'] == $itemType && $item['path'] == $activityId) {
return $learnpath->source_id;
}
Expand Down
16 changes: 11 additions & 5 deletions main/inc/lib/moodleexport/AssignExport.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ public function getData(int $assignId, int $sectionId): ?array
{
$work = $this->course->resources[RESOURCE_WORK][$assignId];

if (empty($work->params['id']) || empty($work->params['title'])) {
return null;
}

$sentDate = !empty($work->params['sent_date']) ? strtotime($work->params['sent_date']) : time();

$workFiles = getAllDocumentToWork($assignId, $this->course->info['real_id']);
$files = [];
if (!empty($workFiles)) {
Expand All @@ -73,11 +79,11 @@ public function getData(int $assignId, int $sectionId): ?array
'contextid' => $this->course->info['real_id'],
'sectionid' => $sectionId,
'sectionnumber' => 0,
'name' => htmlspecialchars($work->params['title']),
'intro' => $work->params['description'],
'duedate' => strtotime($work->params['sent_date']),
'gradingduedate' => strtotime($work->params['sent_date']) + 86400 * 7,
'allowsubmissionsfromdate' => strtotime($work->params['sent_date']),
'name' => htmlspecialchars($work->params['title'], ENT_QUOTES),
'intro' => htmlspecialchars($work->params['description'], ENT_QUOTES),
'duedate' => $sentDate,
'gradingduedate' => $sentDate + 7 * 86400,
'allowsubmissionsfromdate' => $sentDate,
'timemodified' => time(),
'grade_item_id' => 0,
'files' => $files,
Expand Down
10 changes: 9 additions & 1 deletion main/inc/lib/moodleexport/FileExport.php
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,14 @@ private function createFileXmlEntry(array $file): string
*/
private function processDocument(array $filesData, object $document): array
{
if (
$document->file_type === 'file' &&
isset($this->course->used_page_doc_ids) &&
in_array($document->source_id, $this->course->used_page_doc_ids)
) {
return $filesData;
}

if (
$document->file_type === 'file' &&
pathinfo($document->path, PATHINFO_EXTENSION) === 'html' &&
Expand Down Expand Up @@ -296,7 +304,7 @@ private function ensureTrailingSlash(string $path): string
/**
* Get MIME type based on the file extension.
*/
private function getMimeType($filePath): string
public function getMimeType($filePath): string
{
$extension = pathinfo($filePath, PATHINFO_EXTENSION);
$mimeTypes = $this->getMimeTypes();
Expand Down
15 changes: 13 additions & 2 deletions main/inc/lib/moodleexport/MoodleExport.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,15 @@ public function export(string $courseId, string $exportDir, int $version)
$courseExport->exportCourse($tempDir);

// Export files-related data and actual files
$pageExport = new PageExport($this->course);
$pageFiles = [];
$pageData = $pageExport->getData(0, 1);
if (!empty($pageData['files'])) {
$pageFiles = $pageData['files'];
}
$fileExport = new FileExport($this->course);
$filesData = $fileExport->getFilesData();
$filesData['files'] = array_merge($filesData['files'], $pageFiles);
$fileExport->exportFiles($filesData, $tempDir);

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

foreach ($questionsData as $quiz) {
$categoryId = $quiz['questions'][0]['questioncategoryid'] ?? '0';

$categoryId = $quiz['questions'][0]['questioncategoryid'] ?? '1';
$hash = md5($categoryId . $quiz['name']);
if (isset($categoryHashes[$hash])) {
continue;
}
$categoryHashes[$hash] = true;
$xmlContent .= ' <question_category id="'.$categoryId.'">'.PHP_EOL;
$xmlContent .= ' <name>Default for '.htmlspecialchars($quiz['name'] ?? 'Unknown').'</name>'.PHP_EOL;
$xmlContent .= ' <contextid>'.($quiz['contextid'] ?? '0').'</contextid>'.PHP_EOL;
Expand Down
73 changes: 65 additions & 8 deletions main/inc/lib/moodleexport/PageExport.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,25 +46,64 @@ public function getData(int $pageId, int $sectionId): ?array
{
$contextid = $this->course->info['real_id'];
if ($pageId === 0) {
if (
isset($this->course->resources[RESOURCE_TOOL_INTRO]['course_homepage']) &&
is_object($this->course->resources[RESOURCE_TOOL_INTRO]['course_homepage']) &&
!empty($this->course->resources[RESOURCE_TOOL_INTRO]['course_homepage']->intro_text)
) {
$introText = trim($this->course->resources[RESOURCE_TOOL_INTRO]['course_homepage']->intro_text ?? '');

if (!empty($introText)) {
$files = [];
$resources = \DocumentManager::get_resources_from_source_html($introText);
$courseInfo = api_get_course_info($this->course->code);
$adminId = MoodleExport::getAdminUserData()['id'];

foreach ($resources as [$src]) {
if (preg_match('#/document(/[^"\']+)#', $src, $matches)) {
$path = $matches[1];
$docId = \DocumentManager::get_document_id($courseInfo, $path);
if ($docId) {
$this->course->used_page_doc_ids[] = $docId;
$document = \DocumentManager::get_document_data_by_id($docId, $this->course->code);
if ($document) {
$contenthash = hash('sha1', basename($document['path']));
$mimetype = (new FileExport($this->course))->getMimeType($document['path']);

$files[] = [
'id' => $document['id'],
'contenthash' => $contenthash,
'contextid' => $contextid,
'component' => 'mod_page',
'filearea' => 'content',
'itemid' => 1,
'filepath' => '/Documents/',
'documentpath' => 'document' . $document['path'],
'filename' => basename($document['path']),
'userid' => $adminId,
'filesize' => $document['size'],
'mimetype' => $mimetype,
'status' => 0,
'timecreated' => time() - 3600,
'timemodified' => time(),
'source' => $document['title'],
'author' => 'Unknown',
'license' => 'allrightsreserved',
];
}
}
}
}

return [
'id' => 0,
'moduleid' => 0,
'modulename' => 'page',
'contextid' => $contextid,
'name' => get_lang('Introduction'),
'intro' => '',
'content' => trim($this->course->resources[RESOURCE_TOOL_INTRO]['course_homepage']->intro_text),
'content' => $this->normalizeContent($introText),
'sectionid' => $sectionId,
'sectionnumber' => 1,
'display' => 0,
'timemodified' => time(),
'users' => [],
'files' => [],
'files' => $files,
];
}
}
Expand All @@ -79,7 +118,7 @@ public function getData(int $pageId, int $sectionId): ?array
'contextid' => $contextid,
'name' => $page->title,
'intro' => $page->comment ?? '',
'content' => $this->getPageContent($page),
'content' => $this->normalizeContent($this->getPageContent($page)),
'sectionid' => $sectionId,
'sectionnumber' => 1,
'display' => 0,
Expand Down Expand Up @@ -117,6 +156,24 @@ private function createPageXml(array $pageData, string $pageDir): void
$this->createXmlFile('page', $xmlContent, $pageDir);
}

private function normalizeContent(string $html): string
{
return preg_replace_callback(
'#<img[^>]+src=["\'](?<url>[^"\']+)["\']#i',
function ($match) {
$src = $match['url'];

if (preg_match('#/courses/[^/]+/document/(.+)$#', $src, $parts)) {
$filename = basename($parts[1]);
return str_replace($src, '@@PLUGINFILE@@/Documents/' . $filename, $match[0]);
}

return $match[0];
},
$html
);
}

/**
* Retrieves the content of the page.
*/
Expand Down
9 changes: 8 additions & 1 deletion main/inc/lib/moodleexport/QuizExport.php
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,13 @@ private function getQuestionsForQuiz(int $quizId): array

foreach ($quizResources as $questionId => $questionData) {
if (in_array($questionId, $this->course->resources[RESOURCE_QUIZ][$quizId]->obj->question_ids)) {
$categoryId = $questionData->question_category ?? 0;
$categoryId = $categoryId > 0 ? $categoryId : $this->getDefaultCategoryId();
$questions[] = [
'id' => $questionData->source_id,
'questiontext' => $questionData->question,
'qtype' => $this->mapQuestionType($questionData->quiz_type),
'questioncategoryid' => $questionData->question_category ?? 0,
'questioncategoryid' => $categoryId,
'answers' => $this->getAnswersForQuestion($questionData->source_id),
'maxmark' => $questionData->ponderation ?? 1,
];
Expand Down Expand Up @@ -246,6 +248,11 @@ private function getFeedbacksForQuiz(int $quizId): array
return $feedbacks;
}

private function getDefaultCategoryId(): int
{
return 1;
}

/**
* Creates the quiz.xml file.
*/
Expand Down
2 changes: 1 addition & 1 deletion main/inc/lib/moodleexport/SectionExport.php
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ private function addActivityToList(array $item, int $sectionId, array &$activiti
}

$itemType = $item['item_type'] === 'link' ? 'url' :
($item['item_type'] === 'work' ? 'assign' :
($item['item_type'] === 'work' || $item['item_type'] === 'student_publication' ? 'assign' :
($item['item_type'] === 'survey' ? 'feedback' : $item['item_type']));

switch ($itemType) {
Expand Down
Loading