Skip to content
60 changes: 56 additions & 4 deletions main/inc/lib/moodleexport/ActivityExport.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
abstract class ActivityExport
{
protected $course;
public const DOCS_MODULE_ID = 0;

public function __construct($course)
{
Expand All @@ -27,15 +28,44 @@ public function __construct($course)
abstract public function export($activityId, $exportDir, $moduleId, $sectionId);

/**
* Get the section ID for a given activity ID.
* Get the section ID (learnpath source_id) for a given activity.
*/
public function getSectionIdForActivity(int $activityId, string $itemType): int
{
if (empty($this->course->resources[RESOURCE_LEARNPATH])) {
return 0;
}

foreach ($this->course->resources[RESOURCE_LEARNPATH] as $learnpath) {
if (empty($learnpath->items)) {
continue;
}

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;
$normalizedType = $item['item_type'] === 'student_publication'
? 'work'
: $item['item_type'];

if ($normalizedType !== $itemType) {
continue;
}

// Classic case: LP stores the numeric id in "path"
if (ctype_digit((string) $item['path']) && (int) $item['path'] === $activityId) {
return (int) $learnpath->source_id;
}

// Fallback for documents when LP stores the path instead of the id
if ($itemType === RESOURCE_DOCUMENT) {
$doc = \DocumentManager::get_document_data_by_id($activityId, $this->course->code);
if (!empty($doc['path'])) {
$p = (string) $doc['path'];
foreach ([$p, 'document/'.$p, '/'.$p] as $candidate) {
if ((string) $item['path'] === $candidate) {
return (int) $learnpath->source_id;
}
}
}
}
}
}
Expand Down Expand Up @@ -252,4 +282,26 @@ protected function createCalendarXml(array $activityData, string $destinationDir

$this->createXmlFile('calendar', $xmlContent, $destinationDir);
}

/**
* Returns the title of the item in the LP (if it exists); otherwise, $fallback.
*/
protected function lpItemTitle(int $sectionId, string $itemType, int $resourceId, ?string $fallback): string
{
if (!isset($this->course->resources[RESOURCE_LEARNPATH])) {
return $fallback ?? '';
}
foreach ($this->course->resources[RESOURCE_LEARNPATH] as $lp) {
if ((int) $lp->source_id !== $sectionId || empty($lp->items)) {
continue;
}
foreach ($lp->items as $it) {
$type = $it['item_type'] === 'student_publication' ? 'work' : $it['item_type'];
if ($type === $itemType && (int) $it['path'] === $resourceId) {
return $it['title'] ?? ($fallback ?? '');
}
}
}
return $fallback ?? '';
}
}
54 changes: 23 additions & 31 deletions main/inc/lib/moodleexport/FileExport.php
Original file line number Diff line number Diff line change
Expand Up @@ -197,37 +197,28 @@ 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)
) {
// Only real files are exported; folders are represented implicitly by "filepath"
if ($document->file_type !== 'file') {
return $filesData;
}

if (
$document->file_type === 'file' &&
pathinfo($document->path, PATHINFO_EXTENSION) === 'html' &&
substr_count($document->path, '/') === 1
) {
return $filesData;
}
// Base file data (contenthash, size, title, etc.)
$fileData = $this->getFileData($document);

if ($document->file_type === 'file') {
$extension = pathinfo($document->path, PATHINFO_EXTENSION);
if (!in_array(strtolower($extension), ['html', 'htm'])) {
$fileData = $this->getFileData($document);
$fileData['filepath'] = '/Documents/';
$fileData['contextid'] = 0;
$fileData['component'] = 'mod_folder';
$filesData['files'][] = $fileData;
}
} elseif ($document->file_type === 'folder') {
$folderFiles = \DocumentManager::getAllDocumentsByParentId($this->course->info, $document->source_id);
foreach ($folderFiles as $file) {
$filesData['files'][] = $this->getFolderFileData($file, (int) $document->source_id, '/Documents/'.dirname($file['path']).'/');
}
}
// Rebuild the relative filepath so Moodle can recreate the Documents tree
$relDir = dirname($document->path);
$filepath = $this->ensureTrailingSlash(
$relDir === '.' ? '/' : '/'.$relDir.'/'
);

// Attach this file to the global "Documents" folder activity
$fileData['filepath'] = $filepath;
$fileData['contextid'] = ActivityExport::DOCS_MODULE_ID;
$fileData['component'] = 'mod_folder';
$fileData['filearea'] = 'content';
$fileData['itemid'] = ActivityExport::DOCS_MODULE_ID;

$filesData['files'][] = $fileData;

return $filesData;
}
Expand Down Expand Up @@ -267,22 +258,23 @@ private function getFileData(object $document): array
/**
* Get file data for files inside a folder.
*/
private function getFolderFileData(array $file, int $sourceId, string $parentPath = '/Documents/'): array
private function getFolderFileData(array $file, int $sourceId, string $parentPath = '/'): array
{
$adminData = MoodleExport::getAdminUserData();
$adminId = $adminData['id'];
$contenthash = hash('sha1', basename($file['path']));
$mimetype = $this->getMimeType($file['path']);
$filename = basename($file['path']);
$filepath = $this->ensureTrailingSlash($parentPath);
$relDir = dirname($file['path']);
$filepath = $this->ensureTrailingSlash($relDir === '.' ? '/' : '/'.$relDir.'/');

return [
'id' => $file['id'],
'contenthash' => $contenthash,
'contextid' => $sourceId,
'contextid' => ActivityExport::DOCS_MODULE_ID,
'component' => 'mod_folder',
'filearea' => 'content',
'itemid' => (int) $file['id'],
'itemid' => ActivityExport::DOCS_MODULE_ID,
'filepath' => $filepath,
'documentpath' => 'document/'.$file['path'],
'filename' => $filename,
Expand Down
19 changes: 6 additions & 13 deletions main/inc/lib/moodleexport/FolderExport.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ public function export($activityId, $exportDir, $moduleId, $sectionId): void
*/
public function getData(int $folderId, int $sectionId): ?array
{
if ($folderId === 0) {
if ($folderId === 0 || $folderId === ActivityExport::DOCS_MODULE_ID) {
return [
'id' => 0,
'moduleid' => 0,
'id' => ActivityExport::DOCS_MODULE_ID,
'moduleid' => ActivityExport::DOCS_MODULE_ID,
'modulename' => 'folder',
'contextid' => 0,
'contextid' => ActivityExport::DOCS_MODULE_ID,
'name' => 'Documents',
'sectionid' => $sectionId,
'timemodified' => time(),
Expand Down Expand Up @@ -98,17 +98,10 @@ private function createFolderXml(array $folderData, string $folderDir): void
private function getFilesForFolder(int $folderId): array
{
$files = [];
if ($folderId === 0) {
if ($folderId === ActivityExport::DOCS_MODULE_ID) {
foreach ($this->course->resources[RESOURCE_DOCUMENT] as $doc) {
if ($doc->file_type === 'file') {
$files[] = [
'id' => (int) $doc->source_id,
'contenthash' => hash('sha1', basename($doc->path)),
'filename' => basename($doc->path),
'filepath' => '/Documents/',
'filesize' => (int) $doc->size,
'mimetype' => $this->getMimeType($doc->path),
];
$files[] = ['id' => (int) $doc->source_id];
}
}
}
Expand Down
11 changes: 7 additions & 4 deletions main/inc/lib/moodleexport/ForumExport.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public function export($activityId, $exportDir, $moduleId, $sectionId): void
*/
public function getData(int $forumId, int $sectionId): ?array
{
$forum = $this->course->resources['forum'][$forumId]->obj;
$forum = $this->course->resources[RESOURCE_FORUM][$forumId]->obj;

$adminData = MoodleExport::getAdminUserData();
$adminId = $adminData['id'];
Expand Down Expand Up @@ -78,14 +78,17 @@ public function getData(int $forumId, int $sectionId): ?array
}
}

$fileIds = [];
$name = $forum->forum_title ?? '';
if ($sectionId > 0) {
$name = $this->lpItemTitle($sectionId, RESOURCE_FORUM, $forumId, $name);
}

return [
'id' => $forumId,
'moduleid' => $forumId,
'modulename' => 'forum',
'contextid' => $this->course->info['real_id'],
'name' => $forum->forum_title,
'name' => $name,
'description' => $forum->forum_comment,
'timecreated' => time(),
'timemodified' => time(),
Expand All @@ -94,7 +97,7 @@ public function getData(int $forumId, int $sectionId): ?array
'userid' => $adminId,
'threads' => $threads,
'users' => [$adminId],
'files' => $fileIds,
'files' => [],
];
}

Expand Down
Loading
Loading