From 467c33d3e1b86da086854766a3ff7ae01d561c89 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Wed, 16 Oct 2019 09:48:22 +0300 Subject: [PATCH 1/5] More phpstan issues --- .../src/Grav/Common/Page/Flex/PageObject.php | 18 +- .../src/Grav/Common/Page/Flex/PageStorage.php | 8 +- system/src/Grav/Common/Page/Page.php | 1 + system/src/Grav/Common/Page/Pages.php | 169 +++++++++++------- system/src/Grav/Common/Uri.php | 2 +- .../Grav/Framework/Flex/FlexCollection.php | 4 + .../Interfaces/FlexCollectionInterface.php | 7 + system/src/Grav/Installer/Install.php | 24 ++- tests/phpstan/phpstan.neon | 1 + 9 files changed, 155 insertions(+), 79 deletions(-) diff --git a/system/src/Grav/Common/Page/Flex/PageObject.php b/system/src/Grav/Common/Page/Flex/PageObject.php index 381d3ea49..cd61ec15d 100644 --- a/system/src/Grav/Common/Page/Flex/PageObject.php +++ b/system/src/Grav/Common/Page/Flex/PageObject.php @@ -17,7 +17,6 @@ use Grav\Common\Page\Flex\Traits\PageContentTrait; use Grav\Common\Page\Flex\Traits\PageLegacyTrait; use Grav\Common\Page\Flex\Traits\PageRoutableTrait; use Grav\Common\Page\Flex\Traits\PageTranslateTrait; -use Grav\Common\Page\Interfaces\PageInterface; use Grav\Common\Page\Pages; use Grav\Common\Utils; use Grav\Framework\Flex\FlexObject; @@ -144,6 +143,10 @@ class PageObject extends FlexPageObject return $instance; } + /** + * @param array $ordering + * @return PageCollection + */ protected function reorderSiblings(array $ordering) { $storageKey = $this->getStorageKey(); @@ -165,7 +168,8 @@ class PageObject extends FlexPageObject $parent = $this->parent(); /** @var PageCollection $siblings */ - $siblings = $parent ? $parent->children()->withVisible()->getCollection() : []; + $siblings = $parent ? $parent->children() : null; + $siblings = $siblings ? $siblings->withVisible()->getCollection() : null; if ($siblings) { $ordering = array_flip($ordering); if ($storageKey !== null) { @@ -182,6 +186,8 @@ class PageObject extends FlexPageObject } $siblings = $siblings->orderBy(['order' => 'ASC']); $siblings->removeElement($this); + } else { + $siblings = $this->getFlexDirectory()->createCollection([]); } return $siblings; @@ -496,7 +502,13 @@ class PageObject extends FlexPageObject // If parent changes and page is visible, move it to be the last item. if ($parent && !empty($elements['order']) && $parent !== $this->parent()) { - $elements['order'] = ((int)$parent->children()->visible()->sort(['order' => 'ASC'])->last()->order()) + 1; + $siblings = $parent->children(); + $siblings = $siblings ? $siblings->visible()->sort(['order' => 'ASC']) : null; + if ($siblings && $siblings->count()) { + $elements['order'] = ((int)$siblings->last()->order()) + 1; + } else { + $elements['order'] = 1; + } } $parentKey = $parent->getStorageKey(); diff --git a/system/src/Grav/Common/Page/Flex/PageStorage.php b/system/src/Grav/Common/Page/Flex/PageStorage.php index 4f80df984..3582584f7 100644 --- a/system/src/Grav/Common/Page/Flex/PageStorage.php +++ b/system/src/Grav/Common/Page/Flex/PageStorage.php @@ -14,6 +14,8 @@ namespace Grav\Common\Page\Flex; use Grav\Common\Debugger; use Grav\Common\Grav; use Grav\Common\Language\Language; +use Grav\Framework\File\MarkdownFile; +use Grav\Framework\File\YamlFile; use Grav\Framework\Flex\Storage\FolderStorage; use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; @@ -79,7 +81,11 @@ class PageStorage extends FolderStorage $path = $this->getPathFromKey($key); $file = $this->getFile($path); try { - $frontmatter = $file->frontmatter(); + if ($file instanceof MarkdownFile) { + $frontmatter = $file->frontmatter(); + } else { + $frontmatter = $file->raw(); + } } catch (\RuntimeException $e) { $frontmatter = 'ERROR: ' . $e->getMessage(); } diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index ed4544ff0..a04f18b8e 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -64,6 +64,7 @@ class Page implements PageInterface protected $redirect; protected $external_url; protected $items; + /** @var \stdClass */ protected $header; protected $frontmatter; protected $language; diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index eb0e30f4d..23f7a2c1e 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -24,7 +24,6 @@ use Grav\Common\Uri; use Grav\Common\Utils; use Grav\Framework\Flex\Flex; use Grav\Framework\Flex\FlexDirectory; -use Grav\Framework\Flex\Interfaces\FlexObjectInterface; use Grav\Framework\Flex\Interfaces\FlexTranslateInterface; use Grav\Plugin\Admin; use RocketTheme\Toolbox\Event\Event; @@ -38,10 +37,10 @@ class Pages /** @var Grav */ protected $grav; - /** @var FlexDirectory */ + /** @var FlexDirectory|null */ private $directory; - /** @var array|PageInterface[] */ + /** @var array */ protected $instances; /** @var array */ @@ -85,7 +84,7 @@ class Pages /** @var bool */ protected $initialized = false; - /** @var Types */ + /** @var Types|null */ protected static $types; /** @var string|null */ @@ -137,7 +136,7 @@ class Pages { if ($path !== null) { $path = trim($path, '/'); - $this->base = $path ? '/' . $path : null; + $this->base = $path ? '/' . $path : ''; $this->baseRoute = []; } @@ -295,16 +294,15 @@ class Pages */ public function instances() { - if (!$this->directory) { - return $this->instances; - } - $list = []; foreach ($this->instances as $path => $instance) { - if (!$instance instanceof PageInterface) { + if (is_string($instance) && $this->directory) { + /** @var PageInterface $instance */ $instance = $this->directory->getObject($instance, 'flex_key'); } - $list[$path] = $instance; + if ($instance instanceof PageInterface) { + $list[$path] = $instance; + } } return $list; @@ -333,9 +331,9 @@ class Pages $this->instances[$path] = $page; } $route = $page->route($route); - if ($page->parent()) { - $parentPath = $page->parent()->path() ?? ''; - $this->children[$parentPath][$path] = ['slug' => $page->slug()]; + $parent = $page->parent(); + if ($parent) { + $this->children[$parent->path() ?? ''][$path] = ['slug' => $page->slug()]; } $this->routes[$route] = $path; @@ -374,7 +372,7 @@ class Pages $uri = $this->grav['uri']; foreach ($context['taxonomies'] as $taxonomy) { $param = $uri->param(rawurlencode($taxonomy)); - $items = $param ? explode(',', $param) : []; + $items = is_string($param) ? explode(',', $param) : []; foreach ($items as $item) { $params['taxonomies'][$taxonomy][] = htmlspecialchars_decode(rawurldecode($item), ENT_QUOTES); } @@ -641,6 +639,10 @@ class Pages } $path = $page->path(); + if (null === $path) { + return []; + } + $children = $this->children[$path] ?? []; if (!$children) { @@ -662,7 +664,7 @@ class Pages /** * @param Collection $collection - * @param string|int $orderBy + * @param string $orderBy * @param string $orderDir * @param array|null $orderManual * @param int|null $sort_flags @@ -696,19 +698,25 @@ class Pages * * @param string $path The filesystem full path of the page * - * @return PageInterface - * @throws \Exception + * @return PageInterface|null + * @throws \RuntimeException */ public function get($path) { $instance = $this->instances[(string)$path] ?? null; + if (\is_string($instance)) { $instance = $this->directory ? $this->directory->getObject($instance, 'flex_key') : null; - if (method_exists($instance, 'initialize') && $this->grav['config']->get('system.pages.events.page')) { + if ($instance && method_exists($instance, 'initialize') && $this->grav['config']->get('system.pages.events.page')) { $instance->initialize(); } } - if ($instance && !$instance instanceof PageInterface) { + + if (null === $instance) { + return null; + } + + if (!$instance instanceof PageInterface) { throw new \RuntimeException('Routing failed on unknown type', 500); } @@ -808,10 +816,12 @@ class Pages $route = urldecode($route); // Fetch page if there's a defined route to it. - $page = isset($this->routes[$route]) ? $this->get($this->routes[$route]) : null; + $path = $this->routes[$route] ?? null; + $page = null !== $path ? $this->get($path) : null; // Try without trailing slash if (!$page && Utils::endsWith($route, '/')) { - $page = isset($this->routes[rtrim($route, '/')]) ? $this->get($this->routes[rtrim($route, '/')]) : null; + $path = $this->routes[rtrim($route, '/')] ?? null; + $page = null !== $path ? $this->get($path) : null; } // Are we in the admin? this is important! @@ -825,7 +835,7 @@ class Pages } // fall back and check site based redirects - if (!$page || ($page && !$page->routable())) { + if (!$page || !$page->routable()) { // Redirect to the first child (placeholder page) if ($redirect && $page && count($children = $page->children()->visible()) > 0) { $this->grav->redirectLangSafe($children->first()->route()); @@ -839,7 +849,6 @@ class Pages if ($site_route) { $page = $this->dispatch($site_route, $all, $redirect); } else { - /** @var Uri $uri */ $uri = $this->grav['uri']; /** @var \Grav\Framework\Uri\Uri $source_url */ @@ -849,10 +858,12 @@ class Pages $site_redirects = $config->get('site.redirects'); if (is_array($site_redirects)) { foreach ((array)$site_redirects as $pattern => $replace) { - $pattern = '#^' . str_replace('/', '\/', ltrim($pattern, '^')) . '#'; + $pattern = ltrim($pattern, '^'); + $pattern = '#^' . str_replace('/', '\/', $pattern) . '#'; try { + /** @var string $found */ $found = preg_replace($pattern, $replace, $source_url); - if ($found !== $source_url) { + if ($found && $found !== $source_url) { $this->grav->redirectLangSafe($found); } } catch (ErrorException $e) { @@ -867,8 +878,9 @@ class Pages foreach ((array)$site_routes as $pattern => $replace) { $pattern = '#^' . str_replace('/', '\/', ltrim($pattern, '^')) . '#'; try { + /** @var string $found */ $found = preg_replace($pattern, $replace, $source_url); - if ($found !== $source_url) { + if ($found && $found !== $source_url) { $page = $this->dispatch($found, $all, $redirect); } } catch (ErrorException $e) { @@ -887,13 +899,20 @@ class Pages * Get root page. * * @return PageInterface + * @throws \RuntimeException */ public function root() { /** @var UniformResourceLocator $locator */ $locator = $this->grav['locator']; - return $this->get(rtrim($locator->findResource('page://'), '/')); + $path = $locator->findResource('page://'); + $root = is_string($path) ? $this->get(rtrim($path, '/')) : null; + if (null === $root) { + throw new \RuntimeException('Internal error'); + } + + return $root; } /** @@ -928,7 +947,7 @@ class Pages * * @param PageInterface $current * - * @return \Grav\Common\Page\Collection + * @return Collection */ public function all(PageInterface $current = null) { @@ -1053,23 +1072,23 @@ class Pages */ public static function getTypes() { - if (!self::$types) { + if (null === self::$types) { $grav = Grav::instance(); - $scanBlueprintsAndTemplates = function () use ($grav) { + $scanBlueprintsAndTemplates = static function (Types $types) use ($grav) { // Scan blueprints $event = new Event(); - $event->types = self::$types; + $event->types = $types; $grav->fireEvent('onGetPageBlueprints', $event); - self::$types->scanBlueprints('theme://blueprints/'); + $types->scanBlueprints('theme://blueprints/'); // Scan templates $event = new Event(); - $event->types = self::$types; + $event->types = $types; $grav->fireEvent('onGetPageTemplates', $event); - self::$types->scanTemplates('theme://templates/'); + $types->scanTemplates('theme://templates/'); }; if ($grav['config']->get('system.cache.enabled')) { @@ -1078,21 +1097,21 @@ class Pages // Use cached types if possible. $types_cache_id = md5('types'); - self::$types = $cache->fetch($types_cache_id); + $types = $cache->fetch($types_cache_id); - if (!self::$types) { - self::$types = new Types(); - $scanBlueprintsAndTemplates(); - $cache->save($types_cache_id, self::$types); + if (!$types instanceof Types) { + $types = new Types(); + $scanBlueprintsAndTemplates($types); + $cache->save($types_cache_id, $types); } } else { - self::$types = new Types(); - $scanBlueprintsAndTemplates(); + $types = new Types(); + $scanBlueprintsAndTemplates($types); } // Register custom paths to the locator. $locator = $grav['locator']; - foreach (self::$types as $type => $paths) { + foreach ($types as $type => $paths) { foreach ($paths as $k => $path) { if (strpos($path, 'blueprints://') === 0) { unset($paths[$k]); @@ -1102,6 +1121,8 @@ class Pages $locator->addPath('blueprints', "pages/$type.yaml", $paths); } } + + self::$types = $types; } return self::$types; @@ -1142,7 +1163,7 @@ class Pages /** @var Admin $admin */ $admin = Grav::instance()['admin']; - /** @var PageInterface $page */ + /** @var PageInterface|null $page */ $page = $admin->page(); $type = $page && $page->modular() ? 'modular' : 'standard'; @@ -1167,7 +1188,7 @@ class Pages { $accessLevels = []; foreach ($this->all() as $page) { - if ($page && isset($page->header()->access)) { + if ($page instanceof PageInterface && isset($page->header()->access)) { if (\is_array($page->header()->access)) { foreach ($page->header()->access as $index => $accessLevel) { if (\is_array($accessLevel)) { @@ -1292,6 +1313,7 @@ class Pages $page->routable(true); $page->content('## Please install **Flex Objects** plugin. It is required to edit **Flex Pages**.'); + /** @var Header $header */ $header = $page->header(); $menu = $directory->getConfig('admin.menu.list'); $header->access = $menu['authorize'] ?? ['admin.pages', 'admin.super']; @@ -1321,20 +1343,18 @@ class Pages $debugger->startTimer('build-pages', 'Init frontend routes'); if ($this->directory) { - $this->buildFlexPages(); + $this->buildFlexPages($this->directory); } else { $this->buildRegularPages(); } $debugger->stopTimer('build-pages'); } - protected function buildFlexPages() + protected function buildFlexPages(FlexDirectory $directory) { /** @var Config $config */ $config = $this->grav['config']; - $directory = $this->directory; - // TODO: right now we are just emulating normal pages, it is inefficient and bad... but works! $collection = $directory->getIndex(); $cache = $directory->getCache('index'); @@ -1370,10 +1390,13 @@ class Pages /** * @var string $key - * @var PageInterface|FlexObjectInterface $page + * @var PageInterface $page */ foreach ($collection as $key => $page) { $path = $page->path(); + if (null === $path) { + throw new \RuntimeException('Internal error'); + } if ($page instanceof FlexTranslateInterface) { $page = $page && $page->hasTranslation() ? $page->getTranslation() : null; @@ -1435,12 +1458,16 @@ class Pages /** @var UniformResourceLocator $locator */ $locator = $grav['locator']; + $path = $locator->findResource('page://'); + if (!is_string($path)) { + throw new \RuntimeException('Internal Error'); + } /** @var Config $config */ $config = $grav['config']; $page = new Page(); - $page->path($locator->findResource('page://')); + $page->path($path); $page->orderDir($config->get('system.pages.order.dir')); $page->orderBy($config->get('system.pages.order.by')); $page->modified(0); @@ -1460,6 +1487,9 @@ class Pages $locator = $this->grav['locator']; $pages_dir = $locator->findResource('page://'); + if (!is_string($pages_dir)) { + throw new \RuntimeException('Internal Error'); + } if ($config->get('system.cache.enabled')) { /** @var Language $language */ @@ -1689,7 +1719,7 @@ class Pages // 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())); + $page->id($last_modified . md5($page->filePath() ?? '')); // Sort based on Defaults or Page Overridden sort order $this->children[$page->path()] = $this->sort($page); @@ -1708,7 +1738,7 @@ class Pages // Get the home route $home = self::resetHomeRoute(); // Build routes and taxonomy map. - /** @var PageInterface $page */ + /** @var PageInterface|string $page */ foreach ($this->instances as $path => $page) { if (\is_string($page)) { $page = $this->get($path); @@ -1721,9 +1751,13 @@ class Pages // process taxonomy $taxonomy->addTaxonomy($page); + $page_path = $page->path(); + if (null === $page_path) { + throw new \RuntimeException('Internal Error'); + } + $route = $page->route(); $raw_route = $page->rawRoute(); - $page_path = $page->path(); // add regular route $this->routes[$route] = $page_path; @@ -1751,8 +1785,11 @@ class Pages // Alias and set default route to home page. $homeRoute = "/{$home}"; if ($home && isset($this->routes[$homeRoute])) { - $this->routes['/'] = $this->routes[$homeRoute]; - $this->get($this->routes[$homeRoute])->route('/'); + $home = $this->get($this->routes[$homeRoute]); + if ($home) { + $this->routes['/'] = $this->routes[$homeRoute]; + $home->route('/'); + } } } @@ -1769,15 +1806,14 @@ class Pages protected function buildSort($path, array $pages, $order_by = 'default', $manual = null, $sort_flags = null) { $list = []; - $header_default = null; $header_query = null; + $header_default = null; // do this header query work only once if (strpos($order_by, 'header.') === 0) { - $header_query = explode('|', str_replace('header.', '', $order_by)); - if (isset($header_query[1])) { - $header_default = $header_query[1]; - } + $query = explode('|', str_replace('header.', '', $order_by), 2); + $header_query = array_shift($query); + $header_default = array_shift($query); } foreach ($pages as $key => $info) { @@ -1815,12 +1851,12 @@ class Pages case 'folder': $list[$key] = $child->folder(); break; - case (is_string($header_query[0])): + case (is_string($header_query)): $child_header = $child->header(); if (!$child_header instanceof Header) { $child_header = new Header((array)$child_header); } - $header_value = $child_header->get($header_query[0]); + $header_value = $child_header->get($header_query); if (is_array($header_value)) { $list[$key] = implode(',', $header_value); } elseif ($header_value) { @@ -1848,13 +1884,16 @@ class Pages } else { // else just sort the list according to specified key if (extension_loaded('intl') && $this->grav['config']->get('system.intl_enabled')) { - $locale = setlocale(LC_COLLATE, 0); //`setlocale` with a 0 param returns the current locale set + $locale = setlocale(LC_COLLATE, '0'); //`setlocale` with a '0' param returns the current locale set $col = Collator::create($locale); if ($col) { if (($sort_flags & SORT_NATURAL) === SORT_NATURAL) { - $list = preg_replace_callback('~([0-9]+)\.~', function ($number) { + $list = preg_replace_callback('~([0-9]+)\.~', static function ($number) { return sprintf('%032d.', $number[0]); }, $list); + if (!is_array($list)) { + throw new \RuntimeException('Internal Error'); + } $list_vals = array_values($list); if (is_numeric(array_shift($list_vals))) { diff --git a/system/src/Grav/Common/Uri.php b/system/src/Grav/Common/Uri.php index 2a46847f1..dc2c43266 100644 --- a/system/src/Grav/Common/Uri.php +++ b/system/src/Grav/Common/Uri.php @@ -301,7 +301,7 @@ class Uri * Get URI parameter. * * @param string $id - * @param bool $default + * @param string|bool|null $default * * @return bool|string */ diff --git a/system/src/Grav/Framework/Flex/FlexCollection.php b/system/src/Grav/Framework/Flex/FlexCollection.php index 50753b119..ab05b2eba 100644 --- a/system/src/Grav/Framework/Flex/FlexCollection.php +++ b/system/src/Grav/Framework/Flex/FlexCollection.php @@ -300,6 +300,10 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface return $this->getFlexDirectory()->getIndex($this->getKeys(), $this->getKeyField()); } + /** + * @inheritdoc} + * @see FlexCollectionInterface::getCollection() + */ public function getCollection() { return $this; diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexCollectionInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexCollectionInterface.php index 0188401b0..35ab6461d 100644 --- a/system/src/Grav/Framework/Flex/Interfaces/FlexCollectionInterface.php +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexCollectionInterface.php @@ -122,6 +122,13 @@ interface FlexCollectionInterface extends FlexCommonInterface, ObjectCollectionI */ public function getIndex(); + /** + * Load all the objects into memory, + * + * @return FlexCollectionInterface + */ + public function getCollection(); + /** * Get metadata associated to the object * diff --git a/system/src/Grav/Installer/Install.php b/system/src/Grav/Installer/Install.php index dc7d556e9..ee9900868 100644 --- a/system/src/Grav/Installer/Install.php +++ b/system/src/Grav/Installer/Install.php @@ -29,14 +29,15 @@ class Install '7.3' => '7.3.1', '7.2' => '7.2.0', '7.1' => '7.1.3', - '' => '7.2.14' + '' => '7.3.9' ] ], 'grav' => [ 'name' => 'Grav', 'versions' => [ + '1.6' => '1.6.0', '1.5' => '1.5.0', - '' => '1.5.7' + '' => '1.6.16' ] ], 'plugins' => [ @@ -44,32 +45,36 @@ class Install 'name' => 'Admin', 'optional' => true, 'versions' => [ + '1.9' => '1.9.0', '1.8' => '1.8.0', - '' => '1.8.16' + '' => '1.9.10' ] ], 'email' => [ 'name' => 'Email', 'optional' => true, 'versions' => [ + '3.0' => '3.0.0', '2.7' => '2.7.0', - '' => '2.7.2' + '' => '3.0.3' ] ], 'form' => [ 'name' => 'Form', 'optional' => true, 'versions' => [ + '3.0' => '3.0.0', '2.16' => '2.16.0', - '' => '2.16.4' + '' => '3.0.9' ] ], 'login' => [ 'name' => 'Login', 'optional' => true, 'versions' => [ + '3.0' => '3.0.0', '2.8' => '2.8.0', - '' => '2.8.3' + '' => '3.0.4' ] ], ] @@ -157,9 +162,10 @@ class Install public function prepare(): void { // Locate the new Grav update and the target site from the filesystem. - $location = dirname(realpath(__DIR__), 4); - $target = dirname(realpath(GRAV_ROOT . '/index.php')); - if ($location === $target) { + $location = realpath(__DIR__); + $target = realpath(GRAV_ROOT . '/index.php'); + + if ($location && $target && dirname($location, 4) === dirname($target)) { // We cannot copy files into themselves, abort! throw new \RuntimeException('Grav has already been installed here!', 400); } diff --git a/tests/phpstan/phpstan.neon b/tests/phpstan/phpstan.neon index 919548ab3..05b46dc6c 100644 --- a/tests/phpstan/phpstan.neon +++ b/tests/phpstan/phpstan.neon @@ -17,6 +17,7 @@ parameters: - Grav\Common\GPM\Common\Package - Grav\Common\GPM\Local\Package - Grav\Common\GPM\Remote\Package + - Grav\Common\Page\Header - Grav\Common\Session ignoreErrors: From 2db04e43d1e5fd23cea0a0a4090861d46caf230f Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Wed, 16 Oct 2019 12:00:43 +0300 Subject: [PATCH 2/5] Hide accounts and pages from flex types page (frontend) --- system/blueprints/flex/accounts.yaml | 1 + system/blueprints/flex/pages.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/system/blueprints/flex/accounts.yaml b/system/blueprints/flex/accounts.yaml index 652a59663..5deafacfc 100644 --- a/system/blueprints/flex/accounts.yaml +++ b/system/blueprints/flex/accounts.yaml @@ -34,6 +34,7 @@ config: dir: asc site: + hidden: true templates: collection: paths: diff --git a/system/blueprints/flex/pages.yaml b/system/blueprints/flex/pages.yaml index 524acea30..a65570ef6 100644 --- a/system/blueprints/flex/pages.yaml +++ b/system/blueprints/flex/pages.yaml @@ -92,6 +92,7 @@ config: label: PLUGIN_ADMIN.SAVE site: + hidden: true templates: collection: paths: From 7902912269dac1828fa0f32376af67ebf5e69c8b Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Wed, 16 Oct 2019 14:00:37 +0300 Subject: [PATCH 3/5] Added `template_from_string()` twig function --- CHANGELOG.md | 1 + system/src/Grav/Common/Twig/Twig.php | 2 ++ 2 files changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78fc4431f..6a39ff8cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Added `Flex Pages` to Grav core and removed Flex Objects plugin dependency * Added `Utils::simpleTemplate()` method for very simple variable templating * Added `array_diff()` twig function + * Added `template_from_string()` twig function 1. [](#improved) * Improved `Flex Users`: obey blueprints and allow Flex to be used in admin only * Improved `Flex` to support custom site template paths diff --git a/system/src/Grav/Common/Twig/Twig.php b/system/src/Grav/Common/Twig/Twig.php index 93b152a8e..63e769061 100644 --- a/system/src/Grav/Common/Twig/Twig.php +++ b/system/src/Grav/Common/Twig/Twig.php @@ -23,6 +23,7 @@ use Twig\Environment; use Twig\Error\LoaderError; use Twig\Extension\CoreExtension; use Twig\Extension\DebugExtension; +use Twig\Extension\StringLoaderExtension; use Twig\Loader\ArrayLoader; use Twig\Loader\ChainLoader; use Twig\Loader\FilesystemLoader; @@ -198,6 +199,7 @@ class Twig } $this->twig->addExtension(new TwigExtension()); $this->twig->addExtension(new DeferredExtension()); + $this->twig->addExtension(new StringLoaderExtension()); $this->profile = new \Twig\Profiler\Profile(); $this->twig->addExtension(new \Twig\Extension\ProfilerExtension($this->profile)); From 14b33824b1eac894942a20773cf7506c5623dcd1 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Wed, 16 Oct 2019 14:01:30 +0300 Subject: [PATCH 4/5] Added mime support for file formatters --- CHANGELOG.md | 1 + .../Framework/File/Formatter/AbstractFormatter.php | 10 ++++++++++ .../src/Grav/Framework/File/Formatter/CsvFormatter.php | 3 ++- .../File/Interfaces/FileFormatterInterface.php | 6 ++++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a39ff8cd..4e41526fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * Improved `Flex Users`: obey blueprints and allow Flex to be used in admin only * Improved `Flex` to support custom site template paths * Changed Twig `{% cache %}` tag to not need unique key, and `lifetime` is now optional + * Added mime support for file formatters 1. [](#bugfix) * Fixed `Page::untranslatedLanguages()` not being symmetrical to `Page::translatedLanguages()` * Fixed `Flex Pages` not calling `onPageProcessed` event when cached diff --git a/system/src/Grav/Framework/File/Formatter/AbstractFormatter.php b/system/src/Grav/Framework/File/Formatter/AbstractFormatter.php index bd8e0c025..ee5f79956 100644 --- a/system/src/Grav/Framework/File/Formatter/AbstractFormatter.php +++ b/system/src/Grav/Framework/File/Formatter/AbstractFormatter.php @@ -48,6 +48,16 @@ abstract class AbstractFormatter implements FileFormatterInterface $this->doUnserialize(unserialize($serialized, ['allowed_classes' => false])); } + /** + * @return string + */ + public function getMimeType(): string + { + $mime = $this->getConfig('mime'); + + return \is_string($mime) ? $mime : 'application/octet-stream'; + } + /** * {@inheritdoc} * @see FileFormatterInterface::getDefaultFileExtension() diff --git a/system/src/Grav/Framework/File/Formatter/CsvFormatter.php b/system/src/Grav/Framework/File/Formatter/CsvFormatter.php index 84db79a79..d42249696 100644 --- a/system/src/Grav/Framework/File/Formatter/CsvFormatter.php +++ b/system/src/Grav/Framework/File/Formatter/CsvFormatter.php @@ -23,7 +23,8 @@ class CsvFormatter extends AbstractFormatter { $config += [ 'file_extension' => ['.csv', '.tsv'], - 'delimiter' => ',' + 'delimiter' => ',', + 'mime' => 'text/x-csv' ]; parent::__construct($config); diff --git a/system/src/Grav/Framework/File/Interfaces/FileFormatterInterface.php b/system/src/Grav/Framework/File/Interfaces/FileFormatterInterface.php index f7b36e20c..86457318b 100644 --- a/system/src/Grav/Framework/File/Interfaces/FileFormatterInterface.php +++ b/system/src/Grav/Framework/File/Interfaces/FileFormatterInterface.php @@ -26,6 +26,12 @@ namespace Grav\Framework\File\Interfaces; */ interface FileFormatterInterface extends \Serializable { + /** + * @return string + * @since 1.7 + */ + public function getMimeType(): string; + /** * Get default file extension from current formatter (with dot). * From 1656f0160b5078210c98dc70ffca1073eb28ec02 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Wed, 16 Oct 2019 14:01:48 +0300 Subject: [PATCH 5/5] Enabled preview for pages --- system/blueprints/flex/pages.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/system/blueprints/flex/pages.yaml b/system/blueprints/flex/pages.yaml index a65570ef6..8c4af1c5c 100644 --- a/system/blueprints/flex/pages.yaml +++ b/system/blueprints/flex/pages.yaml @@ -91,6 +91,10 @@ config: icon: check label: PLUGIN_ADMIN.SAVE + # Preview View + preview: + enabled: true + site: hidden: true templates: