/** * Recursive function to load & build page relationships. * * @param string $directory * @param Page|null $parent * @return Page * @throws \RuntimeException * @internal */ protected function recurse($directory, Page &$parent = null) { $directory = rtrim($directory, DS); $page = new Page(); /** @var Config $config */ $config = $this->grav['config']; /** @var Language $language */ $language = $this->grav['language']; // stuff to do at root page if ($parent === null) { // Fire event for memory and time consuming plugins... if ($config->get('system.pages.events.page')) { $this->grav->fireEvent('onBuildPagesInitialized'); } } $page->path($directory); if ($parent) { $page->parent($parent); } $page->orderDir($config->get('system.pages.order.dir')); $page->orderBy($config->get('system.pages.order.by')); // Add into instances if (!isset($this->instances[$page->path()])) { $this->instances[$page->path()] = $page; if ($parent && $page->path()) { $this->children[$parent->path()][$page->path()] = array('slug' => $page->slug()); } } else { throw new \RuntimeException('Fatal error when creating page instances.'); } $content_exists = false; $pages_found = glob($directory . '/*' . CONTENT_EXT); $page_extensions = $language->getFallbackPageExtensions(); if ($pages_found) { foreach ($page_extensions as $extension) { foreach ($pages_found as $found) { if (preg_match('/^.*\\/[0-9A-Za-z\\-\\_]+(' . $extension . ')$/', $found)) { $page_found = $found; $page_extension = $extension; break 2; } } } } if ($parent && !empty($page_found)) { $file = new \SplFileInfo($page_found); $page->init($file, $page_extension); $content_exists = true; if ($config->get('system.pages.events.page')) { $this->grav->fireEvent('onPageProcessed', new Event(['page' => $page])); } } // set current modified of page $last_modified = $page->modified(); /** @var \DirectoryIterator $file */ foreach (new \FilesystemIterator($directory) as $file) { $name = $file->getFilename(); // Ignore all hidden files if set. if ($this->ignore_hidden) { if ($name && $name[0] == '.') { continue; } } if ($file->isFile()) { // Update the last modified if it's newer than already found if (!in_array($file->getBasename(), $this->ignore_files) && ($modified = $file->getMTime()) > $last_modified) { $last_modified = $modified; } } elseif ($file->isDir() && !in_array($file->getFilename(), $this->ignore_folders)) { if (!$page->path()) { $page->path($file->getPath()); } $path = $directory . DS . $name; $child = $this->recurse($path, $page); if (Utils::startsWith($name, '_')) { $child->routable(false); } $this->children[$page->path()][$child->path()] = array('slug' => $child->slug()); if ($config->get('system.pages.events.page')) { $this->grav->fireEvent('onFolderProcessed', new Event(['page' => $page])); } } } // Set routability to false if no page found if (!$content_exists) { $page->routable(false); } // Override the modified and ID so that it takes the latest change into account $page->modified($last_modified); $page->id($last_modified . md5($page->filePath())); // Sort based on Defaults or Page Overridden sort order $this->children[$page->path()] = $this->sort($page); return $page; }
/** * Recursive function to load & build page relationships. * * @param string $directory * @param Page|null $parent * @return Page * @throws \RuntimeException * @internal */ protected function recurse($directory, Page &$parent = null) { $directory = rtrim($directory, DS); $iterator = new \DirectoryIterator($directory); $page = new Page(); /** @var Config $config */ $config = $this->grav['config']; $page->path($directory); if ($parent) { $page->parent($parent); } $page->orderDir($config->get('system.pages.order.dir')); $page->orderBy($config->get('system.pages.order.by')); // Add into instances if (!isset($this->instances[$page->path()])) { $this->instances[$page->path()] = $page; if ($parent && $page->path()) { $this->children[$parent->path()][$page->path()] = array('slug' => $page->slug()); } } else { throw new \RuntimeException('Fatal error when creating page instances.'); } // set current modified of page $last_modified = $page->modified(); // flat for content availability $content_exists = false; /** @var \DirectoryIterator $file */ foreach ($iterator as $file) { if ($file->isDot()) { continue; } $name = $file->getFilename(); if ($file->isFile()) { // Update the last modified if it's newer than already found if ($file->getBasename() !== '.DS_Store' && ($modified = $file->getMTime()) > $last_modified) { $last_modified = $modified; } if (preg_match('/^[^.].*' . CONTENT_EXT . '$/', $name)) { $page->init($file); $content_exists = true; if ($config->get('system.pages.events.page')) { $this->grav->fireEvent('onPageProcessed', new Event(['page' => $page])); } } } elseif ($file->isDir()) { if (!$page->path()) { $page->path($file->getPath()); } $path = $directory . DS . $name; $child = $this->recurse($path, $page); if (Utils::startsWith($name, '_')) { $child->routable(false); } $this->children[$page->path()][$child->path()] = array('slug' => $child->slug()); if ($config->get('system.pages.events.page')) { $this->grav->fireEvent('onFolderProcessed', new Event(['page' => $page])); } } } // Set routability to false if no page found if (!$content_exists) { $page->routable(false); } // Override the modified and ID so that it takes the latest change into account $page->modified($last_modified); $page->id($last_modified . md5($page->filePath())); // Sort based on Defaults or Page Overridden sort order $this->children[$page->path()] = $this->sort($page); return $page; }
/** * Returns the page creating it if it does not exist. * * @param $path * @return Page */ protected function getPage($path) { /** @var Pages $pages */ $pages = $this->grav['pages']; if ($path && $path[0] != '/') { $path = "/{$path}"; } $page = $path ? $pages->dispatch($path, true) : $pages->root(); if (!$page) { $slug = basename($path); $ppath = dirname($path); // Find or create parent(s). $parent = $this->getPage($ppath != '/' ? $ppath : ''); // Create page. $page = new Page(); $page->parent($parent); $page->filePath($parent->path() . '/' . $slug . '/' . $page->name()); // Add routing information. $pages->addPage($page, $path); // Determine page type. if (isset($this->session->{$page->route()})) { // Found the type and header from the session. $data = $this->session->{$page->route()}; $page->name($data['type'] . '.md'); $page->header(['title' => $data['title']]); $page->frontmatter(Yaml::dump((array) $page->header())); } else { // Find out the type by looking at the parent. $type = $parent->childType() ? $parent->childType() : $parent->blueprints()->get('child_type', 'default'); $page->name($type . CONTENT_EXT); $page->header(); } $page->modularTwig($slug[0] == '_'); } return $page; }
/** * Find the first available $item ('slug' | 'folder') for a page * Used when copying a page, to determine the first available slot * * @param string $item * @param Page $page * * @return string The first available slot */ protected function findFirstAvailable($item, $page) { if (!$page->parent()->children()) { return $page->{$item}(); } $withoutPrefix = function ($string) { $match = preg_split('/^[0-9]+\\./u', $string, 2, PREG_SPLIT_DELIM_CAPTURE); return isset($match[1]) ? $match[1] : $match[0]; }; $withoutPostfix = function ($string) { $match = preg_split('/-(\\d+)$/', $string, 2, PREG_SPLIT_DELIM_CAPTURE); return $match[0]; }; /* $appendedNumber = function ($string) { $match = preg_split('/-(\d+)$/', $string, 2, PREG_SPLIT_DELIM_CAPTURE); $append = (isset($match[1]) ? (int)$match[1] + 1 : 2); return $append; };*/ $highest = 1; $siblings = $page->parent()->children(); $findCorrectAppendedNumber = function ($item, $page_item, $highest) use($siblings, &$findCorrectAppendedNumber, &$withoutPrefix) { foreach ($siblings as $sibling) { if ($withoutPrefix($sibling->{$item}()) == ($highest === 1 ? $page_item : $page_item . '-' . $highest)) { $highest = $findCorrectAppendedNumber($item, $page_item, $highest + 1); return $highest; } } return $highest; }; $base = $withoutPrefix($withoutPostfix($page->{$item}())); $return = $base; $highest = $findCorrectAppendedNumber($item, $base, $highest); if ($highest > 1) { $return .= '-' . $highest; } return $return; }
/** * Returns the page creating it if it does not exist. * * @param $path * * @return Page */ public function getPage($path) { /** @var Pages $pages */ $pages = $this->grav['pages']; if ($path && $path[0] != '/') { $path = "/{$path}"; } $page = $path ? $pages->dispatch($path, true) : $pages->root(); if (!$page) { $slug = basename($path); if ($slug == '') { return null; } $ppath = str_replace('\\', '/', dirname($path)); // Find or create parent(s). $parent = $this->getPage($ppath != '/' ? $ppath : ''); // Create page. $page = new Page(); $page->parent($parent); $page->filePath($parent->path() . '/' . $slug . '/' . $page->name()); // Add routing information. $pages->addPage($page, $path); // Set if Modular $page->modularTwig($slug[0] == '_'); // Determine page type. if (isset($this->session->{$page->route()})) { // Found the type and header from the session. $data = $this->session->{$page->route()}; // Set the key header value $header = ['title' => $data['title']]; if (isset($data['visible'])) { if ($data['visible'] == '' || $data['visible']) { // if auto (ie '') $children = $page->parent()->children(); foreach ($children as $child) { if ($child->order()) { // set page order $page->order(1000); break; } } } if ($data['visible'] == 1 && !$page->order()) { $header['visible'] = $data['visible']; } } if ($data['name'] == 'modular') { $header['body_classes'] = 'modular'; } $name = $page->modular() ? str_replace('modular/', '', $data['name']) : $data['name']; $page->name($name . '.md'); // Fire new event to allow plugins to manipulate page frontmatter $this->grav->fireEvent('onAdminCreatePageFrontmatter', new Event(['header' => &$header])); $page->header($header); $page->frontmatter(Yaml::dump((array) $page->header(), 10, 2, false)); } else { // Find out the type by looking at the parent. $type = $parent->childType() ? $parent->childType() : $parent->blueprints()->get('child_type', 'default'); $page->name($type . CONTENT_EXT); $page->header(); } $page->modularTwig($slug[0] == '_'); } return $page; }
/** * Guess the intended visibility status based on other sibling folders * * @param \Grav\Common\Page\Page $page * * @return bool */ public function guessVisibility(Page $page) { $children = $page->parent()->children(); foreach ($children as $child) { if ($child->order()) { return true; } } return false; }
/** * Recursive function to load & build page relationships. * * @param string $directory * @param null $parent * @return Page * @throws \RuntimeException * @internal */ protected function recurse($directory = PAGES_DIR, Page &$parent = null) { $directory = rtrim($directory, DS); $iterator = new \DirectoryIterator($directory); $page = new Page(); $config = $this->grav['config']; $page->path($directory); if ($parent) { $page->parent($parent); } $page->orderDir($config->get('system.pages.order.dir')); $page->orderBy($config->get('system.pages.order.by')); // Add into instances if (!isset($this->instances[$page->path()])) { $this->instances[$page->path()] = $page; if ($parent && $page->path()) { $this->children[$parent->path()][$page->path()] = array('slug' => $page->slug()); } } else { throw new \RuntimeException('Fatal error when creating page instances.'); } $last_modified = 0; /** @var \DirectoryIterator $file */ foreach ($iterator as $file) { $name = $file->getFilename(); $date = $file->getMTime(); if ($date > $last_modified) { $last_modified = $date; } if ($file->isFile() && Utils::endsWith($name, CONTENT_EXT)) { $page->init($file); if ($config->get('system.pages.events.page')) { $this->grav->fireEvent('onPageProcessed', new Event(['page' => $page])); } } elseif ($file->isDir() && !$file->isDot()) { if (!$page->path()) { $page->path($file->getPath()); } $path = $directory . DS . $name; $child = $this->recurse($path, $page); if (Utils::startsWith($name, '_')) { $child->routable(false); } $this->children[$page->path()][$child->path()] = array('slug' => $child->slug()); // set the modified time if not already set if (!$page->date()) { $page->date($file->getMTime()); } // set the last modified time on pages $this->lastModified($file->getMTime()); if ($config->get('system.pages.events.page')) { $this->grav->fireEvent('onFolderProcessed', new Event(['page' => $page])); } } } // Override the modified and ID so that it takes the latest change // into account $page->modified($last_modified); $page->id($last_modified . md5($page->filePath())); // Sort based on Defaults or Page Overridden sort order $this->children[$page->path()] = $this->sort($page); return $page; }