diff --git a/CHANGELOG.md b/CHANGELOG.md index d2d54c6e5..86cb40f0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ 1. [](#bugfix) * Handle `errors.display` system property better in admin plugin [admin#1452](https://github.com/getgrav/grav-plugin-admin/issues/1452) * Fix classes on non-http based protocol links [#2034](https://github.com/getgrav/grav/issues/2034) + * Fixed crash on IIS (Windows) with open_basedir in effect [#2053](https://github.com/getgrav/grav/issues/2053) # v1.4.5 ## 05/15/2018 diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 2ff049d9e..12afa7e88 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -1007,32 +1007,63 @@ class Pages throw new \RuntimeException('Fatal error when creating page instances.'); } - $content_exists = false; - $pages_found = new \GlobIterator($directory . '/*' . CONTENT_EXT); + // Build regular expression for all the allowed page extensions. + $page_extensions = $language->getFallbackPageExtensions(); + $regex = '/^[^\.]*(' . implode('|', array_map( + function ($str) { + return preg_quote($str, '/'); + }, + $page_extensions + )) . ')$/'; + + $folders = []; $page_found = null; - $page_extension = ''; + $last_modified = 0; - if ($pages_found && count($pages_found) > 0) { + $iterator = new \FilesystemIterator($directory); + /** @var \FilesystemIterator $file */ + foreach ($iterator as $file) { + $filename = $file->getFilename(); - $page_extensions = $language->getFallbackPageExtensions(); + // Ignore all hidden files if set. + if ($this->ignore_hidden && $filename && $filename[0] === '.') { + continue; + } - foreach ($page_extensions as $extension) { - foreach ($pages_found as $found) { - if ($found->isDir()) { - continue; - } - $regex = '/^[^\.]*' . preg_quote($extension, '/') . '$/'; - if (preg_match($regex, $found->getFilename())) { - $page_found = $found; - $page_extension = $extension; - break 2; - } + // Handle folders later. + if ($file->isDir()) { + // But ignore all folders in ignore list. + if (!\in_array($filename, $this->ignore_folders, true)) { + $folders[] = $file; + } + continue; + } + + // Ignore all files in ignore list. + if (\in_array($file->getBasename(), $this->ignore_files, true)) { + continue; + } + + // Update last modified date to match the last updated file in the folder. + $modified = $file->getMTime(); + if ($modified > $last_modified) { + $last_modified = $modified; + } + + // Page is the one that matches to $page_extensions list with the lowest index number. + if (preg_match($regex, $filename, $matches, PREG_OFFSET_CAPTURE)) { + $ext = $matches[1][0]; + + if ($page_found === null || array_search($ext, $page_extensions, true) < array_search($page_extension, $page_extensions, true)) { + $page_found = $file; + $page_extension = $ext; } } } - if ($parent && !empty($page_found)) { + $content_exists = false; + if ($parent && $page_found) { $page->init($page_found, $page_extension); $content_exists = true; @@ -1042,48 +1073,31 @@ class Pages } } - // set current modified of page - $last_modified = $page->modified(); + // Now handle all the folders under the page. + /** @var \FilesystemIterator $file */ + foreach ($folders as $file) { + $filename = $file->getFilename(); - $iterator = new \FilesystemIterator($directory); - - /** @var \DirectoryIterator $file */ - foreach ($iterator as $file) { - $name = $file->getFilename(); - - // Ignore all hidden files if set. - if ($this->ignore_hidden && $name && $name[0] === '.') { + // if folder contains separator, continue + if (Utils::contains($file->getFilename(), $config->get('system.param_sep', ':'))) { 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()); + } - // if folder contains separator, continue - if (Utils::contains($file->getFilename(), $config->get('system.param_sep', ':'))) { - continue; - } + $path = $directory . DS . $filename; + $child = $this->recurse($path, $page); - if (!$page->path()) { - $page->path($file->getPath()); - } + if (Utils::startsWith($filename, '_')) { + $child->routable(false); + } - $path = $directory . DS . $name; - $child = $this->recurse($path, $page); + $this->children[$page->path()][$child->path()] = ['slug' => $child->slug()]; - if (Utils::startsWith($name, '_')) { - $child->routable(false); - } - - $this->children[$page->path()][$child->path()] = ['slug' => $child->slug()]; - - if ($config->get('system.pages.events.page')) { - $this->grav->fireEvent('onFolderProcessed', new Event(['page' => $page])); - } + if ($config->get('system.pages.events.page')) { + $this->grav->fireEvent('onFolderProcessed', new Event(['page' => $page])); } }