Skip to content

Commit 491df29

Browse files
authored
Merge pull request #2348 from nextcloud/fix/export-structure
fix: Export structure
2 parents a4a59c7 + 7a62719 commit 491df29

3 files changed

Lines changed: 43 additions & 27 deletions

File tree

lib/Db/BookmarkMapper.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,10 @@ public function insert(Entity $entity): Bookmark {
895895
return $entity;
896896
} catch (Exception $e) {
897897
if ($e->getReason() === Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) {
898+
if ($this->db->inTransaction()) {
899+
$this->db->commit();
900+
$this->db->beginTransaction();
901+
}
898902
throw new AlreadyExistsError('A bookmark with this URL already exists');
899903
}
900904
throw $e;

lib/Service/HtmlExporter.php

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ public function exportFolder(string $userId, int $folderId): string {
7070
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
7171
<TITLE>Bookmarks</TITLE>';
7272

73-
$file .= $this->serializeFolder($userId, $folderId, true);
73+
$file .= "<DL><p>\n";
74+
$file .= $this->serializeFolder($userId, $folderId);
75+
$file .= "</DL><p>\n";
7476

7577
return $file;
7678
}
@@ -84,14 +86,15 @@ public function exportFolder(string $userId, int $folderId): string {
8486
* @throws MultipleObjectsReturnedException
8587
* @throws UnauthorizedAccessError
8688
*/
87-
protected function serializeFolder(string $userId, int $id, bool $onlyContent = false): string {
88-
if ($onlyContent) {
89-
$output = '';
90-
} else {
91-
$folder = $this->folderMapper->find($id);
92-
$output = '<DT><h3>' . htmlspecialchars($folder->getTitle()) . '</h3>' . "\n"
93-
. '<DL><p>';
89+
protected function serializeFolder(string $userId, int $id, string $indent = ''): string {
90+
$output = '';
91+
$nextIndent = $indent . ' ';
92+
$childFolders = $this->treeMapper->findChildren(TreeMapper::TYPE_FOLDER, $id);
93+
foreach ($childFolders as $childFolder) {
94+
$output .= $indent . '<DT><H3>' . htmlspecialchars($childFolder->getTitle()) . '</H3>' . "\n";
95+
$output .= $indent . '<DL><p>' . "\n" . $this->serializeFolder($userId, $childFolder->getId(), $nextIndent) . '</DL><p>' . "\n";
9496
}
97+
9598
$childBookmarks = $this->treeMapper->findChildren(TreeMapper::TYPE_BOOKMARK, $id);
9699
foreach ($childBookmarks as $bookmark) {
97100
// discards records with no URL. This should not happen but
@@ -105,25 +108,15 @@ protected function serializeFolder(string $userId, int $id, bool $onlyContent =
105108
$tags = Util::sanitizeHTML(implode(',', $tags));
106109
$title = trim($bookmark->getTitle());
107110
$url = Util::sanitizeHTML($bookmark->getUrl());
108-
if ($title === '') {
109-
$title = $url;
110-
}
111111
$title = Util::sanitizeHTML($title);
112112
$description = Util::sanitizeHTML($bookmark->getDescription());
113113

114-
$output .= '<DT><A HREF="' . $url . '" TAGS="' . $tags . '" ADD_DATE="' . $bookmark->getAdded() . '">' . $title . '</A>' . "\n";
114+
$output .= $indent . '<DT><A HREF="' . $url . '" TAGS="' . $tags . '" ADD_DATE="' . $bookmark->getAdded() . '">' . $title . '</A>' . "\n";
115115
if ($description !== '') {
116116
$output .= '<DD>' . $description . '</DD>';
117117
}
118118
$output .= "\n";
119119
}
120-
121-
$childFolders = $this->treeMapper->findChildren(TreeMapper::TYPE_FOLDER, $id);
122-
foreach ($childFolders as $childFolder) {
123-
$output .= $this->serializeFolder($userId, $childFolder->getId());
124-
}
125-
126-
$output .= '</p></DL>';
127120
return $output;
128121
}
129122
}

tests/HtmlImportExportTest.php

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public function testExport(...$bookmarks): void {
131131
// Set up database
132132
for ($i = 0; $i < 4; $i++) {
133133
$f = new Db\Folder();
134-
$f->setTitle($i);
134+
$f->setTitle(md5($i));
135135
$f->setUserId($this->userId);
136136
$f = $this->folderMapper->insert($f);
137137
$this->treeMapper->move(Db\TreeMapper::TYPE_FOLDER, $f->getId(), $rootFolder->getId());
@@ -143,13 +143,32 @@ public function testExport(...$bookmarks): void {
143143

144144
$exported = $this->htmlExporter->exportFolder($this->userId, $rootFolder->getId());
145145

146-
$rootFolders = $this->treeMapper->findChildren(Db\TreeMapper::TYPE_FOLDER, $rootFolder->getId());
147-
$this->assertCount(4, $rootFolders);
148-
foreach ($rootFolders as $rootFolder) {
149-
foreach ($this->treeMapper->findChildren(Db\TreeMapper::TYPE_BOOKMARK, $rootFolder->getId()) as $bookmark) {
146+
$exportedRootFolders = $this->treeMapper->findChildren(Db\TreeMapper::TYPE_FOLDER, $rootFolder->getId());
147+
$this->assertCount(4, $exportedRootFolders);
148+
foreach ($exportedRootFolders as $exportedRootFolder) {
149+
foreach ($this->treeMapper->findChildren(Db\TreeMapper::TYPE_BOOKMARK, $exportedRootFolder->getId()) as $bookmark) {
150+
$this->assertStringContainsString($exportedRootFolder->getTitle(), $exported);
150151
$this->assertStringContainsString($bookmark->getUrl(), $exported);
151152
}
152153
}
154+
155+
$f = new Db\Folder();
156+
$f->setTitle('Testimport');
157+
$f->setUserId($this->userId);
158+
$f = $this->folderMapper->insert($f);
159+
$this->htmlImporter->import($this->userId, $exported, $f->getId());
160+
$importedRootFolders = $this->treeMapper->findChildren(Db\TreeMapper::TYPE_FOLDER, $f->getId());
161+
foreach ($importedRootFolders as $i => $importedRootFolder) {
162+
$exportedRootFolder = $exportedRootFolders[$i];
163+
$this->assertEquals($importedRootFolder->getTitle(), $exportedRootFolder->getTitle());
164+
$exportedBookmarks = $this->treeMapper->findChildren(Db\TreeMapper::TYPE_BOOKMARK, $exportedRootFolder->getId());
165+
foreach ($this->treeMapper->findChildren(Db\TreeMapper::TYPE_BOOKMARK, $importedRootFolder->getId()) as $j => $bookmark) {
166+
$this->assertEquals($bookmark->getUrl(), $exportedBookmarks[$j]->getUrl());
167+
$this->assertEquals($bookmark->getTitle(), $exportedBookmarks[$j]->getTitle());
168+
$this->assertEquals($bookmark->getDescription(), $exportedBookmarks[$j]->getDescription());
169+
$this->assertEquals($this->tagMapper->findByBookmark($bookmark->getId()), $this->tagMapper->findByBookmark($exportedBookmarks[$j]->getId()));
170+
}
171+
}
153172
}
154173

155174
public function importProvider(): array {
@@ -166,10 +185,10 @@ public function exportProvider(): array {
166185
return Db\Bookmark::fromArray($props);
167186
}, [
168187
['url' => 'https://google.com/', 'title' => 'Google', 'description' => 'Search engine'],
169-
['url' => 'https://nextcloud.com/', 'title' => 'Nextcloud', 'description' => ''],
188+
['url' => 'https://nextcloud.com/', 'title' => 'Nextcloud', 'description' => 'cloud cloud cloud'],
170189
['url' => 'https://php.net/', 'title' => '', 'description' => ''],
171-
['url' => 'https://de.wikipedia.org/wiki/%C3%9C', 'title' => '', 'description' => ''],
172-
['url' => 'https://github.com/nextcloud/bookmarks/projects/1', 'title' => '', 'description' => ''],
190+
['url' => 'https://de.wikipedia.org/wiki/%C3%9C', 'title' => '', 'description' => '<H1>Hello</H1>'],
191+
['url' => 'https://github.com/nextcloud/bookmarks/projects/1', 'title' => '', 'description' => '</DL>'],
173192
]),
174193
];
175194
}

0 commit comments

Comments
 (0)