From 9385666585b68ef5ccf3a93294639f7fc7848751 Mon Sep 17 00:00:00 2001 From: mjansen Date: Wed, 15 Jan 2025 11:39:20 +0100 Subject: [PATCH] Forum: Fix export/import of attachments See: https://mantis.ilias.de/view.php?id=43584 --- .../Forum/classes/class.ilForumExporter.php | 5 +- .../Forum/classes/class.ilForumXMLWriter.php | 182 ++++++++++-------- 2 files changed, 102 insertions(+), 85 deletions(-) diff --git a/components/ILIAS/Forum/classes/class.ilForumExporter.php b/components/ILIAS/Forum/classes/class.ilForumExporter.php index 2e26a3f8a7f1..3710259b973c 100755 --- a/components/ILIAS/Forum/classes/class.ilForumExporter.php +++ b/components/ILIAS/Forum/classes/class.ilForumExporter.php @@ -45,7 +45,10 @@ public function getXmlRepresentation(string $a_entity, string $a_schema_version, $writer = new ilForumXMLWriter(); $writer->setForumId((int) $a_id); ilFileUtils::makeDirParents($this->getAbsoluteExportDirectory()); - $writer->setFileTargetDirectories($this->getRelativeExportDirectory(), $this->getAbsoluteExportDirectory()); + $writer->setFileTargetDirectories( + $this->exp->getExportDirInContainer(), + $this->getAbsoluteExportDirectory() + ); $writer->start(); $xml .= $writer->getXML(); } diff --git a/components/ILIAS/Forum/classes/class.ilForumXMLWriter.php b/components/ILIAS/Forum/classes/class.ilForumXMLWriter.php index ad07d3ba9211..673fd7ef8003 100755 --- a/components/ILIAS/Forum/classes/class.ilForumXMLWriter.php +++ b/components/ILIAS/Forum/classes/class.ilForumXMLWriter.php @@ -30,9 +30,11 @@ */ class ilForumXMLWriter extends ilXmlWriter { + private const LEGACY_RESOURCE_SUB_DIRECTORY = 'expDir_1'; + public ?int $forum_id = 0; - private ?string $target_dir_relative = null; - private ?string $target_dir_absolute = null; + private ?string $relative_component_path = null; + private ?string $absolute_root_export_path = null; private readonly \ILIAS\Style\Content\DomainService $content_style_domain; @@ -57,8 +59,18 @@ public function setForumId(int $id): void public function setFileTargetDirectories(string $a_rel, string $a_abs): void { - $this->target_dir_relative = $a_rel; - $this->target_dir_absolute = $a_abs; + $path = str_replace('\\', '/', $a_rel); + $segments = explode('/', $path); + array_shift($segments); + $a_rel = implode('/', $segments); + + $this->relative_component_path = $a_rel; + $this->absolute_root_export_path = rtrim($a_abs, '/'); + } + + public function getComponentPath(): string + { + return $this->absolute_root_export_path . '/' . $this->relative_component_path; } public function start(): bool @@ -66,7 +78,9 @@ public function start(): bool global $DIC; $ilDB = $DIC->database(); - ilFileUtils::makeDir($this->target_dir_absolute . "/objects"); + ilFileUtils::makeDirParents($this->getComponentPath()); + ilFileUtils::makeDir($this->getComponentPath() . '/' . self::LEGACY_RESOURCE_SUB_DIRECTORY); + ilFileUtils::makeDir($this->getComponentPath() . '/' . self::LEGACY_RESOURCE_SUB_DIRECTORY . '/objects'); $query_frm = ' SELECT * @@ -80,58 +94,58 @@ public function start(): bool $res = $ilDB->query($query_frm); $row = $ilDB->fetchObject($res); - $style = $this->content_style_domain->styleForObjId((int) (int) $row->obj_id); + $style = $this->content_style_domain->styleForObjId((int) $row->obj_id); $attributes = [ 'Style' => $style->getStyleId() ]; - $this->xmlStartTag("Forum", $attributes); - - $this->xmlElement("Id", null, (int) $row->top_pk); - $this->xmlElement("ObjId", null, (int) $row->obj_id); - $this->xmlElement("Title", null, $row->title); - $this->xmlElement("Description", null, $row->description); - $this->xmlElement("DefaultView", null, (int) $row->default_view); - $this->xmlElement("Pseudonyms", null, (int) $row->anonymized); - $this->xmlElement("Statistics", null, (int) $row->statistics_enabled); - $this->xmlElement("ThreadRatings", null, (int) $row->thread_rating); - $this->xmlElement("MarkModeratorPosts", null, (int) $row->mark_mod_posts); - $this->xmlElement("PostingActivation", null, (int) $row->post_activation); - $this->xmlElement("PresetSubject", null, (int) $row->preset_subject); - $this->xmlElement("PresetRe", null, (int) $row->add_re_subject); - $this->xmlElement("NotificationType", null, $row->notification_type); - $this->xmlElement("NotificationEvents", null, (int) $row->interested_events); - $this->xmlElement("ForceNotification", null, (int) $row->admin_force_noti); - $this->xmlElement("ToggleNotification", null, (int) $row->user_toggle_noti); - $this->xmlElement("LastPost", null, $row->top_last_post); - $this->xmlElement("Moderator", null, (int) $row->top_mods); - $this->xmlElement("CreateDate", null, $row->top_date); - $this->xmlElement("UpdateDate", null, $row->top_update); - $this->xmlElement("FileUpload", null, (int) $row->file_upload_allowed); - $this->xmlElement("UpdateUserId", null, $row->update_user); - $this->xmlElement("UserId", null, (int) $row->top_usr_id); - - $query_thr = "SELECT frm_threads.* " . - " FROM frm_threads " . - " INNER JOIN frm_data ON top_pk = thr_top_fk " . + $this->xmlStartTag('Forum', $attributes); + + $this->xmlElement('Id', null, (int) $row->top_pk); + $this->xmlElement('ObjId', null, (int) $row->obj_id); + $this->xmlElement('Title', null, $row->title); + $this->xmlElement('Description', null, $row->description); + $this->xmlElement('DefaultView', null, (int) $row->default_view); + $this->xmlElement('Pseudonyms', null, (int) $row->anonymized); + $this->xmlElement('Statistics', null, (int) $row->statistics_enabled); + $this->xmlElement('ThreadRatings', null, (int) $row->thread_rating); + $this->xmlElement('MarkModeratorPosts', null, (int) $row->mark_mod_posts); + $this->xmlElement('PostingActivation', null, (int) $row->post_activation); + $this->xmlElement('PresetSubject', null, (int) $row->preset_subject); + $this->xmlElement('PresetRe', null, (int) $row->add_re_subject); + $this->xmlElement('NotificationType', null, $row->notification_type); + $this->xmlElement('NotificationEvents', null, (int) $row->interested_events); + $this->xmlElement('ForceNotification', null, (int) $row->admin_force_noti); + $this->xmlElement('ToggleNotification', null, (int) $row->user_toggle_noti); + $this->xmlElement('LastPost', null, $row->top_last_post); + $this->xmlElement('Moderator', null, (int) $row->top_mods); + $this->xmlElement('CreateDate', null, $row->top_date); + $this->xmlElement('UpdateDate', null, $row->top_update); + $this->xmlElement('FileUpload', null, (int) $row->file_upload_allowed); + $this->xmlElement('UpdateUserId', null, $row->update_user); + $this->xmlElement('UserId', null, (int) $row->top_usr_id); + + $query_thr = 'SELECT frm_threads.* ' . + ' FROM frm_threads ' . + ' INNER JOIN frm_data ON top_pk = thr_top_fk ' . 'WHERE top_frm_fk = ' . $ilDB->quote($this->forum_id, 'integer'); $res = $ilDB->query($query_thr); while ($row = $ilDB->fetchObject($res)) { - $this->xmlStartTag("Thread"); - - $this->xmlElement("Id", null, (int) $row->thr_pk); - $this->xmlElement("Subject", null, $row->thr_subject); - $this->xmlElement("UserId", null, (int) $row->thr_display_user_id); - $this->xmlElement("AuthorId", null, (int) $row->thr_author_id); - $this->xmlElement("Alias", null, $row->thr_usr_alias); - $this->xmlElement("LastPost", null, $row->thr_last_post); - $this->xmlElement("CreateDate", null, $row->thr_date); - $this->xmlElement("UpdateDate", null, $row->thr_date); - $this->xmlElement("ImportName", null, $row->import_name); - $this->xmlElement("Sticky", null, (int) $row->is_sticky); - $this->xmlElement("Closed", null, (int) $row->is_closed); + $this->xmlStartTag('Thread'); + + $this->xmlElement('Id', null, (int) $row->thr_pk); + $this->xmlElement('Subject', null, $row->thr_subject); + $this->xmlElement('UserId', null, (int) $row->thr_display_user_id); + $this->xmlElement('AuthorId', null, (int) $row->thr_author_id); + $this->xmlElement('Alias', null, $row->thr_usr_alias); + $this->xmlElement('LastPost', null, $row->thr_last_post); + $this->xmlElement('CreateDate', null, $row->thr_date); + $this->xmlElement('UpdateDate', null, $row->thr_date); + $this->xmlElement('ImportName', null, $row->import_name); + $this->xmlElement('Sticky', null, (int) $row->is_sticky); + $this->xmlElement('Closed', null, (int) $row->is_closed); $query = 'SELECT frm_posts.*, frm_posts_tree.* FROM frm_posts @@ -140,25 +154,25 @@ public function start(): bool INNER JOIN frm_posts_tree ON pos_fk = pos_pk WHERE pos_thr_fk = ' . $ilDB->quote($row->thr_pk, 'integer') . ' '; - $query .= " ORDER BY frm_posts_tree.lft ASC"; + $query .= ' ORDER BY frm_posts_tree.lft ASC'; $resPosts = $ilDB->query($query); while ($rowPost = $ilDB->fetchObject($resPosts)) { - $this->xmlStartTag("Post"); - $this->xmlElement("Id", null, (int) $rowPost->pos_pk); - $this->xmlElement("UserId", null, (int) $rowPost->pos_display_user_id); - $this->xmlElement("AuthorId", null, (int) $rowPost->pos_author_id); - $this->xmlElement("Alias", null, $rowPost->pos_usr_alias); - $this->xmlElement("Subject", null, $rowPost->pos_subject); - $this->xmlElement("CreateDate", null, $rowPost->pos_date); - $this->xmlElement("UpdateDate", null, $rowPost->pos_update); - $this->xmlElement("UpdateUserId", null, (int) $rowPost->update_user); - $this->xmlElement("Censorship", null, (int) $rowPost->pos_cens); - $this->xmlElement("CensorshipMessage", null, $rowPost->pos_cens_com); - $this->xmlElement("Notification", null, $rowPost->notify); - $this->xmlElement("ImportName", null, $rowPost->import_name); - $this->xmlElement("Status", null, (int) $rowPost->pos_status); - $this->xmlElement("Message", null, ilRTE::_replaceMediaObjectImageSrc($rowPost->pos_message, 0)); + $this->xmlStartTag('Post'); + $this->xmlElement('Id', null, (int) $rowPost->pos_pk); + $this->xmlElement('UserId', null, (int) $rowPost->pos_display_user_id); + $this->xmlElement('AuthorId', null, (int) $rowPost->pos_author_id); + $this->xmlElement('Alias', null, $rowPost->pos_usr_alias); + $this->xmlElement('Subject', null, $rowPost->pos_subject); + $this->xmlElement('CreateDate', null, $rowPost->pos_date); + $this->xmlElement('UpdateDate', null, $rowPost->pos_update); + $this->xmlElement('UpdateUserId', null, (int) $rowPost->update_user); + $this->xmlElement('Censorship', null, (int) $rowPost->pos_cens); + $this->xmlElement('CensorshipMessage', null, $rowPost->pos_cens_com); + $this->xmlElement('Notification', null, $rowPost->notify); + $this->xmlElement('ImportName', null, $rowPost->import_name); + $this->xmlElement('Status', null, (int) $rowPost->pos_status); + $this->xmlElement('Message', null, ilRTE::_replaceMediaObjectImageSrc($rowPost->pos_message, 0)); if ($rowPost->is_author_moderator === null) { $is_moderator_string = 'NULL'; @@ -166,36 +180,36 @@ public function start(): bool $is_moderator_string = (string) $rowPost->is_author_moderator; } - $this->xmlElement("isAuthorModerator", null, $is_moderator_string); + $this->xmlElement('isAuthorModerator', null, $is_moderator_string); $media_exists = false; $mobs = ilObjMediaObject::_getMobsOfObject('frm:html', (int) $rowPost->pos_pk); foreach ($mobs as $mob) { - $moblabel = "il_" . IL_INST_ID . "_mob_" . $mob; + $moblabel = 'il_' . IL_INST_ID . '_mob_' . $mob; if (ilObjMediaObject::_exists($mob)) { if (!$media_exists) { - $this->xmlStartTag("MessageMediaObjects"); + $this->xmlStartTag('MessageMediaObjects'); $media_exists = true; } $mob_obj = new ilObjMediaObject($mob); $imgattrs = [ - "label" => $moblabel, - "uri" => $this->target_dir_relative . "/objects/" . "il_" . IL_INST_ID . "_mob_" . $mob . "/" . $mob_obj->getTitle() + 'label' => $moblabel, + 'uri' => $this->relative_component_path . '/' . self::LEGACY_RESOURCE_SUB_DIRECTORY . '/objects/' . 'il_' . IL_INST_ID . '_mob_' . $mob . '/' . $mob_obj->getTitle() ]; - $this->xmlElement("MediaObject", $imgattrs, null); - $mob_obj->exportFiles($this->target_dir_absolute); + $this->xmlElement('MediaObject', $imgattrs, null); + $mob_obj->exportFiles($this->getComponentPath() . '/' . self::LEGACY_RESOURCE_SUB_DIRECTORY); } } if ($media_exists) { - $this->xmlEndTag("MessageMediaObjects"); + $this->xmlEndTag('MessageMediaObjects'); } - $this->xmlElement("Lft", null, (int) $rowPost->lft); - $this->xmlElement("Rgt", null, (int) $rowPost->rgt); - $this->xmlElement("Depth", null, (int) $rowPost->depth); - $this->xmlElement("ParentId", null, (int) $rowPost->parent_pos); + $this->xmlElement('Lft', null, (int) $rowPost->lft); + $this->xmlElement('Rgt', null, (int) $rowPost->rgt); + $this->xmlElement('Depth', null, (int) $rowPost->depth); + $this->xmlElement('ParentId', null, (int) $rowPost->parent_pos); $tmp_file_obj = new ilFileDataForum( (int) $this->forum_id, @@ -203,19 +217,19 @@ public function start(): bool ); foreach ($tmp_file_obj->getFilesOfPost() as $file) { - $this->xmlStartTag("Attachment"); - copy($file['path'], $this->target_dir_absolute . "/" . basename($file['name'])); - $content = $this->target_dir_relative . "/" . basename($file['name']); - $this->xmlElement("Content", null, $content); + $this->xmlStartTag('Attachment'); + copy($file['path'], $this->getComponentPath() . '/' . self::LEGACY_RESOURCE_SUB_DIRECTORY . '/' . basename($file['name'])); + $relative_path = $this->relative_component_path . '/' . self::LEGACY_RESOURCE_SUB_DIRECTORY . '/' . basename($file['name']); + $this->xmlElement('Content', null, $relative_path); - $this->xmlEndTag("Attachment"); + $this->xmlEndTag('Attachment'); } - $this->xmlEndTag("Post"); + $this->xmlEndTag('Post'); } - $this->xmlEndTag("Thread"); + $this->xmlEndTag('Thread'); } - $this->xmlEndTag("Forum"); + $this->xmlEndTag('Forum'); return true; }