Skip to content

Commit

Permalink
fix(PageService): Create index page if folder or subfolders have pages
Browse files Browse the repository at this point in the history
Fixes the scenario where a folder is missing the index page but
one of its subfolders contains pages.

Signed-off-by: Jonas <[email protected]>
  • Loading branch information
mejo- committed Nov 6, 2024
1 parent c713f1c commit 5621112
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 23 deletions.
61 changes: 38 additions & 23 deletions lib/Service/PageService.php
Original file line number Diff line number Diff line change
Expand Up @@ -391,35 +391,50 @@ private function getIndexPageFile(Folder $folder): File {
*/
public function getPagesFromFolder(int $collectiveId, Folder $folder, string $userId, bool $recurse = false, bool $forceIndex = false): array {
$pageInfos = [];
$indexPage = null;

// Add subpages and recurse over subfolders
foreach ($folder->getDirectoryListing() as $node) {
if ($node instanceof File && NodeHelper::isPage($node)) {
try {
$page = $this->getPageByFile($node, $folder);
} catch (NotFoundException) {
// If parent folder doesn't have an index page, it throws NotFoundException. Let's ignore it.
continue;
}
if (NodeHelper::isIndexPage($node)) {
$indexPage = $page;
} else {
$pageInfos[] = $page;
}
} elseif ($recurse && $node instanceof Folder) {
array_push($pageInfos, ...$this->getPagesFromFolder($collectiveId, $node, $userId, true));
$folderNodes = $folder->getDirectoryListing();

// Get page infos of subfolders
if ($recurse) {
$subfolders = array_filter($folderNodes, static function (Node $node) {
return $node instanceof Folder;
});
foreach ($subfolders as $subfolder) {
array_push($pageInfos, ...$this->getPagesFromFolder($collectiveId, $subfolder, $userId, true));
}
}

if (!$indexPage) {
if (!$forceIndex && count($pageInfos) === 0) {
return [];
}
$pageFiles = array_filter($folderNodes, static function (Node $node) {
return $node instanceof File && NodeHelper::isPage($node);
});

// Create missing index file if folder or subfolders have page files (or forceIndex)
$hasIndexFile = (bool)array_filter($folderNodes, static function (Node $node) {
return $node instanceof File && NodeHelper::isIndexPage($node);
});
$hasPages = count($pageFiles) > 0 || count($pageInfos) > 0;
if (!$hasIndexFile && ($hasPages || $forceIndex)) {
$indexPage = $this->newPage($collectiveId, $folder, PageInfo::INDEX_PAGE_TITLE, $userId);
}

return array_merge([$indexPage], $pageInfos);
// Add markdown files from this folder
$folderPageInfos = [];
foreach ($pageFiles as $pageFile) {
try {
$page = $this->getPageByFile($pageFile, $folder);
} catch (NotFoundException) {
// If parent folder doesn't have an index page, it throws NotFoundException.
continue;
}

if (NodeHelper::isIndexPage($pageFile)) {
$indexPage = $page;
} else {
$folderPageInfos[] = $page;
}
array_unshift($folderPageInfos, $indexPage);
}

return array_merge($folderPageInfos, $pageInfos);
}

/**
Expand Down
73 changes: 73 additions & 0 deletions tests/Unit/Service/PageServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,79 @@ public function testGetPagesFromFolder(): void {
self::assertEquals($pageInfos, $this->service->getPagesFromFolder($this->collectiveId, $folder, $this->userId, true));
}

public function testGetPagesFromFolderWithMissingIndex(): void {
$files = [];
$pageInfos = [];

$mountPoint = $this->getMockBuilder(MountPoint::class)
->disableOriginalConstructor()
->getMock();
$mountPoint->method('getMountPoint')->willReturn('/files/user/Collectives/collective/');

$folder = $this->createMock(Folder::class);
$folder->method('getParent')
->willReturn($folder);
$folder->method('getName')
->willReturn('testfolder');

$file1Name = 'page1.md';
$file1 = $this->getMockBuilder(File::class)
->disableOriginalConstructor()
->getMock();
$file1->method('getId')
->willReturn(1);
$file1->method('getName')
->willReturn($file1Name);
$file1->method('getParent')
->willReturn($folder);
$file1->method('getMountPoint')
->willReturn($mountPoint);
$file1->method('getInternalPath')
->willReturn('Collectives/testfolder/' . $file1Name);
$file1->method('getMTime')
->willReturn(0);
$file1->method('getSize')
->willReturn(0);
$files[] = $file1;

$folder->method('getDirectoryListing')
->willReturn($files);

$pageInfo1 = new PageInfo();
$pageInfo1->fromFile($file1, 1);
$pageInfo1->setParentId(101);
$pageInfos[] = $pageInfo1;

$indexFile = $this->createMock(File::class);
$indexFile->method('getId')
->willReturn(101);
$indexFile->method('getName')
->willReturn('Readme.md');
$folder->method('get')
->willReturn($indexFile);
$indexFile->method('getParent')
->willReturn($folder);
$indexFile->method('getMountPoint')
->willReturn($mountPoint);
$indexFile->method('getInternalPath')
->willReturn('Collectives/testfolder/Readme.md');
$indexFile->method('getMTime')
->willReturn(0);
$indexFile->method('getSize')
->willReturn(0);
$folder->method('newFile')
->willReturn($indexFile);

$indexPageInfo = new PageInfo();
$indexPageInfo->fromFile($indexFile, 1);
$indexPageInfo->setParentId(101);
$indexPageInfo->setTitle('testfolder');
$indexPageInfo->setLastUserId('jane');
array_unshift($pageInfos, $indexPageInfo);

self::assertEquals($pageInfos, $this->service->getPagesFromFolder($this->collectiveId, $folder, $this->userId, true));
}

public function testGetPageLink(): void {
$collectiveName = 'My Collective';

Expand Down

0 comments on commit 5621112

Please sign in to comment.