diff --git a/system/Controllers/PageController.php b/system/Controllers/PageController.php index 23a8325..c906279 100644 --- a/system/Controllers/PageController.php +++ b/system/Controllers/PageController.php @@ -106,11 +106,12 @@ class PageController extends Controller $favicon = true; } - # get the cached navigation here (structure without hidden files ) + + # the navigation is a copy of the structure without the hidden pages $navigation = $cache->getCache('cache', 'navigation.txt'); if(!$navigation) { - # use the structure as navigation if there is no difference + # use the structure if there is no cached navigation $navigation = $structure; } @@ -147,8 +148,8 @@ class PageController extends Controller $home = false; if(empty($args)) { - $home = true; - $item = Folder::getItemForUrl($navigation, $uri->getBasePath(), $uri->getBaseUrl(), NULL, $home); + $home = true; + $item = Folder::getItemForUrl($navigation, $uri->getBasePath(), $uri->getBaseUrl(), NULL, $home); $urlRel = $uri->getBasePath(); } else @@ -160,6 +161,13 @@ class PageController extends Controller # important to use the structure here so it is found, even if the item is hidden. $item = Folder::getItemForUrl($structure, $urlRel, $uri->getBasePath()); + # if the item is a folder and if that folder is not hidden + if($item && isset($item->hide) && !$item->hide) + { + # use the navigation instead of the structure so that hidden elements are erased + $item = Folder::getItemForUrl($navigation, $urlRel, $uri->getBaseUrl(), NULL, $home); + } + # if there is still no item, return a 404-page if(!$item) { @@ -177,31 +185,34 @@ class PageController extends Controller 'favicon' => $favicon )); } + } - if(!$item->hide) - { + + if(isset($item->hide)) + { + # if it is a hidden page + if($item->hide) + { # get breadcrumb for page and set pages active - # use navigation, the hidden pages won't get a breadcrumb - $breadcrumb = Folder::getBreadcrumb($navigation, $item->keyPathArray); + # use structure here because the hidden item is not part of the navigation + $breadcrumb = Folder::getBreadcrumb($structure, $item->keyPathArray); $breadcrumb = $this->c->dispatcher->dispatch('onBreadcrumbLoaded', new OnBreadcrumbLoaded($breadcrumb))->getData(); - # set pages active for navigation again - # Folder::getBreadcrumb($navigation, $item->keyPathArray); + # add the paging to the item + $item = Folder::getPagingForItem($structure, $item); + } + else + { + # get breadcrumb for page and set pages active + # use navigation, because it is used for frontend + $breadcrumb = Folder::getBreadcrumb($navigation, $item->keyPathArray); + $breadcrumb = $this->c->dispatcher->dispatch('onBreadcrumbLoaded', new OnBreadcrumbLoaded($breadcrumb))->getData(); # add the paging to the item $item = Folder::getPagingForItem($navigation, $item); } } - if(isset($item->hide) && $item->hide) - { - # delete the paging elements - $item->thisChapter = false; - $item->nextItem = false; - $item->prevItem = false; - $breadcrumb = false; - } - # dispatch the item $item = $this->c->dispatcher->dispatch('onItemLoaded', new OnItemLoaded($item))->getData(); @@ -212,13 +223,6 @@ class PageController extends Controller if($item->elementType == 'folder') { $filePath = $filePath . DIRECTORY_SEPARATOR . 'index.md'; - - # if folder is not hidden - if(isset($item->hide) && !$item->hide) - { - # use the navigation instead of the structure so that hidden elements are erased - $item = Folder::getItemForUrl($navigation, $urlRel, $uri->getBaseUrl(), NULL, $home); - } } # read the content of the file @@ -373,7 +377,7 @@ class PageController extends Controller $extended = $yaml->getYaml('cache', 'structure-extended.yaml'); # create an array of object with the whole content of the folder - $structure = Folder::getFolderContentDetails($pagetree, $extended, $uri->getBaseUrl(), $uri->getBasePath()); + # $structure = Folder::getFolderContentDetails($pagetree, $extended, $uri->getBaseUrl(), $uri->getBasePath()); # now update the extended structure if(!$extended) @@ -385,9 +389,16 @@ class PageController extends Controller $yaml->updateYaml('cache', 'structure-extended.yaml', $extended); # we have to update the structure with extended again - $structure = Folder::getFolderContentDetails($pagetree, $extended, $uri->getBaseUrl(), $uri->getBasePath()); + # $structure = Folder::getFolderContentDetails($pagetree, $extended, $uri->getBaseUrl(), $uri->getBasePath()); + } + else + { + $extended = false; } } + + # create an array of object with the whole content of the folder + $structure = Folder::getFolderContentDetails($pagetree, $extended, $uri->getBaseUrl(), $uri->getBasePath()); # cache structure $cache->updateCache('cache', 'structure.txt', 'lastCache.txt', $structure); @@ -410,6 +421,8 @@ class PageController extends Controller return $this->getCachedStructure($cache); } + # creates a file that holds all hide flags and navigation titles + # reads all meta-files and creates an array with url => ['hide' => bool, 'navtitle' => 'bla'] protected function createExtended($contentPath, $yaml, $structure, $extended = NULL) { if(!$extended) @@ -439,6 +452,7 @@ class PageController extends Controller return $extended; } + # checks if there is a hidden page, returns true on first find protected function containsHiddenPages($extended) { foreach($extended as $element) diff --git a/system/Models/Folder.php b/system/Models/Folder.php index 1df2d86..bed4c25 100644 --- a/system/Models/Folder.php +++ b/system/Models/Folder.php @@ -5,7 +5,7 @@ namespace Typemill\Models; use \URLify; class Folder -{ +{ /* * scans content of a folder (without recursion) @@ -363,42 +363,83 @@ class Folder if($item->elementType == 'folder') { - /* get the first element in the folder */ + # get the first element in the folder $item->nextItem = isset($item->folderContent[0]) ? clone($item->folderContent[0]) : false; } + # the item is a file or an empty folder if(!$item->nextItem) { + # walk to the next file in the same hierarchy $nextItemArray[$keyPos]++; - $item->nextItem = self::getItemWithKeyPath($content, $nextItemArray); + + # get the key of the last element in this hierarchy level + # if there is no chapter, then it is probably an empty first-level-folder. Count content to get the number of first level items + $lastKey = $item->thisChapter ? array_key_last($item->thisChapter->folderContent) : count($content); + + # as long as the nextItemArray is smaller than the last key in this hierarchy level, search for the next item + # this ensures that it does not stop if key is missing (e.g. if the next page is hidden) + while( ($nextItemArray[$keyPos] <= $lastKey) && !$item->nextItem = self::getItemWithKeyPath($content, $nextItemArray) ) + { + $nextItemArray[$keyPos]++; + } } + # there is no next file or folder in this level, so walk up the hierarchy to the next folder or file while(!$item->nextItem) { + # delete the array level with the current item, so you are in the parent folder array_pop($nextItemArray); + + # if the array is empty now, then you where in the base level already, so break if(empty($nextItemArray)) break; + + # define the key position where you are right now $newKeyPos = count($nextItemArray)-1; + + # go to the next position $nextItemArray[$newKeyPos]++; - $item->nextItem = self::getItemWithKeyPath($content, $nextItemArray); + + # search for 5 items in case there are some hidden elements + $maxlength = $nextItemArray[$newKeyPos]+5; + while( ($nextItemArray[$newKeyPos] <= $maxlength) && !$item->nextItem = self::getItemWithKeyPath($content, $nextItemArray) ) + { + $nextItemArray[$newKeyPos]++; + } } /************************ * ADD PREVIOUS ITEM * ************************/ - if($prevItemArray[$keyPos] > 0) + # check if element is the first in the array + $first = ($prevItemArray[$keyPos] == 0) ? true : false; + + if(!$first) { $prevItemArray[$keyPos]--; - $item->prevItem = self::getItemWithKeyPath($content, $prevItemArray); - if($item->prevItem && $item->prevItem->elementType == 'folder' && !empty($item->prevItem->folderContent)) + while($prevItemArray[$keyPos] >= 0 && !$item->prevItem = self::getItemWithKeyPath($content, $prevItemArray)) { - /* get last item in folder */ + $prevItemArray[$keyPos]--; + } + + # if no item is found, then all previous items are hidden, so set first item to true and it will walk up the array later + if(!$item->prevItem) + { + $first = true; + } + elseif($item->prevItem && $item->prevItem->elementType == 'folder' && !empty($item->prevItem->folderContent)) + { + # if the previous item is a folder, the get the last item of that folder $item->prevItem = self::getLastItemOfFolder($item->prevItem); } } - else + + # if it is the first item in the folder (or all other files are hidden) + if($first) { + # then the previous item is the containing chapter $item->prevItem = $item->thisChapter; } @@ -501,7 +542,9 @@ class Folder return $structure; } - /* get breadcrumb as copied array, set elements active in original and mark parent element in original */ + # get breadcrumb as copied array, + # set elements active in original + # mark parent element in original public static function getBreadcrumb($content, $searchArray, $i = NULL, $breadcrumb = NULL) { # if it is the first round, create an empty array @@ -522,6 +565,7 @@ class Folder { $item->activeParent = true; } + /* $item->active = true; if($i == count($searchArray)-2)