From afc18236c2d43907b96577272dff517ddc037640 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 24 Oct 2016 10:13:21 -0600 Subject: [PATCH 01/56] Fixed issue with site redirects/routes not processing with extensions --- CHANGELOG.md | 6 ++++++ system/src/Grav/Common/Page/Pages.php | 14 ++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8e44f6fb..837f1b2a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v1.1.9 +## xx/xx/2016 + +1. [](#bugfix) + * Fixed an issue with site redirects/routes, not processing with extension (.html, .json, etc.) + # v1.1.8 ## 10/22/2016 diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 719f48937..0b7691b4a 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -342,13 +342,19 @@ class Pages $page = $this->dispatch($route, $all); } else { // Try Regex style redirects + $source_url = $url; + $extension = $this->grav['uri']->extension(); + if (isset($extension)) { + $source_url.= '.' . $extension; + } + $site_redirects = $config->get("site.redirects"); if (is_array($site_redirects)) { foreach ((array)$site_redirects as $pattern => $replace) { $pattern = '#' . $pattern . '#'; try { - $found = preg_replace($pattern, $replace, $url); - if ($found != $url) { + $found = preg_replace($pattern, $replace, $source_url); + if ($found != $source_url) { $this->grav->redirectLangSafe($found); } } catch (ErrorException $e) { @@ -363,8 +369,8 @@ class Pages foreach ((array)$site_routes as $pattern => $replace) { $pattern = '#' . $pattern . '#'; try { - $found = preg_replace($pattern, $replace, $url); - if ($found != $url) { + $found = preg_replace($pattern, $replace, $source_url); + if ($found != $source_url) { $page = $this->dispatch($found, $all); } } catch (ErrorException $e) { From cd15b9197b8cda585e07ee1d5144a67da2281f4c Mon Sep 17 00:00:00 2001 From: Adam Roe Date: Wed, 26 Oct 2016 00:25:56 +1000 Subject: [PATCH 02/56] Don't truncate HTML if content length is less than summary size (#1125), fixes #1114 --- system/src/Grav/Common/Page/Page.php | 2 +- system/src/Grav/Common/Utils.php | 6 +++++- tests/unit/Grav/Common/UtilsTest.php | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 0806fff9e..fbf3ebdc3 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -507,7 +507,7 @@ class Page } $summary = Utils::truncateHTML($content, $size); - + return html_entity_decode($summary); } diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index c63aa8ffe..c7b9bb4e2 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -188,7 +188,11 @@ abstract class Utils */ public static function truncateHtml($text, $length = 100, $ellipsis = '...') { - return Truncator::truncateLetters($text, $length, $ellipsis); + if (mb_strlen($text) <= $length) { + return $text; + } else { + return Truncator::truncateLetters($text, $length, $ellipsis); + } } /** diff --git a/tests/unit/Grav/Common/UtilsTest.php b/tests/unit/Grav/Common/UtilsTest.php index d45eee356..61149f239 100644 --- a/tests/unit/Grav/Common/UtilsTest.php +++ b/tests/unit/Grav/Common/UtilsTest.php @@ -129,6 +129,7 @@ class UtilsTest extends \Codeception\TestCase\Test $this->assertEquals('

This is a string to truncate

', Utils::truncateHtml('

This is a string to truncate

', 100)); $this->assertEquals('', Utils::truncateHtml('', 6)); $this->assertEquals('
  1. item 1 so...
', Utils::truncateHtml('
  1. item 1 something
  2. item 2 bold
', 10)); + $this->assertEquals("

This is a string.

\n

It splits two lines.

", Utils::truncateHtml("

This is a string.

\n

It splits two lines.

", 100)); } public function testSafeTruncateHtml() From 1c32f4eaee72485b53af01509ee3567a0a502c20 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Tue, 25 Oct 2016 16:27:24 +0200 Subject: [PATCH 03/56] Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 837f1b2a7..57b86b2d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 1. [](#bugfix) * Fixed an issue with site redirects/routes, not processing with extension (.html, .json, etc.) + * Don't truncate HTML if content length is less than summary size [#1125](https://github.com/getgrav/grav/issues/1125) # v1.1.8 ## 10/22/2016 From 8e1454b3abf0c72c13951cbf6003205ca742358f Mon Sep 17 00:00:00 2001 From: Gilles van Eeden Date: Tue, 25 Oct 2016 16:32:18 +0200 Subject: [PATCH 04/56] functions added to taxonomy and twigextension (#1124) * Update Taxonomy.php * Update TwigExtension.php * Update TwigExtension.php Incorrect comment updated. --- system/src/Grav/Common/Taxonomy.php | 16 ++++++++++++++++ system/src/Grav/Common/Twig/TwigExtension.php | 15 +++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/system/src/Grav/Common/Taxonomy.php b/system/src/Grav/Common/Taxonomy.php index f4c49ab3d..37975f7a1 100644 --- a/system/src/Grav/Common/Taxonomy.php +++ b/system/src/Grav/Common/Taxonomy.php @@ -126,4 +126,20 @@ class Taxonomy return $this->taxonomy_map; } + + /** + * Gets item keys per taxonomy + * + * @param string $taxonomy taxonomy name + * + * @return array keys of this taxonomy + */ + public function getTaxonomyItemKeys($taxonomy) { + if (isset($this->taxonomy_map[$taxonomy])) { + + $results = array_keys($this->taxonomy_map[$taxonomy]); + + return $results; + } + } } diff --git a/system/src/Grav/Common/Twig/TwigExtension.php b/system/src/Grav/Common/Twig/TwigExtension.php index f67e441f2..c0a615392 100644 --- a/system/src/Grav/Common/Twig/TwigExtension.php +++ b/system/src/Grav/Common/Twig/TwigExtension.php @@ -115,6 +115,7 @@ class TwigExtension extends \Twig_Extension new \Twig_SimpleFunction('url', [$this, 'urlFunc']), new \Twig_SimpleFunction('json_decode', [$this, 'jsonDecodeFilter']), new \Twig_SimpleFunction('get_cookie', [$this, 'getCookie']), + new \Twig_SimpleFunction('redirect_me', [$this, 'redirectFunc']), ]; } @@ -820,4 +821,18 @@ class TwigExtension extends \Twig_Extension { return preg_replace($pattern, $replace, $subject, $limit); } + + /** + * redirect browser from twig + * + * @param string $url the url to redirect to + * @param string $statusCode statuscode, default 303 + * + * @return none + */ + public function redirectFunc($url, $statusCode = 303) + { + header('Location: ' . $url, true, $statusCode); + die(); + } } From c3aa11abeb586f4333a9c572762059f764e82d0a Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Tue, 25 Oct 2016 16:33:57 +0200 Subject: [PATCH 05/56] Changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57b86b2d0..21510f85f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # v1.1.9 ## xx/xx/2016 +1. [](#improved) + * Added `getTaxonomyItemKeys` to the Taxonomy object [#1124](https://github.com/getgrav/grav/issues/1124) + * Added a `redirect_me` Twig function [#1124](https://github.com/getgrav/grav/issues/1124) 1. [](#bugfix) * Fixed an issue with site redirects/routes, not processing with extension (.html, .json, etc.) * Don't truncate HTML if content length is less than summary size [#1125](https://github.com/getgrav/grav/issues/1125) From af53d79e5ee5f9cdc407b799a204c79897bf21d7 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Tue, 25 Oct 2016 18:58:52 +0200 Subject: [PATCH 06/56] Add Caddyfile for newer Caddy versions #1115 --- CHANGELOG.md | 1 + webserver-configs/Caddyfile | 10 ++++++---- webserver-configs/Caddyfile-0.8.x | 33 +++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 webserver-configs/Caddyfile-0.8.x diff --git a/CHANGELOG.md b/CHANGELOG.md index 21510f85f..02fbbab13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ 1. [](#improved) * Added `getTaxonomyItemKeys` to the Taxonomy object [#1124](https://github.com/getgrav/grav/issues/1124) * Added a `redirect_me` Twig function [#1124](https://github.com/getgrav/grav/issues/1124) + * Added a Caddyfile for newer Caddy versions [#1115](https://github.com/getgrav/grav/issues/1115) 1. [](#bugfix) * Fixed an issue with site redirects/routes, not processing with extension (.html, .json, etc.) * Don't truncate HTML if content length is less than summary size [#1125](https://github.com/getgrav/grav/issues/1125) diff --git a/webserver-configs/Caddyfile b/webserver-configs/Caddyfile index 682947087..9d3b43760 100644 --- a/webserver-configs/Caddyfile +++ b/webserver-configs/Caddyfile @@ -6,23 +6,25 @@ fastcgi / 127.0.0.1:9000 php # deny all direct access for these folders rewrite { r /(.git|cache|bin|logs|backups|tests)/.*$ - status 403 + to /403 } # deny running scripts inside core system folders rewrite { r /(system|vendor)/.*\.(txt|xml|md|html|yaml|php|pl|py|cgi|twig|sh|bat)$ - status 403 + to /403 } # deny running scripts inside user folder rewrite { r /user/.*\.(txt|md|yaml|php|pl|py|cgi|twig|sh|bat)$ - status 403 + to /403 } # deny access to specific files in the root folder rewrite { r /(LICENSE.txt|composer.lock|composer.json|nginx.conf|web.config|htaccess.txt|\.htaccess) - status 403 + to /403 } + +status 403 /403 ## End - Security # global rewrite should come last. diff --git a/webserver-configs/Caddyfile-0.8.x b/webserver-configs/Caddyfile-0.8.x new file mode 100644 index 000000000..520eafb42 --- /dev/null +++ b/webserver-configs/Caddyfile-0.8.x @@ -0,0 +1,33 @@ +# Caddyfile for Caddy 0.8.x and below + +:8080 +gzip +fastcgi / 127.0.0.1:9000 php + +# Begin - Security +# deny all direct access for these folders +rewrite { + r /(.git|cache|bin|logs|backups|tests)/.*$ + status 403 +} +# deny running scripts inside core system folders +rewrite { + r /(system|vendor)/.*\.(txt|xml|md|html|yaml|php|pl|py|cgi|twig|sh|bat)$ + status 403 +} +# deny running scripts inside user folder +rewrite { + r /user/.*\.(txt|md|yaml|php|pl|py|cgi|twig|sh|bat)$ + status 403 +} +# deny access to specific files in the root folder +rewrite { + r /(LICENSE.txt|composer.lock|composer.json|nginx.conf|web.config|htaccess.txt|\.htaccess) + status 403 +} +## End - Security + +# global rewrite should come last. +rewrite { + to {path} {path}/ /index.php?_url={uri} +} From 37b8ffb7d23b40ea799acd1112d806ba0b5e5a05 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Thu, 27 Oct 2016 21:04:25 +0200 Subject: [PATCH 07/56] Fix #1135 return max available number of items when calling random() on a collection passing an int > available items --- CHANGELOG.md | 1 + system/src/Grav/Common/Iterator.php | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02fbbab13..1961a8695 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ 1. [](#bugfix) * Fixed an issue with site redirects/routes, not processing with extension (.html, .json, etc.) * Don't truncate HTML if content length is less than summary size [#1125](https://github.com/getgrav/grav/issues/1125) + * Return max available number when calling random() on a collection passing an int > available items [#1135](https://github.com/getgrav/grav/issues/1135) # v1.1.8 ## 10/22/2016 diff --git a/system/src/Grav/Common/Iterator.php b/system/src/Grav/Common/Iterator.php index ad5722dfc..2618c1064 100644 --- a/system/src/Grav/Common/Iterator.php +++ b/system/src/Grav/Common/Iterator.php @@ -189,6 +189,10 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable */ public function random($num = 1) { + if ($num > count($this->items)) { + $num = count($this->items); + } + $this->items = array_intersect_key($this->items, array_flip((array)array_rand($this->items, $num))); return $this; From 76aed8a1190f53bbe3794dabaa03f69a3b9e8dc6 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Fri, 28 Oct 2016 13:49:11 -0600 Subject: [PATCH 08/56] Added CompiledJsonFile --- CHANGELOG.md | 2 ++ system/src/Grav/Common/File/CompiledJsonFile.php | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 system/src/Grav/Common/File/CompiledJsonFile.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 1961a8695..046490832 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # v1.1.9 ## xx/xx/2016 +1. [](#new) + * Added a `CompiledJsonFile` object to better handle Json files. 1. [](#improved) * Added `getTaxonomyItemKeys` to the Taxonomy object [#1124](https://github.com/getgrav/grav/issues/1124) * Added a `redirect_me` Twig function [#1124](https://github.com/getgrav/grav/issues/1124) diff --git a/system/src/Grav/Common/File/CompiledJsonFile.php b/system/src/Grav/Common/File/CompiledJsonFile.php new file mode 100644 index 000000000..8933a2e25 --- /dev/null +++ b/system/src/Grav/Common/File/CompiledJsonFile.php @@ -0,0 +1,16 @@ + Date: Tue, 1 Nov 2016 13:52:50 +0100 Subject: [PATCH 09/56] Use correct ratio when applying image filters to image alternatives (#1147) Because of a previous change, the keys of the image alternatives array is no longer the ratio, but rather the image width. We now make sure to calculate the ratio correctly and use the appropriate one when applying the image filters. --- system/src/Grav/Common/Page/Media.php | 3 ++- system/src/Grav/Common/Page/Medium/ImageMedium.php | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/system/src/Grav/Common/Page/Media.php b/system/src/Grav/Common/Page/Media.php index c4451e08c..35baab6ab 100644 --- a/system/src/Grav/Common/Page/Media.php +++ b/system/src/Grav/Common/Page/Media.php @@ -110,8 +110,9 @@ class Media extends Getters $types['alternative'][$i] = MediumFactory::scaledFromMedium($alternatives[$max]['file'], $max, $i); } - foreach ($types['alternative'] as $ratio => $altMedium) { + foreach ($types['alternative'] as $altMedium) { if ($altMedium['file'] != $medium) { + $ratio = $altMedium['file']->get('width') / $medium->get('width'); $medium->addAlternative($ratio, $altMedium['file']); } } diff --git a/system/src/Grav/Common/Page/Medium/ImageMedium.php b/system/src/Grav/Common/Page/Medium/ImageMedium.php index a2bb7b169..c6c1b7180 100644 --- a/system/src/Grav/Common/Page/Medium/ImageMedium.php +++ b/system/src/Grav/Common/Page/Medium/ImageMedium.php @@ -497,7 +497,7 @@ class ImageMedium extends Medium try { call_user_func_array([$this->image, $method], $args); - foreach ($this->alternatives as $ratio => $medium) { + foreach ($this->alternatives as $medium) { if (!$medium->image) { $medium->image(); } @@ -509,7 +509,7 @@ class ImageMedium extends Medium if (isset(self::$magic_resize_actions[$method])) { foreach (self::$magic_resize_actions[$method] as $param) { if (isset($args_copy[$param])) { - $args_copy[$param] = (int) $args_copy[$param] * $ratio; + $args_copy[$param] *= $medium->get('ratio'); } } } From 2dcd4aeaad1da413acbfc1a38dd8bf838133bd04 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Tue, 1 Nov 2016 13:54:06 +0100 Subject: [PATCH 10/56] Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 046490832..e318e4e50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * Fixed an issue with site redirects/routes, not processing with extension (.html, .json, etc.) * Don't truncate HTML if content length is less than summary size [#1125](https://github.com/getgrav/grav/issues/1125) * Return max available number when calling random() on a collection passing an int > available items [#1135](https://github.com/getgrav/grav/issues/1135) + * Use correct ratio when applying image filters to image alternatives [#1147](https://github.com/getgrav/grav/issues/1147) # v1.1.8 ## 10/22/2016 From abca8ce4339ca74fd84e3b5895f24795d7d039ac Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 1 Nov 2016 13:03:43 -0600 Subject: [PATCH 11/56] `CompiledJsonFile::content()` should support $assoc --- system/src/Grav/Common/File/CompiledJsonFile.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/system/src/Grav/Common/File/CompiledJsonFile.php b/system/src/Grav/Common/File/CompiledJsonFile.php index 8933a2e25..674f3fa6e 100644 --- a/system/src/Grav/Common/File/CompiledJsonFile.php +++ b/system/src/Grav/Common/File/CompiledJsonFile.php @@ -13,4 +13,20 @@ use RocketTheme\Toolbox\File\JsonFile; class CompiledJsonFile extends JsonFile { use CompiledFile; + + public function content($var = null, $assoc = false) + { + if ($var !== null) { + $this->content = $this->check($var); + + // Update RAW, too. + $this->raw = $this->encode($this->content); + + } elseif ($this->content === null) { + // Decode RAW file. + $this->content = $this->decode($this->raw(), $assoc); + } + + return $this->content; + } } From e73773672b72d865290f526361fc4f8c372204b0 Mon Sep 17 00:00:00 2001 From: Djamil Legato Date: Tue, 1 Nov 2016 17:07:06 -0700 Subject: [PATCH 12/56] Removed internal docs reference for Folder::create and Folder::mkdir --- system/src/Grav/Common/Filesystem/Folder.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/system/src/Grav/Common/Filesystem/Folder.php b/system/src/Grav/Common/Filesystem/Folder.php index 17616a1cb..a1bcc0883 100644 --- a/system/src/Grav/Common/Filesystem/Folder.php +++ b/system/src/Grav/Common/Filesystem/Folder.php @@ -386,7 +386,6 @@ abstract class Folder /** * @param string $folder * @throws \RuntimeException - * @internal */ public static function mkdir($folder) { @@ -396,7 +395,6 @@ abstract class Folder /** * @param string $folder * @throws \RuntimeException - * @internal */ public static function create($folder) { From 491e73eade7a4e6fa72354b882256f085a30a044 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Fri, 4 Nov 2016 06:47:27 -0600 Subject: [PATCH 13/56] Fixed CompiledJsonFile as it was not caching properly --- .../src/Grav/Common/File/CompiledJsonFile.php | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/system/src/Grav/Common/File/CompiledJsonFile.php b/system/src/Grav/Common/File/CompiledJsonFile.php index 674f3fa6e..236680809 100644 --- a/system/src/Grav/Common/File/CompiledJsonFile.php +++ b/system/src/Grav/Common/File/CompiledJsonFile.php @@ -14,19 +14,15 @@ class CompiledJsonFile extends JsonFile { use CompiledFile; - public function content($var = null, $assoc = false) + /** + * Decode RAW string into contents. + * + * @param string $var + * @param bool $assoc + * @return array mixed + */ + protected function decode($var, $assoc = true) { - if ($var !== null) { - $this->content = $this->check($var); - - // Update RAW, too. - $this->raw = $this->encode($this->content); - - } elseif ($this->content === null) { - // Decode RAW file. - $this->content = $this->decode($this->raw(), $assoc); - } - - return $this->content; + return (array) json_decode($var, $assoc); } } From fbf9c345b9051396f07ccc1af00ed3621b83c4d7 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Mon, 7 Nov 2016 08:45:02 +0200 Subject: [PATCH 14/56] Fixed URI path in multi-site when query parameters were used in front page --- CHANGELOG.md | 1 + system/src/Grav/Common/Uri.php | 14 ++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e318e4e50..46bf2d33e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * Don't truncate HTML if content length is less than summary size [#1125](https://github.com/getgrav/grav/issues/1125) * Return max available number when calling random() on a collection passing an int > available items [#1135](https://github.com/getgrav/grav/issues/1135) * Use correct ratio when applying image filters to image alternatives [#1147](https://github.com/getgrav/grav/issues/1147) + * Fixed URI path in multi-site when query parameters were used in front page # v1.1.8 ## 10/22/2016 diff --git a/system/src/Grav/Common/Uri.php b/system/src/Grav/Common/Uri.php index edfc79725..10cacb47e 100644 --- a/system/src/Grav/Common/Uri.php +++ b/system/src/Grav/Common/Uri.php @@ -304,11 +304,10 @@ class Uri $bits = parse_url($uri); // process query string - if (isset($bits['query']) && isset($bits['path'])) { + if (isset($bits['query'])) { if (!$this->query) { $this->query = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING); } - $uri = $bits['path']; } //process fragment @@ -316,8 +315,11 @@ class Uri $this->fragment = $bits['fragment']; } + // Get the path. If there's no path, make sure pathinfo() still returns dirname variable + $path = isset($bits['path']) ? $bits['path'] : '/'; + // remove the extension if there is one set - $parts = pathinfo($uri); + $parts = pathinfo($path); // set the original basename $this->basename = $parts['basename']; @@ -331,12 +333,12 @@ class Uri // Strip the file extension for valid page types if (preg_match('/\.(' . $valid_page_types . ')$/', $parts['basename'])) { - $uri = rtrim(str_replace(DIRECTORY_SEPARATOR, DS, $parts['dirname']), DS) . '/' . $parts['filename']; + $path = rtrim(str_replace(DIRECTORY_SEPARATOR, DS, $parts['dirname']), DS) . '/' . $parts['filename']; } // set the new url - $this->url = $this->root . $uri; - $this->path = $uri; + $this->url = $this->root . $path; + $this->path = $path; $this->content_path = trim(str_replace($this->base, '', $this->path), '/'); if ($this->content_path != '') { $this->paths = explode('/', $this->content_path); From 7c98ca71347e9ed722575e7e940179944b534b4a Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 7 Nov 2016 12:19:04 -0700 Subject: [PATCH 15/56] Added Base32 encode/decode class --- CHANGELOG.md | 1 + system/src/Grav/Common/Helpers/Base32.php | 101 ++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 system/src/Grav/Common/Helpers/Base32.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 46bf2d33e..628c7cf29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 1. [](#new) * Added a `CompiledJsonFile` object to better handle Json files. + * Added Base32 encode/decode class 1. [](#improved) * Added `getTaxonomyItemKeys` to the Taxonomy object [#1124](https://github.com/getgrav/grav/issues/1124) * Added a `redirect_me` Twig function [#1124](https://github.com/getgrav/grav/issues/1124) diff --git a/system/src/Grav/Common/Helpers/Base32.php b/system/src/Grav/Common/Helpers/Base32.php new file mode 100644 index 000000000..db346e99d --- /dev/null +++ b/system/src/Grav/Common/Helpers/Base32.php @@ -0,0 +1,101 @@ +', '?' + 0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06, // '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G' + 0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E, // 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O' + 0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16, // 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W' + 0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF, // 'X', 'Y', 'Z', '[', '\', ']', '^', '_' + 0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06, // '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g' + 0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E, // 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o' + 0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16, // 'p', 'q', 'r', 's', 't', 'u', 'v', 'w' + 0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF // 'x', 'y', 'z', '{', '|', '}', '~', 'DEL' + ); + + /** + * Encode in Base32 + * + * @param $bytes + * @return string + */ + public static function encode( $bytes ) { + $i = 0; $index = 0; $digit = 0; + $base32 = ""; + while( $i < strlen($bytes) ) { + $currByte = ord($bytes{$i}); + /* Is the current digit going to span a byte boundary? */ + if( $index > 3 ) { + if( ($i + 1) < strlen($bytes) ) { + $nextByte = ord($bytes{$i+1}); + } else { + $nextByte = 0; + } + $digit = $currByte & (0xFF >> $index); + $index = ($index + 5) % 8; + $digit <<= $index; + $digit |= $nextByte >> (8 - $index); + $i++; + } else { + $digit = ($currByte >> (8 - ($index + 5))) & 0x1F; + $index = ($index + 5) % 8; + if( $index == 0 ) $i++; + } + $base32 .= self::$base32Chars{$digit}; + } + return $base32; + } + + /** + * Decode in Base32 + * + * @param $base32 + * @return string + */ + public static function decode( $base32 ) { + $bytes = array(); + for( $i=strlen($base32)*5/8-1; $i>=0; --$i ) { + $bytes[] = 0; + } + for( $i = 0, $index = 0, $offset = 0; $i < strlen($base32); $i++ ) { + $lookup = ord($base32{$i}) - ord('0'); + /* Skip chars outside the lookup table */ + if( $lookup < 0 || $lookup >= count(self::$base32Lookup) ) { + continue; + } + $digit = self::$base32Lookup[$lookup]; + /* If this digit is not in the table, ignore it */ + if( $digit == 0xFF ) continue; + if( $index <= 3 ) { + $index = ($index + 5) % 8; + if( $index == 0) { + $bytes[$offset] |= $digit; + $offset++; + if( $offset >= count($bytes) ) break; + } else { + $bytes[$offset] |= $digit << (8 - $index); + } + } else { + $index = ($index + 5) % 8; + $bytes[$offset] |= ($digit >> $index); + $offset++; + if ($offset >= count($bytes) ) break; + $bytes[$offset] |= $digit << (8 - $index); + } + } + $bites = ""; + foreach( $bytes as $byte ) $bites .= chr($byte); + return $bites; + } +} From 079468c6092f4471dfaa5dcff18152165c1e4eed Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 8 Nov 2016 11:17:01 -0700 Subject: [PATCH 16/56] Added `User::find()` method --- CHANGELOG.md | 1 + system/src/Grav/Common/User/User.php | 36 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 628c7cf29..9aecfa50d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ 1. [](#new) * Added a `CompiledJsonFile` object to better handle Json files. * Added Base32 encode/decode class + * Added a new `User::find()` method 1. [](#improved) * Added `getTaxonomyItemKeys` to the Taxonomy object [#1124](https://github.com/getgrav/grav/issues/1124) * Added a `redirect_me` Twig function [#1124](https://github.com/getgrav/grav/issues/1124) diff --git a/system/src/Grav/Common/User/User.php b/system/src/Grav/Common/User/User.php index 340797011..fcc8f6c43 100644 --- a/system/src/Grav/Common/User/User.php +++ b/system/src/Grav/Common/User/User.php @@ -54,6 +54,42 @@ class User extends Data return $user; } + /** + * Find a user by username, email, etc + * + * @param $query the query to search for + * @param array $fields the fields to search + * @return User + */ + public static function find($query, $fields = ['username', 'email']) + { + $account_dir = Grav::instance()['locator']->findResource('account://'); + $files = array_diff(scandir($account_dir), ['.', '..']); + + // Try with username first, you never know! + if (in_array('username', $fields)) { + $user = User::load($query); + unset($fields[array_search('username', $fields)]); + } else { + $user = User::load(''); + } + + // If not found, try the fields + if (!$user->exists()) { + foreach ($files as $file) { + if (Utils::endsWith($file, YAML_EXT)) { + $find_user = User::load(trim(pathinfo($file, PATHINFO_FILENAME))); + foreach ($fields as $field) { + if ($find_user[$field] == $query) { + return $find_user; + } + } + } + } + } + return $user; + } + /** * Remove user account. * From 95ab80b8f9101f4df18d2ff480e26d59cf561100 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 9 Nov 2016 10:48:36 -0700 Subject: [PATCH 17/56] Added message service into core Grav --- CHANGELOG.md | 1 + system/src/Grav/Common/Grav.php | 1 + .../Service/MessagesServiceProvider.php | 30 +++++++++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 system/src/Grav/Common/Service/MessagesServiceProvider.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 9aecfa50d..465a16acc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Added Base32 encode/decode class * Added a new `User::find()` method 1. [](#improved) + * Moved `messages` object into core Grav from login plugin * Added `getTaxonomyItemKeys` to the Taxonomy object [#1124](https://github.com/getgrav/grav/issues/1124) * Added a `redirect_me` Twig function [#1124](https://github.com/getgrav/grav/issues/1124) * Added a Caddyfile for newer Caddy versions [#1115](https://github.com/getgrav/grav/issues/1115) diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 20fc5d554..c18fa4c2a 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -29,6 +29,7 @@ class Grav extends Container 'events' => 'RocketTheme\Toolbox\Event\EventDispatcher', 'cache' => 'Grav\Common\Cache', 'session' => 'Grav\Common\Session', + 'Grav\Common\Service\MessagesServiceProvider', 'plugins' => 'Grav\Common\Plugins', 'themes' => 'Grav\Common\Themes', 'twig' => 'Grav\Common\Twig\Twig', diff --git a/system/src/Grav/Common/Service/MessagesServiceProvider.php b/system/src/Grav/Common/Service/MessagesServiceProvider.php new file mode 100644 index 000000000..78238fb9b --- /dev/null +++ b/system/src/Grav/Common/Service/MessagesServiceProvider.php @@ -0,0 +1,30 @@ +messages)) { + $session->messages = new Message; + } + + return $session->messages; + }; + } +} From 5c003d38be15900346d9b40f7e4a166499ff9967 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 9 Nov 2016 10:58:13 -0700 Subject: [PATCH 18/56] Ready for an RC.1 release --- CHANGELOG.md | 4 ++-- system/defines.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 465a16acc..6fd7dc63f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ -# v1.1.9 -## xx/xx/2016 +# v1.1.9-rc.1 +## 11/09/2016 1. [](#new) * Added a `CompiledJsonFile` object to better handle Json files. diff --git a/system/defines.php b/system/defines.php index 550246281..e702bb268 100644 --- a/system/defines.php +++ b/system/defines.php @@ -8,8 +8,8 @@ // Some standard defines define('GRAV', true); -define('GRAV_VERSION', '1.1.8'); -define('GRAV_TESTING', false); +define('GRAV_VERSION', '1.1.9-rc.1'); +define('GRAV_TESTING', true); define('DS', '/'); define('GRAV_PHP_MIN', '5.5.9'); From 9a15b5ebdc35e50d7fb902e885a68e6be42f75d9 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 15 Nov 2016 16:10:34 +0200 Subject: [PATCH 19/56] Multisite: Create image cache folder if it doesn't exist --- system/src/Grav/Common/Page/Medium/ImageMedium.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Page/Medium/ImageMedium.php b/system/src/Grav/Common/Page/Medium/ImageMedium.php index c6c1b7180..94602e336 100644 --- a/system/src/Grav/Common/Page/Medium/ImageMedium.php +++ b/system/src/Grav/Common/Page/Medium/ImageMedium.php @@ -532,7 +532,9 @@ class ImageMedium extends Medium $locator = Grav::instance()['locator']; $file = $this->get('filepath'); - $cacheDir = $locator->findResource('cache://images', true); + + // Use existing cache folder or if it doesn't exist, create it. + $cacheDir = $locator->findResource('cache://images', true) ?: $locator->findResource('cache://images', true, true); $this->image = ImageFile::open($file) ->setCacheDir($cacheDir) From 9dd4f690a816814d79dc1fbe5310be89806967c2 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Sat, 19 Nov 2016 19:29:28 +0100 Subject: [PATCH 20/56] Allow to override sorting flags for page header-based or default ordering. (#1173) If the `intl` PHP extension is loaded, only these flags are available: https://secure.php.net/manual/en/collator.asort.php. Otherwise, you can use the PHP standard sorting flags (https://secure.php.net/manual/en/array.constants.php) [#1169](https://github.com/getgrav/grav/issues/1169) --- CHANGELOG.md | 3 ++- system/src/Grav/Common/Page/Collection.php | 6 +++--- system/src/Grav/Common/Page/Page.php | 9 ++++++++- system/src/Grav/Common/Page/Pages.php | 22 +++++++++++++--------- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fd7dc63f..44b5bf9c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,12 +10,13 @@ * Added `getTaxonomyItemKeys` to the Taxonomy object [#1124](https://github.com/getgrav/grav/issues/1124) * Added a `redirect_me` Twig function [#1124](https://github.com/getgrav/grav/issues/1124) * Added a Caddyfile for newer Caddy versions [#1115](https://github.com/getgrav/grav/issues/1115) + * Allow to override sorting flags for page header-based or default ordering. If the `intl` PHP extension is loaded, only these flags are available: https://secure.php.net/manual/en/collator.asort.php. Otherwise, you can use the PHP standard sorting flags (https://secure.php.net/manual/en/array.constants.php) [#1169](https://github.com/getgrav/grav/issues/1169) 1. [](#bugfix) * Fixed an issue with site redirects/routes, not processing with extension (.html, .json, etc.) * Don't truncate HTML if content length is less than summary size [#1125](https://github.com/getgrav/grav/issues/1125) * Return max available number when calling random() on a collection passing an int > available items [#1135](https://github.com/getgrav/grav/issues/1135) * Use correct ratio when applying image filters to image alternatives [#1147](https://github.com/getgrav/grav/issues/1147) - * Fixed URI path in multi-site when query parameters were used in front page + * Fixed URI path in multi-site when query parameters were used in front page # v1.1.8 ## 10/22/2016 diff --git a/system/src/Grav/Common/Page/Collection.php b/system/src/Grav/Common/Page/Collection.php index 5a70ba99c..53baf620d 100644 --- a/system/src/Grav/Common/Page/Collection.php +++ b/system/src/Grav/Common/Page/Collection.php @@ -84,7 +84,6 @@ class Collection extends Iterator public function setParams(array $params) { $this->params = array_merge($this->params, $params); - return $this; } @@ -172,12 +171,13 @@ class Collection extends Iterator * @param string $by * @param string $dir * @param array $manual + * @param string $sort_flags * * @return $this */ - public function order($by, $dir = 'asc', $manual = null) + public function order($by, $dir = 'asc', $manual = null, $sort_flags = null) { - $this->items = $this->pages->sortCollection($this, $by, $dir, $manual); + $this->items = $this->pages->sortCollection($this, $by, $dir, $manual, $sort_flags); return $this; } diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index fbf3ebdc3..eb83808b6 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -2291,7 +2291,14 @@ class Page $by = isset($params['order']['by']) ? $params['order']['by'] : 'default'; $dir = isset($params['order']['dir']) ? $params['order']['dir'] : 'asc'; $custom = isset($params['order']['custom']) ? $params['order']['custom'] : null; - $collection->order($by, $dir, $custom); + $sort_flags = isset($params['order']['sort_flags']) ? $params['order']['sort_flags'] : null; + + if (is_array($sort_flags)) { + $sort_flags = array_map('constant', $sort_flags); //transform strings to constant value + $sort_flags = array_reduce($sort_flags, function($a, $b) { return $a | $b; }, 0); //merge constant values using bit or + } + + $collection->order($by, $dir, $custom, $sort_flags); } /** @var Grav $grav */ diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 0b7691b4a..02a3f1e88 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -21,6 +21,7 @@ use Grav\Plugin\Admin; use RocketTheme\Toolbox\Event\Event; use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; use Whoops\Exception\ErrorException; +use Collator as Collator; class Pages { @@ -197,7 +198,7 @@ class Pages * * @return array */ - public function sort(Page $page, $order_by = null, $order_dir = null) + public function sort(Page $page, $order_by = null, $order_dir = null, $sort_flags = null) { if ($order_by === null) { $order_by = $page->orderBy(); @@ -214,7 +215,7 @@ class Pages } if (!isset($this->sort[$path][$order_by])) { - $this->buildSort($path, $children, $order_by, $page->orderManual()); + $this->buildSort($path, $children, $order_by, $page->orderManual(), $sort_flags); } $sort = $this->sort[$path][$order_by]; @@ -235,7 +236,7 @@ class Pages * @return array * @internal */ - public function sortCollection(Collection $collection, $orderBy, $orderDir = 'asc', $orderManual = null) + public function sortCollection(Collection $collection, $orderBy, $orderDir = 'asc', $orderManual = null, $sort_flags = null) { $items = $collection->toArray(); if (!$items) { @@ -244,7 +245,7 @@ class Pages $lookup = md5(json_encode($items) . json_encode($orderManual) . $orderBy . $orderDir); if (!isset($this->sort[$lookup][$orderBy])) { - $this->buildSort($lookup, $items, $orderBy, $orderManual); + $this->buildSort($lookup, $items, $orderBy, $orderManual, $sort_flags); } $sort = $this->sort[$lookup][$orderBy]; @@ -1023,12 +1024,11 @@ class Pages * @throws \RuntimeException * @internal */ - protected function buildSort($path, array $pages, $order_by = 'default', $manual = null) + protected function buildSort($path, array $pages, $order_by = 'default', $manual = null, $sort_flags = null) { $list = []; $header_default = null; $header_query = null; - $sort_flags = SORT_NATURAL | SORT_FLAG_CASE; // do this header query work only once if (strpos($order_by, 'header.') === 0) { @@ -1070,16 +1070,20 @@ class Pages } else { $list[$key] = $header_default ?: $key; } - $sort_flags = SORT_REGULAR; + $sort_flags = $sort_flags ?: SORT_REGULAR; break; case 'manual': case 'default': default: $list[$key] = $key; - $sort_flags = SORT_REGULAR; + $sort_flags = $sort_flags ?: SORT_REGULAR; } } + if (!$sort_flags) { + $sort_flags = SORT_NATURAL | SORT_FLAG_CASE; + } + // handle special case when order_by is random if ($order_by == 'random') { $list = $this->arrayShuffle($list); @@ -1087,7 +1091,7 @@ class Pages // else just sort the list according to specified key if (extension_loaded('intl')) { $locale = setlocale(LC_COLLATE, 0); //`setlocale` with a 0 param returns the current locale set - $col = \Collator::create($locale); + $col = Collator::create($locale); if ($col) { $col->asort($list, $sort_flags); } else { From 20e36c8a0070f0898e72b0a163caf944011396b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Am=C3=A9lie=20Turgeon?= Date: Sat, 19 Nov 2016 13:32:05 -0500 Subject: [PATCH 21/56] Add 2 new language values for French (#1174) set the name and native name for these two. (fr-FR and fr-CA) --- system/src/Grav/Common/Language/LanguageCodes.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/system/src/Grav/Common/Language/LanguageCodes.php b/system/src/Grav/Common/Language/LanguageCodes.php index 85b3236e3..de56a79bf 100644 --- a/system/src/Grav/Common/Language/LanguageCodes.php +++ b/system/src/Grav/Common/Language/LanguageCodes.php @@ -52,6 +52,8 @@ class LanguageCodes 'fi' => [ 'name' => 'Finnish', 'nativeName' => 'Suomi' ], 'fj-FJ' => [ 'name' => 'Fijian', 'nativeName' => 'Vosa vaka-Viti' ], 'fr' => [ 'name' => 'French', 'nativeName' => 'Français' ], + 'fr-CA' => [ 'name' => 'French (Canada)', 'nativeName' => 'Français (Canada)' ], + 'fr-FR' => [ 'name' => 'French (France)', 'nativeName' => 'Français (France)' ], 'fur' => [ 'name' => 'Friulian', 'nativeName' => 'Furlan' ], 'fur-IT' => [ 'name' => 'Friulian', 'nativeName' => 'Furlan' ], 'fy' => [ 'name' => 'Frisian', 'nativeName' => 'Frysk' ], From 5105be338a3ef8d69eff413906b724f6c2f27c96 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Sat, 19 Nov 2016 19:32:54 +0100 Subject: [PATCH 22/56] Decode single taxonomy params (#1164) Allows to use commas in taxonomy terms --- system/src/Grav/Common/Page/Page.php | 1 + 1 file changed, 1 insertion(+) diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index eb83808b6..d0d62de48 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -2269,6 +2269,7 @@ class Page continue; } foreach ($items as $item) { + $item = rawurldecode($item); if (empty($page->taxonomy[$taxonomy]) || !in_array(htmlspecialchars_decode($item, ENT_QUOTES), $page->taxonomy[$taxonomy]) ) { From 55bb4cf2fa1780d5017c1248a46f578c9a342aca Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Tue, 22 Nov 2016 17:22:27 +0100 Subject: [PATCH 23/56] Fix #1179 issue when we have a meta file without corresponding media Also update changelog entries --- CHANGELOG.md | 9 +++++++++ system/src/Grav/Common/Page/Media.php | 3 +++ 2 files changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44b5bf9c1..98e8d8da9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# v1.1.x +## 11/xx/2016 + +1. [](#improved) + * Multisite: Create image cache folder if it doesn't exist + * Add 2 new language values for French [#1174](https://github.com/getgrav/grav/issues/1174) +1. [](#bugfix) + * Fixed issue when we have a meta file without corresponding media [#1179](https://github.com/getgrav/grav/issues/1179) + # v1.1.9-rc.1 ## 11/09/2016 diff --git a/system/src/Grav/Common/Page/Media.php b/system/src/Grav/Common/Page/Media.php index 35baab6ab..16dfdf313 100644 --- a/system/src/Grav/Common/Page/Media.php +++ b/system/src/Grav/Common/Page/Media.php @@ -75,6 +75,9 @@ class Media extends Getters // Create the base medium if (empty($types['base'])) { + if (!isset($types['alternative'])) { + continue; + } $max = max(array_keys($types['alternative'])); $medium = $types['alternative'][$max]['file']; $medium = MediumFactory::scaledFromMedium($medium, $max, 1)['file']; From 923b2469f98e9a602e8f4d237c3bca5dfda8826d Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Thu, 24 Nov 2016 13:50:15 +0100 Subject: [PATCH 24/56] Fix https://github.com/getgrav/grav-plugin-admin/issues/874 use updated class namespace --- CHANGELOG.md | 1 + system/blueprints/pages/default.yaml | 2 +- system/blueprints/pages/modular_new.yaml | 2 +- system/blueprints/pages/modular_raw.yaml | 2 +- system/blueprints/pages/move.yaml | 2 +- system/blueprints/pages/new.yaml | 4 ++-- system/blueprints/pages/new_folder.yaml | 2 +- system/blueprints/pages/raw.yaml | 2 +- system/blueprints/user/account.yaml | 4 ++-- 9 files changed, 11 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98e8d8da9..6e6b96ad3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Add 2 new language values for French [#1174](https://github.com/getgrav/grav/issues/1174) 1. [](#bugfix) * Fixed issue when we have a meta file without corresponding media [#1179](https://github.com/getgrav/grav/issues/1179) + * Update class namespace for Admin class [#874](https://github.com/getgrav/grav-plugin-admin/issues/874) # v1.1.9-rc.1 ## 11/09/2016 diff --git a/system/blueprints/pages/default.yaml b/system/blueprints/pages/default.yaml index 14116aab0..f54468082 100644 --- a/system/blueprints/pages/default.yaml +++ b/system/blueprints/pages/default.yaml @@ -139,7 +139,7 @@ form: label: PLUGIN_ADMIN.PARENT classes: fancy data-options@: '\Grav\Common\Page\Pages::parentsRawRoutes' - data-default@: '\Grav\Plugin\admin::rawRoute' + data-default@: '\Grav\Plugin\Admin\Admin::rawRoute' options: '/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT diff --git a/system/blueprints/pages/modular_new.yaml b/system/blueprints/pages/modular_new.yaml index 57ede83e8..8c19d8960 100644 --- a/system/blueprints/pages/modular_new.yaml +++ b/system/blueprints/pages/modular_new.yaml @@ -30,7 +30,7 @@ form: label: PLUGIN_ADMIN.PAGE classes: fancy data-options@: '\Grav\Common\Page\Pages::parentsRawRoutes' - data-default@: '\Grav\Plugin\admin::rawRoute' + data-default@: '\Grav\Plugin\Admin\Admin::rawRoute' validate: required: true diff --git a/system/blueprints/pages/modular_raw.yaml b/system/blueprints/pages/modular_raw.yaml index 6e71eaa13..8e4647989 100644 --- a/system/blueprints/pages/modular_raw.yaml +++ b/system/blueprints/pages/modular_raw.yaml @@ -79,7 +79,7 @@ form: label: PLUGIN_ADMIN.PARENT classes: fancy data-options@: '\Grav\Common\Page\Pages::parentsRawRoutes' - data-default@: '\Grav\Plugin\admin::rawRoute' + data-default@: '\Grav\Plugin\Admin\Admin::rawRoute' options: '': PLUGIN_ADMIN.DEFAULT_OPTION_SELECT validate: diff --git a/system/blueprints/pages/move.yaml b/system/blueprints/pages/move.yaml index 5fda52fd2..518f21828 100644 --- a/system/blueprints/pages/move.yaml +++ b/system/blueprints/pages/move.yaml @@ -12,6 +12,6 @@ form: label: PLUGIN_ADMIN.PARENT classes: fancy data-options@: '\Grav\Common\Page\Pages::parentsRawRoutes' - data-default@: '\Grav\Plugin\admin::rawRoute' + data-default@: '\Grav\Plugin\Admin\Admin::rawRoute' options: '/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT diff --git a/system/blueprints/pages/new.yaml b/system/blueprints/pages/new.yaml index 0b2fe75fc..71ca78a81 100644 --- a/system/blueprints/pages/new.yaml +++ b/system/blueprints/pages/new.yaml @@ -32,7 +32,7 @@ form: label: PLUGIN_ADMIN.PARENT_PAGE classes: fancy data-options@: '\Grav\Common\Page\Pages::parentsRawRoutes' - data-default@: '\Grav\Plugin\admin::getLastPageRoute' + data-default@: '\Grav\Plugin\Admin\Admin::getLastPageRoute' options: '/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT validate: @@ -44,7 +44,7 @@ form: label: PLUGIN_ADMIN.PAGE_FILE help: PLUGIN_ADMIN.PAGE_FILE_HELP data-options@: '\Grav\Common\Page\Pages::types' - data-default@: '\Grav\Plugin\admin::getLastPageName' + data-default@: '\Grav\Plugin\Admin\Admin::getLastPageName' validate: required: true diff --git a/system/blueprints/pages/new_folder.yaml b/system/blueprints/pages/new_folder.yaml index c4fe96165..ddf47a97d 100644 --- a/system/blueprints/pages/new_folder.yaml +++ b/system/blueprints/pages/new_folder.yaml @@ -25,7 +25,7 @@ form: label: PLUGIN_ADMIN.PARENT_PAGE classes: fancy data-options@: '\Grav\Common\Page\Pages::parentsRawRoutes' - data-default@: '\Grav\Plugin\admin::getLastPageRoute' + data-default@: '\Grav\Plugin\Admin\Admin::getLastPageRoute' options: '/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT validate: diff --git a/system/blueprints/pages/raw.yaml b/system/blueprints/pages/raw.yaml index fe5dba2fe..3b582eb14 100644 --- a/system/blueprints/pages/raw.yaml +++ b/system/blueprints/pages/raw.yaml @@ -79,7 +79,7 @@ form: label: PLUGIN_ADMIN.PARENT classes: fancy data-options@: '\Grav\Common\Page\Pages::parentsRawRoutes' - data-default@: '\Grav\Plugin\admin::rawRoute' + data-default@: '\Grav\Plugin\Admin\Admin::rawRoute' options: '/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT diff --git a/system/blueprints/user/account.yaml b/system/blueprints/user/account.yaml index bd1caa85f..e53544744 100644 --- a/system/blueprints/user/account.yaml +++ b/system/blueprints/user/account.yaml @@ -1,4 +1,4 @@ -title: Site +title: Account form: validation: loose @@ -56,7 +56,7 @@ form: label: PLUGIN_ADMIN.LANGUAGE size: medium classes: fancy - data-options@: '\Grav\Plugin\admin::adminLanguages' + data-options@: '\Grav\Plugin\Admin\Admin::adminLanguages' default: 'en' help: PLUGIN_ADMIN.LANGUAGE_HELP From 287a329a4ddf7855431ead9c5aac7656ca716a70 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 24 Nov 2016 15:03:51 +0200 Subject: [PATCH 25/56] Added two new sort order options for pages: `publish_date` and `unpublish_date` --- CHANGELOG.md | 2 ++ system/src/Grav/Common/Page/Pages.php | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e6b96ad3..193452ca6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # v1.1.x ## 11/xx/2016 +1. [](#new) + * Added two new sort order options for pages: `publish_date` and `unpublish_date` 1. [](#improved) * Multisite: Create image cache folder if it doesn't exist * Add 2 new language values for French [#1174](https://github.com/getgrav/grav/issues/1174) diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 02a3f1e88..0a71ad888 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -1056,6 +1056,14 @@ class Pages $list[$key] = $child->modified(); $sort_flags = SORT_REGULAR; break; + case 'publish_date': + $list[$key] = $child->publish_date(); + $sort_flags = SORT_REGULAR; + break; + case 'unpublish_date': + $list[$key] = $child->unpublish_date(); + $sort_flags = SORT_REGULAR; + break; case 'slug': $list[$key] = $child->slug(); break; From 3064fe8ad995137fb6b714696c7ade5d3f662dc9 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Fri, 25 Nov 2016 18:33:49 +0100 Subject: [PATCH 26/56] Fix #713 Remove mappings missing if not cloned from github --- system/src/Grav/Console/Cli/SandboxCommand.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/system/src/Grav/Console/Cli/SandboxCommand.php b/system/src/Grav/Console/Cli/SandboxCommand.php index 769bf6a33..918806b47 100644 --- a/system/src/Grav/Console/Cli/SandboxCommand.php +++ b/system/src/Grav/Console/Cli/SandboxCommand.php @@ -47,7 +47,6 @@ class SandboxCommand extends ConsoleCommand * @var array */ protected $mappings = [ - '/.editorconfig' => '/.editorconfig', '/.gitignore' => '/.gitignore', '/CHANGELOG.md' => '/CHANGELOG.md', '/LICENSE.txt' => '/LICENSE.txt', @@ -59,7 +58,6 @@ class SandboxCommand extends ConsoleCommand '/system' => '/system', '/vendor' => '/vendor', '/webserver-configs' => '/webserver-configs', - '/codeception.yml' => '/codeception.yml', ]; /** From 8dd65b709dbab1e6df19d87abea6ff92d60f8c12 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Fri, 25 Nov 2016 22:32:14 +0100 Subject: [PATCH 27/56] Fix #946 issue with the sample nginx.conf, security section moved before PHP handler, and fixed `backup` folder uncorrectly named as `backups` --- webserver-configs/nginx.conf | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/webserver-configs/nginx.conf b/webserver-configs/nginx.conf index 18db9fdd5..640964a6d 100644 --- a/webserver-configs/nginx.conf +++ b/webserver-configs/nginx.conf @@ -16,6 +16,17 @@ server { } ## End - Index + ## Begin - Security + # deny all direct access for these folders + location ~* /(.git|cache|bin|logs|backup|tests)/.*$ { return 403; } + # deny running scripts inside core system folders + location ~* /(system|vendor)/.*\.(txt|xml|md|html|yaml|php|pl|py|cgi|twig|sh|bat)$ { return 403; } + # deny running scripts inside user folder + location ~* /user/.*\.(txt|md|yaml|php|pl|py|cgi|twig|sh|bat)$ { return 403; } + # deny access to specific files in the root folder + location ~ /(LICENSE.txt|composer.lock|composer.json|nginx.conf|web.config|htaccess.txt|\.htaccess) { return 403; } + ## End - Security + ## Begin - PHP location ~ \.php$ { # Choose either a socket or TCP/IP address @@ -28,16 +39,5 @@ server { fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; } ## End - PHP - - ## Begin - Security - # deny all direct access for these folders - location ~* /(.git|cache|bin|logs|backups|tests)/.*$ { return 403; } - # deny running scripts inside core system folders - location ~* /(system|vendor)/.*\.(txt|xml|md|html|yaml|php|pl|py|cgi|twig|sh|bat)$ { return 403; } - # deny running scripts inside user folder - location ~* /user/.*\.(txt|md|yaml|php|pl|py|cgi|twig|sh|bat)$ { return 403; } - # deny access to specific files in the root folder - location ~ /(LICENSE.txt|composer.lock|composer.json|nginx.conf|web.config|htaccess.txt|\.htaccess) { return 403; } - ## End - Security } From f7b35c3b7980e71d1122d9a376cb8b7ede3e4f08 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sat, 26 Nov 2016 20:22:33 -0700 Subject: [PATCH 28/56] Updated version --- CHANGELOG.md | 4 ++-- system/defines.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 193452ca6..0e98c3a38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ -# v1.1.x -## 11/xx/2016 +# v1.1.9-rc.2 +## 11/26/2016 1. [](#new) * Added two new sort order options for pages: `publish_date` and `unpublish_date` diff --git a/system/defines.php b/system/defines.php index e702bb268..b3d0a24f2 100644 --- a/system/defines.php +++ b/system/defines.php @@ -8,7 +8,7 @@ // Some standard defines define('GRAV', true); -define('GRAV_VERSION', '1.1.9-rc.1'); +define('GRAV_VERSION', '1.1.9-rc.2'); define('GRAV_TESTING', true); define('DS', '/'); define('GRAV_PHP_MIN', '5.5.9'); From f6ddba52d81eede6a16388a7cec7c3a7cd6ae212 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Mon, 28 Nov 2016 13:27:23 +0100 Subject: [PATCH 29/56] Added alias `selfupdate` to the `self-upgrade` `bin/gpm` CLI command --- CHANGELOG.md | 6 ++++++ system/src/Grav/Console/Gpm/SelfupgradeCommand.php | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e98c3a38..575d4b987 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v1.1.9-rc.X +## 11/xx/2016 + +1. [](#improved) + * Added alias `selfupdate` to the `self-upgrade` `bin/gpm` CLI command + # v1.1.9-rc.2 ## 11/26/2016 diff --git a/system/src/Grav/Console/Gpm/SelfupgradeCommand.php b/system/src/Grav/Console/Gpm/SelfupgradeCommand.php index 9179ae7c7..f15ca8902 100644 --- a/system/src/Grav/Console/Gpm/SelfupgradeCommand.php +++ b/system/src/Grav/Console/Gpm/SelfupgradeCommand.php @@ -59,7 +59,7 @@ class SelfupgradeCommand extends ConsoleCommand { $this ->setName("self-upgrade") - ->setAliases(['selfupgrade']) + ->setAliases(['selfupgrade', 'selfupdate']) ->addOption( 'force', 'f', From 3838de1d97d8aee241caa9eddc17cb7e53d560c4 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Mon, 28 Nov 2016 18:59:41 +0100 Subject: [PATCH 30/56] If an array field has `ignore_empty: true`, only save options with a value --- CHANGELOG.md | 1 + system/src/Grav/Common/Data/Validation.php | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 575d4b987..07ec79211 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 1. [](#improved) * Added alias `selfupdate` to the `self-upgrade` `bin/gpm` CLI command + * Add `ignore_empty` property to be used on array fields, if positive only save options with a value # v1.1.9-rc.2 ## 11/26/2016 diff --git a/system/src/Grav/Common/Data/Validation.php b/system/src/Grav/Common/Data/Validation.php index 22f6d8454..7dbf34838 100644 --- a/system/src/Grav/Common/Data/Validation.php +++ b/system/src/Grav/Common/Data/Validation.php @@ -9,6 +9,7 @@ namespace Grav\Common\Data; use Grav\Common\Grav; +use Grav\Common\Utils; use Symfony\Component\Yaml\Exception\ParseException; use Symfony\Component\Yaml\Parser; use Symfony\Component\Yaml\Yaml; @@ -569,6 +570,7 @@ class Validation return null; } + if ($options) { $useKey = isset($field['use']) && $field['use'] == 'keys'; foreach ($values as $key => $value) { @@ -586,6 +588,18 @@ class Validation } } + if (isset($field['ignore_empty']) && Utils::isPositive($field['ignore_empty'])) { + foreach ($values as $key => $value) { + foreach ($value as $inner_key => $inner_value) { + if ($inner_value == '') { + unset($value[$inner_key]); + } + } + + $values[$key] = $value; + } + } + return $values; } From d8b3f215a2045a81d66eb5cbde3a63962a508f11 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Mon, 28 Nov 2016 19:00:25 +0100 Subject: [PATCH 31/56] Use new `permissions` field in user account --- CHANGELOG.md | 4 +++- system/blueprints/user/account.yaml | 15 ++++----------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07ec79211..ef7db0ea2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,11 @@ # v1.1.9-rc.X ## 11/xx/2016 +1. [](#new) + * Add `ignore_empty` property to be used on array fields, if positive only save options with a value + * Use new `permissions` field in user account 1. [](#improved) * Added alias `selfupdate` to the `self-upgrade` `bin/gpm` CLI command - * Add `ignore_empty` property to be used on array fields, if positive only save options with a value # v1.1.9-rc.2 ## 11/26/2016 diff --git a/system/blueprints/user/account.yaml b/system/blueprints/user/account.yaml index e53544744..ff657b4c4 100644 --- a/system/blueprints/user/account.yaml +++ b/system/blueprints/user/account.yaml @@ -77,16 +77,9 @@ form: validate: type: commalist - access.admin: - type: array - label: PLUGIN_ADMIN.ADMIN_ACCESS - multiple: false - validate: - type: array - - access.site: - type: array - label: PLUGIN_ADMIN.SITE_ACCESS - multiple: false + access: + type: permissions + label: PLUGIN_ADMIN.PERMISSIONS + ignore_empty: true validate: type: array From 6315283a3ab80d805c7e5c5e8c88d9cdc5a54e0e Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 29 Nov 2016 12:29:16 +0200 Subject: [PATCH 32/56] Fix publish date ordering --- system/src/Grav/Common/Page/Pages.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 0a71ad888..93656dcbb 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -1057,11 +1057,11 @@ class Pages $sort_flags = SORT_REGULAR; break; case 'publish_date': - $list[$key] = $child->publish_date(); + $list[$key] = $child->publishDate(); $sort_flags = SORT_REGULAR; break; case 'unpublish_date': - $list[$key] = $child->unpublish_date(); + $list[$key] = $child->unpublishDate(); $sort_flags = SORT_REGULAR; break; case 'slug': From ee1742af1f5ce32d2b798ff0f0e7028a0c3fe48a Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Tue, 29 Nov 2016 11:33:47 +0100 Subject: [PATCH 33/56] Sync webserver-configs/htaccess.txt with .htaccess --- CHANGELOG.md | 1 + webserver-configs/htaccess.txt | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef7db0ea2..dd259827b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Use new `permissions` field in user account 1. [](#improved) * Added alias `selfupdate` to the `self-upgrade` `bin/gpm` CLI command + * Synced `webserver-configs/htaccess.txt` with `.htaccess` # v1.1.9-rc.2 ## 11/26/2016 diff --git a/webserver-configs/htaccess.txt b/webserver-configs/htaccess.txt index c82ca8fa6..faef479f7 100644 --- a/webserver-configs/htaccess.txt +++ b/webserver-configs/htaccess.txt @@ -3,7 +3,7 @@ RewriteEngine On ## Begin RewriteBase -# If you are getting 404 errors on subpages, you may have to uncomment the RewriteBase entry +# If you are getting 500 or 404 errors on subpages, you may have to uncomment the RewriteBase entry # You should change the '/' to your appropriate subfolder. For example if you have # your Grav install at the root of your site '/' should work, else it might be something # along the lines of: RewriteBase / @@ -13,6 +13,16 @@ RewriteEngine On ## End - RewriteBase +## Begin - X-Forwarded-Proto +# In some hosted or load balanced environments, SSL negotiation happens upstream. +# In order for Grav to recognize the connection as secure, you need to uncomment +# the following lines. +# +# RewriteCond %{HTTP:X-Forwarded-Proto} https +# RewriteRule .* - [E=HTTPS:on] +# +## End - X-Forwarded-Proto + ## Begin - Exploits # If you experience problems on your site block out the operations listed below # This attempts to block the most common type of exploit `attempts` to Grav @@ -52,7 +62,7 @@ RewriteRule ^(user)/(.*)\.(txt|md|yaml|php|pl|py|cgi|twig|sh|bat)$ error [F] # Block all direct access to .md files: RewriteRule \.md$ error [F] # Block all direct access to files and folders beginning with a dot -RewriteRule (^\.|/\.) - [F] +RewriteRule (^|/)\.(?!well-known) - [F] # Block access to specific files in the root folder RewriteRule ^(LICENSE.txt|composer.lock|composer.json|\.htaccess)$ error [F] ## End - Security @@ -62,4 +72,4 @@ RewriteRule ^(LICENSE.txt|composer.lock|composer.json|\.htaccess)$ error [F] # Begin - Prevent Browsing and Set Default Resources Options -Indexes DirectoryIndex index.php index.html index.htm -# End - Prevent Browsing and Set Default Resources +# End - Prevent Browsing and Set Default Resources \ No newline at end of file From 52b68a0a1b1eb598127e79765a8a03a2e3a7a56d Mon Sep 17 00:00:00 2001 From: Djamil Legato Date: Thu, 1 Dec 2016 12:40:21 -0800 Subject: [PATCH 34/56] Add `range(int min, int max, int step)` twig function to generate an array of numbers between min and max, inclusive --- CHANGELOG.md | 1 + system/src/Grav/Common/Twig/TwigExtension.php | 21 ++++++++++++++---- .../Grav/Common/Twig/TwigExtensionTest.php | 22 +++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd259827b..0d88d4f2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ 1. [](#new) * Add `ignore_empty` property to be used on array fields, if positive only save options with a value * Use new `permissions` field in user account + * Add `range(int min, int max, int step)` twig function to generate an array of numbers between min and max, inclusive 1. [](#improved) * Added alias `selfupdate` to the `self-upgrade` `bin/gpm` CLI command * Synced `webserver-configs/htaccess.txt` with `.htaccess` diff --git a/system/src/Grav/Common/Twig/TwigExtension.php b/system/src/Grav/Common/Twig/TwigExtension.php index c0a615392..aa9f1de04 100644 --- a/system/src/Grav/Common/Twig/TwigExtension.php +++ b/system/src/Grav/Common/Twig/TwigExtension.php @@ -116,6 +116,7 @@ class TwigExtension extends \Twig_Extension new \Twig_SimpleFunction('json_decode', [$this, 'jsonDecodeFilter']), new \Twig_SimpleFunction('get_cookie', [$this, 'getCookie']), new \Twig_SimpleFunction('redirect_me', [$this, 'redirectFunc']), + new \Twig_SimpleFunction('range', [$this, 'rangeFunc']), ]; } @@ -821,18 +822,30 @@ class TwigExtension extends \Twig_Extension { return preg_replace($pattern, $replace, $subject, $limit); } - + /** * redirect browser from twig * * @param string $url the url to redirect to - * @param string $statusCode statuscode, default 303 - * - * @return none + * @param int $statusCode statusCode, default 303 */ public function redirectFunc($url, $statusCode = 303) { header('Location: ' . $url, true, $statusCode); die(); } + + /** + * Generates an array containing a range of elements, optionally stepped + * + * @param int $start Minimum number, default 0 + * @param int $end Maximum number, default `getrandmax()` + * @param int $step Increment between elements in the sequence, default 1 + * + * @return array + */ + public function rangeFunc($start = 0, $end = 100, $step = 1) + { + return range($start, $end, $step); + } } diff --git a/tests/unit/Grav/Common/Twig/TwigExtensionTest.php b/tests/unit/Grav/Common/Twig/TwigExtensionTest.php index df70fc53c..1c1f6fa0a 100644 --- a/tests/unit/Grav/Common/Twig/TwigExtensionTest.php +++ b/tests/unit/Grav/Common/Twig/TwigExtensionTest.php @@ -183,4 +183,26 @@ class TwigExtensionTest extends \Codeception\TestCase\Test { } + + public function testRangeFunc() + { + $hundred = []; + for($i = 0; $i <= 100; $i++) { $hundred[] = $i; } + + + $this->assertSame([0], $this->twig_ext->rangeFunc(0, 0)); + $this->assertSame([0, 1, 2], $this->twig_ext->rangeFunc(0, 2)); + + $this->assertSame([0, 5, 10, 15], $this->twig_ext->rangeFunc(0, 16, 5)); + + // default (min 0, max 100, step 1) + $this->assertSame($hundred, $this->twig_ext->rangeFunc()); + + // 95 items, starting from 5, (min 5, max 100, step 1) + $this->assertSame(array_slice($hundred, 5), $this->twig_ext->rangeFunc(5)); + + // reversed range + $this->assertSame(array_reverse($hundred), $this->twig_ext->rangeFunc(100, 0)); + $this->assertSame([4, 2, 0], $this->twig_ext->rangeFunc(4, 0, 2)); + } } From c64cdb5dad6e970b52346e53dcac970b014f4176 Mon Sep 17 00:00:00 2001 From: Djamil Legato Date: Thu, 1 Dec 2016 12:42:59 -0800 Subject: [PATCH 35/56] Typos in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d88d4f2e..0b1c42f81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ 1. [](#new) * Add `ignore_empty` property to be used on array fields, if positive only save options with a value * Use new `permissions` field in user account - * Add `range(int min, int max, int step)` twig function to generate an array of numbers between min and max, inclusive + * Add `range(int start, int end, int step)` twig function to generate an array of numbers between start and end, inclusive 1. [](#improved) * Added alias `selfupdate` to the `self-upgrade` `bin/gpm` CLI command * Synced `webserver-configs/htaccess.txt` with `.htaccess` From 10da784d5334949c58e76af8139d8ea495333a59 Mon Sep 17 00:00:00 2001 From: Vivien HAAG Date: Fri, 2 Dec 2016 18:16:05 +0100 Subject: [PATCH 36/56] Fix Page Collections problem with @page.modular (#1178) --- system/src/Grav/Common/Page/Page.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index d0d62de48..a8703b9e7 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -507,7 +507,7 @@ class Page } $summary = Utils::truncateHTML($content, $size); - + return html_entity_decode($summary); } @@ -2419,7 +2419,10 @@ class Page switch ($parts[0]) { case 'modular': $results = new Collection(); - $results = $results->addPage($page)->Modular(); + foreach ($page->children() as $child) { + $results = $results->addPage($child); + } + $results->modular(); break; case 'page': case 'self': From 36428e47354d63c7f24b514ecfb5a35208319940 Mon Sep 17 00:00:00 2001 From: Fredrik Ekelund Date: Fri, 2 Dec 2016 18:21:59 +0100 Subject: [PATCH 37/56] Added ability to pass an array of explicit widths to ImageMedium#derivatives (#1133) * Added ability to pass an array of explicit widths to ImageMedium#derivatives Allows for more precise control than the min-width, max-width and step parameters. * ImageMedium#derivatives can now be called with an array from Markdown as well Previously it was only possible from Twig code or PHP code --- system/src/Grav/Common/Helpers/Excerpts.php | 11 +++++- .../Grav/Common/Page/Medium/ImageMedium.php | 37 +++++++++++++------ 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/system/src/Grav/Common/Helpers/Excerpts.php b/system/src/Grav/Common/Helpers/Excerpts.php index 090dd1121..3ab86ce03 100644 --- a/system/src/Grav/Common/Helpers/Excerpts.php +++ b/system/src/Grav/Common/Helpers/Excerpts.php @@ -282,8 +282,15 @@ class Excerpts // loop through actions for the image and call them foreach ($actions as $action) { - $medium = call_user_func_array([$medium, $action['method']], - explode(',', $action['params'])); + $matches = []; + + if (preg_match('/\[(.*)\]/', $action['params'], $matches)) { + $args = [explode(',', $matches[1])]; + } else { + $args = explode(',', $action['params']); + } + + $medium = call_user_func_array([$medium, $action['method']], $args); } if (isset($url_parts['fragment'])) { diff --git a/system/src/Grav/Common/Page/Medium/ImageMedium.php b/system/src/Grav/Common/Page/Medium/ImageMedium.php index 94602e336..2e92ccfd8 100644 --- a/system/src/Grav/Common/Page/Medium/ImageMedium.php +++ b/system/src/Grav/Common/Page/Medium/ImageMedium.php @@ -236,14 +236,16 @@ class ImageMedium extends Medium } /** - * Generate derivatives + * Generate alternative image widths, using either an array of integers, or + * a min width, a max width, and a step parameter to fill out the necessary + * widths. Existing image alternatives won't be overwritten. * - * @param int $min_width - * @param int $max_width - * @param int $step + * @param int|int[] $min_width + * @param int [$max_width=2500] + * @param int [$step=200] * @return $this */ - public function derivatives($min_width, $max_width, $step = 200) { + public function derivatives($min_width, $max_width = 2500, $step = 200) { if (!empty($this->alternatives)) { $max = max(array_keys($this->alternatives)); $base = $this->alternatives[$max]; @@ -251,10 +253,23 @@ class ImageMedium extends Medium $base = $this; } - // Do not upscale images. - $max_width = min($max_width, $base->get('width')); + $widths = []; - for ($width = $min_width; $width < $max_width; $width = $width + $step) { + if (func_num_args() === 1) { + foreach ((array) func_get_arg(0) as $width) { + if ($width < $base->get('width')) { + $widths[] = $width; + } + } + } else { + $max_width = min($max_width, $base->get('width')); + + for ($width = $min_width; $width < $max_width; $width = $width + $step) { + $widths[] = $width; + } + } + + foreach ($widths as $width) { // Only generate image alternatives that don't already exist if (array_key_exists((int) $width, $this->alternatives)) { continue; @@ -267,10 +282,10 @@ class ImageMedium extends Medium // retrieved from the page cache if (isset($derivative)) { $index = 2; - $widths = array_keys($this->alternatives); - sort($widths); + $alt_widths = array_keys($this->alternatives); + sort($alt_widths); - foreach ($widths as $i => $key) { + foreach ($alt_widths as $i => $key) { if ($width > $key) { $index += max($i, 1); } From 678c4457999f016b77b4492e6fc2e8edb6f1baf2 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Fri, 2 Dec 2016 10:27:39 -0700 Subject: [PATCH 38/56] updated changelog --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b1c42f81..615eae98d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,15 +5,18 @@ * Add `ignore_empty` property to be used on array fields, if positive only save options with a value * Use new `permissions` field in user account * Add `range(int start, int end, int step)` twig function to generate an array of numbers between start and end, inclusive + * New retina Media image derivatives array support (`![](image.jpg?derivatives=[640,1024,1440]`) [#1147](https://github.com/getgrav/grav/pull/1147) 1. [](#improved) * Added alias `selfupdate` to the `self-upgrade` `bin/gpm` CLI command * Synced `webserver-configs/htaccess.txt` with `.htaccess` + 1. [](#bugfix) + * Fix page collections problem with `@page.modular` [#1178](https://github.com/getgrav/grav/pull/1178) # v1.1.9-rc.2 ## 11/26/2016 1. [](#new) - * Added two new sort order options for pages: `publish_date` and `unpublish_date` + * Added two new sort order options for pages: `publish_date` and `unpublish_date` [#1173](https://github.com/getgrav/grav/pull/1173)) 1. [](#improved) * Multisite: Create image cache folder if it doesn't exist * Add 2 new language values for French [#1174](https://github.com/getgrav/grav/issues/1174) From 896fb8138bcde436ad4ade3f9670f9a8008ddd9f Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Sat, 3 Dec 2016 13:47:25 +0100 Subject: [PATCH 39/56] Fix #1184 Fix issue with using a multiple taxonomy filter of which one had no results If there are 2+ taxonomies required but one has 0 items, it was just picking the ones corresponding to the other taxonomy, thus generating a wrong result. Adding an empty array will later make array_intersect_key generate an empty array if the operation is `and` --- CHANGELOG.md | 1 + system/src/Grav/Common/Taxonomy.php | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 615eae98d..a12e7deae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * Synced `webserver-configs/htaccess.txt` with `.htaccess` 1. [](#bugfix) * Fix page collections problem with `@page.modular` [#1178](https://github.com/getgrav/grav/pull/1178) + * Fix issue with using a multiple taxonomy filter of which one had no results [#1184](https://github.com/getgrav/grav/issues/1184) # v1.1.9-rc.2 ## 11/26/2016 diff --git a/system/src/Grav/Common/Taxonomy.php b/system/src/Grav/Common/Taxonomy.php index 37975f7a1..25be7edd3 100644 --- a/system/src/Grav/Common/Taxonomy.php +++ b/system/src/Grav/Common/Taxonomy.php @@ -93,6 +93,8 @@ class Taxonomy foreach ((array)$items as $item) { if (isset($this->taxonomy_map[$taxonomy][$item])) { $matches[] = $this->taxonomy_map[$taxonomy][$item]; + } else { + $matches[] = []; } } } @@ -126,7 +128,7 @@ class Taxonomy return $this->taxonomy_map; } - + /** * Gets item keys per taxonomy * From 4a5847784ab40df521c6b1b4cad5f53d43c6406c Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Mon, 5 Dec 2016 10:06:47 +0100 Subject: [PATCH 40/56] Thanks to @hughbris for taxonomy filter issue https://github.com/getgrav/grav/commit/896fb8138bcde436ad4ade3f9670f9a8008ddd9f --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a12e7deae..dede6f8ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ * Synced `webserver-configs/htaccess.txt` with `.htaccess` 1. [](#bugfix) * Fix page collections problem with `@page.modular` [#1178](https://github.com/getgrav/grav/pull/1178) - * Fix issue with using a multiple taxonomy filter of which one had no results [#1184](https://github.com/getgrav/grav/issues/1184) + * Fix issue with using a multiple taxonomy filter of which one had no results, thanks to @hughbris [#1184](https://github.com/getgrav/grav/issues/1184) # v1.1.9-rc.2 ## 11/26/2016 From 6c1a76b901365a2196db546c714e9db9c4c5445b Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Mon, 5 Dec 2016 19:17:46 +0100 Subject: [PATCH 41/56] Use permissions field in group details. Fix saving permissions --- CHANGELOG.md | 2 ++ system/blueprints/user/group.yaml | 15 ++++----------- system/src/Grav/Common/User/Group.php | 2 +- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dede6f8ef..df6aaeaf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,9 +9,11 @@ 1. [](#improved) * Added alias `selfupdate` to the `self-upgrade` `bin/gpm` CLI command * Synced `webserver-configs/htaccess.txt` with `.htaccess` + * Use permissions field in group details. 1. [](#bugfix) * Fix page collections problem with `@page.modular` [#1178](https://github.com/getgrav/grav/pull/1178) * Fix issue with using a multiple taxonomy filter of which one had no results, thanks to @hughbris [#1184](https://github.com/getgrav/grav/issues/1184) + * Fix saving permissions in group # v1.1.9-rc.2 ## 11/26/2016 diff --git a/system/blueprints/user/group.yaml b/system/blueprints/user/group.yaml index 0adcbb5c0..a5a7477b6 100644 --- a/system/blueprints/user/group.yaml +++ b/system/blueprints/user/group.yaml @@ -29,16 +29,9 @@ form: size: small label: PLUGIN_ADMIN_PRO.ICON - access.admin: - type: array - label: PLUGIN_ADMIN.ADMIN_ACCESS - multiple: false - validate: - type: array - - access.site: - type: array - label: PLUGIN_ADMIN.SITE_ACCESS - multiple: false + access: + type: permissions + label: PLUGIN_ADMIN.PERMISSIONS + ignore_empty: true validate: type: array diff --git a/system/src/Grav/Common/User/Group.php b/system/src/Grav/Common/User/Group.php index 7092cfce4..2a29340db 100644 --- a/system/src/Grav/Common/User/Group.php +++ b/system/src/Grav/Common/User/Group.php @@ -87,7 +87,7 @@ class Group extends Data $config->set("groups.$this->groupname.$value", $this->items['data'][$value]); } } - if ($field['type'] == 'array') { + if ($field['type'] == 'array' || $field['type'] == 'permissions') { $value = $field['name']; $arrayValues = Utils::getDotNotation($this->items['data'], $field['name']); From 83fdecbdd165aae2786f2e57d3876cc345218a7f Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Wed, 7 Dec 2016 19:51:06 +0200 Subject: [PATCH 42/56] Added stream support for images (`![Sepia Image](image://image.jpg?sepia)`) Added stream support for links (`[Download PDF](user://data/pdf/my.pdf)`) --- CHANGELOG.md | 4 +- system/src/Grav/Common/Helpers/Excerpts.php | 159 +++++++++----- system/src/Grav/Common/Page/Media.php | 195 +++++------------- .../Grav/Common/Page/Medium/AbstractMedia.php | 154 ++++++++++++++ .../Grav/Common/Page/Medium/GlobalMedia.php | 117 +++++++++++ system/src/Grav/Common/Page/Medium/Medium.php | 4 +- 6 files changed, 425 insertions(+), 208 deletions(-) create mode 100644 system/src/Grav/Common/Page/Medium/AbstractMedia.php create mode 100644 system/src/Grav/Common/Page/Medium/GlobalMedia.php diff --git a/CHANGELOG.md b/CHANGELOG.md index df6aaeaf2..5584e98f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,9 @@ * Add `ignore_empty` property to be used on array fields, if positive only save options with a value * Use new `permissions` field in user account * Add `range(int start, int end, int step)` twig function to generate an array of numbers between start and end, inclusive - * New retina Media image derivatives array support (`![](image.jpg?derivatives=[640,1024,1440]`) [#1147](https://github.com/getgrav/grav/pull/1147) + * New retina Media image derivatives array support (`![](image.jpg?derivatives=[640,1024,1440])`) [#1147](https://github.com/getgrav/grav/pull/1147) + * Added stream support for images (`![Sepia Image](image://image.jpg?sepia)`) + * Added stream support for links (`[Download PDF](user://data/pdf/my.pdf)`) 1. [](#improved) * Added alias `selfupdate` to the `self-upgrade` `bin/gpm` CLI command * Synced `webserver-configs/htaccess.txt` with `.htaccess` diff --git a/system/src/Grav/Common/Helpers/Excerpts.php b/system/src/Grav/Common/Helpers/Excerpts.php index 3ab86ce03..05afd3df4 100644 --- a/system/src/Grav/Common/Helpers/Excerpts.php +++ b/system/src/Grav/Common/Helpers/Excerpts.php @@ -10,9 +10,9 @@ namespace Grav\Common\Helpers; use Grav\Common\Grav; use Grav\Common\Uri; -use Grav\Common\Utils; use Grav\Common\Page\Medium\Medium; use RocketTheme\Toolbox\Event\Event; +use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; class Excerpts { @@ -115,11 +115,11 @@ class Excerpts */ public static function processLinkExcerpt($excerpt, $page, $type = 'link') { - $url = $excerpt['element']['attributes']['href']; + $url = htmlspecialchars_decode(urldecode($excerpt['element']['attributes']['href'])); - $url_parts = parse_url(htmlspecialchars_decode(urldecode($url))); + $url_parts = static::parseUrl($url); - // if there is a query, then parse it and build action calls + // If there is a query, then parse it and build action calls. if (isset($url_parts['query'])) { $actions = array_reduce(explode('&', $url_parts['query']), function ($carry, $item) { $parts = explode('=', $item, 2); @@ -129,19 +129,19 @@ class Excerpts return $carry; }, []); - // valid attributes supported + // Valid attributes supported. $valid_attributes = ['rel', 'target', 'id', 'class', 'classes']; - // Unless told to not process, go through actions + // Unless told to not process, go through actions. if (array_key_exists('noprocess', $actions)) { unset($actions['noprocess']); } else { - // loop through actions for the image and call them + // Loop through actions for the image and call them. foreach ($actions as $attrib => $value) { $key = $attrib; if (in_array($attrib, $valid_attributes)) { - // support both class and classes + // support both class and classes. if ($attrib == 'classes') { $attrib = 'class'; } @@ -154,25 +154,33 @@ class Excerpts $url_parts['query'] = http_build_query($actions, null, '&', PHP_QUERY_RFC3986); } - // if no query elements left, unset query + // If no query elements left, unset query. if (empty($url_parts['query'])) { unset ($url_parts['query']); } - // set path to / if not set + // Set path to / if not set. if (empty($url_parts['path'])) { $url_parts['path'] = ''; } - // if special scheme, just return - if(isset($url_parts['scheme']) && !Utils::startsWith($url_parts['scheme'], 'http')) { + // If scheme isn't http(s).. + if (!empty($url_parts['scheme']) && !in_array($url_parts['scheme'], ['http', 'https'])) { + // Handle custom streams. + if ($type !== 'image' && !empty($url_parts['stream']) && !empty($url_parts['path'])) { + $url_parts['path'] = Grav::instance()['base_url_relative'] . '/' . static::resolveStream("{$url_parts['scheme']}://{$url_parts['path']}"); + unset($url_parts['stream'], $url_parts['scheme']); + + $excerpt['element']['attributes']['href'] = Uri::buildUrl($url_parts); + } + return $excerpt; } - // handle paths and such + // Handle paths and such. $url_parts = Uri::convertUrl($page, $url_parts, $type); - // build the URL from the component parts and set it on the element + // Build the URL from the component parts and set it on the element. $excerpt['element']['attributes']['href'] = Uri::buildUrl($url_parts); return $excerpt; @@ -187,62 +195,65 @@ class Excerpts */ public static function processImageExcerpt($excerpt, $page) { - $url = $excerpt['element']['attributes']['src']; + $url = htmlspecialchars_decode(urldecode($excerpt['element']['attributes']['src'])); + $url_parts = static::parseUrl($url); - $url_parts = parse_url(htmlspecialchars_decode(urldecode($url))); + $media = null; + $filename = null; - if (isset($url_parts['scheme']) && !Utils::startsWith($url_parts['scheme'], 'http')) { - $stream_path = $url_parts['scheme'] . '://' . $url_parts['host'] . $url_parts['path']; - $url_parts['path'] = $stream_path; - unset($url_parts['host']); - unset($url_parts['scheme']); - } + if (!empty($url_parts['stream'])) { + $filename = $url_parts['scheme'] . '://' . (isset($url_parts['path']) ? $url_parts['path'] : ''); - $this_host = isset($url_parts['host']) && $url_parts['host'] == Grav::instance()['uri']->host(); + $media = $page->media(); - // if there is no host set but there is a path, the file is local - if ((!isset($url_parts['host']) || $this_host) && isset($url_parts['path'])) { + } else { + // File is also local if scheme is http(s) and host matches. + $local_file = isset($url_parts['path']) + && (empty($url_parts['scheme']) || in_array($url_parts['scheme'], ['http', 'https'])) + && (empty($url_parts['host']) || $url_parts['host'] == Grav::instance()['uri']->host()); - $path_parts = pathinfo($url_parts['path']); - $media = null; + if ($local_file) { + $filename = basename($url_parts['path']); + $folder = dirname($url_parts['path']); - // get the local path to page media if possible - if ($path_parts['dirname'] == $page->url(false, false, false)) { - // get the media objects for this page - $media = $page->media(); - } else { - // see if this is an external page to this one - $base_url = rtrim(Grav::instance()['base_url_relative'] . Grav::instance()['pages']->base(), '/'); - $page_route = '/' . ltrim(str_replace($base_url, '', $path_parts['dirname']), '/'); - - $ext_page = Grav::instance()['pages']->dispatch($page_route, true); - if ($ext_page) { - $media = $ext_page->media(); + // Get the local path to page media if possible. + if ($folder === $page->url(false, false, false)) { + // Get the media objects for this page. + $media = $page->media(); } else { - Grav::instance()->fireEvent('onMediaLocate', new Event(['route' => $page_route, 'media' => &$media])); + // see if this is an external page to this one + $base_url = rtrim(Grav::instance()['base_url_relative'] . Grav::instance()['pages']->base(), '/'); + $page_route = '/' . ltrim(str_replace($base_url, '', $folder), '/'); + + $ext_page = Grav::instance()['pages']->dispatch($page_route, true); + if ($ext_page) { + $media = $ext_page->media(); + } else { + Grav::instance()->fireEvent('onMediaLocate', new Event(['route' => $page_route, 'media' => &$media])); + } } } + } - // if there is a media file that matches the path referenced.. - if ($media && isset($media->all()[$path_parts['basename']])) { - // get the medium object - /** @var Medium $medium */ - $medium = $media->all()[$path_parts['basename']]; + // If there is a media file that matches the path referenced.. + if ($media && $filename && isset($media[$filename])) { + // Get the medium object. + /** @var Medium $medium */ + $medium = $media[$filename]; - // Process operations - $medium = static::processMediaActions($medium, $url_parts); + // Process operations + $medium = static::processMediaActions($medium, $url_parts); - $alt = isset($excerpt['element']['attributes']['alt']) ? $excerpt['element']['attributes']['alt'] : ''; - $title = isset($excerpt['element']['attributes']['title']) ? $excerpt['element']['attributes']['title'] : ''; - $class = isset($excerpt['element']['attributes']['class']) ? $excerpt['element']['attributes']['class'] : ''; - $id = isset($excerpt['element']['attributes']['id']) ? $excerpt['element']['attributes']['id'] : ''; + $alt = isset($excerpt['element']['attributes']['alt']) ? $excerpt['element']['attributes']['alt'] : ''; + $title = isset($excerpt['element']['attributes']['title']) ? $excerpt['element']['attributes']['title'] : ''; + $class = isset($excerpt['element']['attributes']['class']) ? $excerpt['element']['attributes']['class'] : ''; + $id = isset($excerpt['element']['attributes']['id']) ? $excerpt['element']['attributes']['id'] : ''; - $excerpt['element'] = $medium->parseDownElement($title, $alt, $class, $id, true); + $excerpt['element'] = $medium->parseDownElement($title, $alt, $class, $id, true); - } else { - // not a current page media file, see if it needs converting to relative - $excerpt['element']['attributes']['src'] = Uri::buildUrl($url_parts); - } + } else { + // Not a current page media file, see if it needs converting to relative. + $excerpt['element']['attributes']['src'] = Uri::buildUrl($url_parts); } return $excerpt; @@ -300,4 +311,40 @@ class Excerpts return $medium; } + /** + * Variation of parse_url() which works also with local streams. + * + * @param string $url + * @return array|bool + */ + protected static function parseUrl($url) + { + $url_parts = parse_url($url); + + if (isset($url_parts['scheme'])) { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + + // Special handling for the streams. + if ($locator->schemeExists($url_parts['scheme'])) { + if (isset($url_parts['host'])) { + // Merge host and path into a path. + $url_parts['path'] = $url_parts['host'] . (isset($url_parts['path']) ? '/' . $url_parts['path'] : ''); + unset($url_parts['host']); + } + + $url_parts['stream'] = true; + } + } + + return $url_parts; + } + + protected static function resolveStream($url) + { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + + return $locator->isStream($url) ? ($locator->findResource($url, false) ?: $locator->findResource($url, false, true)) : $url; + } } diff --git a/system/src/Grav/Common/Page/Media.php b/system/src/Grav/Common/Page/Media.php index 16dfdf313..7d1522f9e 100644 --- a/system/src/Grav/Common/Page/Media.php +++ b/system/src/Grav/Common/Page/Media.php @@ -8,51 +8,78 @@ namespace Grav\Common\Page; -use Grav\Common\Getters; -use Grav\Common\Page\Medium\Medium; +use Grav\Common\Page\Medium\AbstractMedia; +use Grav\Common\Page\Medium\GlobalMedia; use Grav\Common\Page\Medium\MediumFactory; +use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; -class Media extends Getters +class Media extends AbstractMedia { - protected $gettersVariable = 'instances'; + protected static $global; + protected $path; - - protected $instances = []; - protected $images = []; - protected $videos = []; - protected $audios = []; - protected $files = []; - + /** * @param $path */ public function __construct($path) { + $this->path = $path; + + if (!isset(static::$global)) { + // Add fallback to global media. + static::$global = new GlobalMedia($path); + } + + $this->init(); + } + + /** + * @param mixed $offset + * + * @return bool + */ + public function offsetExists($offset) + { + return parent::offsetExists($offset) ?: isset(static::$global[$offset]); + } + + /** + * @param mixed $offset + * + * @return mixed + */ + public function offsetGet($offset) + { + return parent::offsetGet($offset) ?: static::$global[$offset]; + } + + /** + * Initialize class. + */ + protected function init() + { + // Handle special cases where page doesn't exist in filesystem. - if (!is_dir($path)) { + if (!is_dir($this->path)) { return; } - $this->path = $path; - - $iterator = new \FilesystemIterator($path, \FilesystemIterator::UNIX_PATHS | \FilesystemIterator::SKIP_DOTS); + $iterator = new \FilesystemIterator($this->path, \FilesystemIterator::UNIX_PATHS | \FilesystemIterator::SKIP_DOTS); $media = []; /** @var \DirectoryIterator $info */ foreach ($iterator as $path => $info) { // Ignore folders and Markdown files. - if (!$info->isFile() || $info->getExtension() == 'md' || $info->getBasename() === '.DS_Store') { + if (!$info->isFile() || $info->getExtension() == 'md' || $info->getBasename()[0] === '.') { continue; } // Find out what type we're dealing with list($basename, $ext, $type, $extra) = $this->getFileParts($info->getFilename()); - $media["{$basename}.{$ext}"] = isset($media["{$basename}.{$ext}"]) ? $media["{$basename}.{$ext}"] : []; - if ($type === 'alternative') { - $media["{$basename}.{$ext}"][$type] = isset($media["{$basename}.{$ext}"][$type]) ? $media["{$basename}.{$ext}"][$type] : []; $media["{$basename}.{$ext}"][$type][$extra] = [ 'file' => $path, 'size' => $info->getSize() ]; } else { $media["{$basename}.{$ext}"][$type] = [ 'file' => $path, 'size' => $info->getSize() ]; @@ -124,134 +151,4 @@ class Media extends Getters $this->add($name, $medium); } } - - /** - * Get medium by filename. - * - * @param string $filename - * @return Medium|null - */ - public function get($filename) - { - return isset($this->instances[$filename]) ? $this->instances[$filename] : null; - } - - /** - * Get a list of all media. - * - * @return array|Medium[] - */ - public function all() - { - ksort($this->instances, SORT_NATURAL | SORT_FLAG_CASE); - return $this->instances; - } - - /** - * Get a list of all image media. - * - * @return array|Medium[] - */ - public function images() - { - ksort($this->images, SORT_NATURAL | SORT_FLAG_CASE); - return $this->images; - } - - /** - * Get a list of all video media. - * - * @return array|Medium[] - */ - public function videos() - { - ksort($this->videos, SORT_NATURAL | SORT_FLAG_CASE); - return $this->videos; - } - - /** - * Get a list of all audio media. - * - * @return array|Medium[] - */ - public function audios() - { - ksort($this->audios, SORT_NATURAL | SORT_FLAG_CASE); - return $this->audios; - } - - /** - * Get a list of all file media. - * - * @return array|Medium[] - */ - public function files() - { - ksort($this->files, SORT_NATURAL | SORT_FLAG_CASE); - return $this->files; - } - - /** - * @internal - */ - protected function add($name, $file) - { - $this->instances[$name] = $file; - switch ($file->type) { - case 'image': - $this->images[$name] = $file; - break; - case 'video': - $this->videos[$name] = $file; - break; - case 'audio': - $this->audios[$name] = $file; - break; - default: - $this->files[$name] = $file; - } - } - - /** - * Get filename, extension and meta part. - * - * @param string $filename - * @return array - */ - protected function getFileParts($filename) - { - $fileParts = explode('.', $filename); - - $name = array_shift($fileParts); - $type = 'base'; - $extra = null; - - if (preg_match('/(.*)@(\d+)x\.(.*)$/', $filename, $matches)) { - $name = $matches[1]; - $extension = $matches[3]; - $extra = (int) $matches[2]; - $type = 'alternative'; - - if ($extra === 1) { - $type = 'base'; - $extra = null; - } - } else { - $extension = null; - while (($part = array_shift($fileParts)) !== null) { - if ($part != 'meta' && $part != 'thumb') { - if (isset($extension)) { - $name .= '.' . $extension; - } - $extension = $part; - } else { - $type = $part; - $extra = '.' . $part . '.' . implode('.', $fileParts); - break; - } - } - } - - return array($name, $extension, $type, $extra); - } } diff --git a/system/src/Grav/Common/Page/Medium/AbstractMedia.php b/system/src/Grav/Common/Page/Medium/AbstractMedia.php new file mode 100644 index 000000000..8d86ea027 --- /dev/null +++ b/system/src/Grav/Common/Page/Medium/AbstractMedia.php @@ -0,0 +1,154 @@ +offsetGet($filename); + } + + /** + * Get a list of all media. + * + * @return array|Medium[] + */ + public function all() + { + ksort($this->instances, SORT_NATURAL | SORT_FLAG_CASE); + return $this->instances; + } + + /** + * Get a list of all image media. + * + * @return array|Medium[] + */ + public function images() + { + ksort($this->images, SORT_NATURAL | SORT_FLAG_CASE); + return $this->images; + } + + /** + * Get a list of all video media. + * + * @return array|Medium[] + */ + public function videos() + { + ksort($this->videos, SORT_NATURAL | SORT_FLAG_CASE); + return $this->videos; + } + + /** + * Get a list of all audio media. + * + * @return array|Medium[] + */ + public function audios() + { + ksort($this->audios, SORT_NATURAL | SORT_FLAG_CASE); + return $this->audios; + } + + /** + * Get a list of all file media. + * + * @return array|Medium[] + */ + public function files() + { + ksort($this->files, SORT_NATURAL | SORT_FLAG_CASE); + return $this->files; + } + + /** + * @param string $name + * @param Medium $file + */ + protected function add($name, $file) + { + $this->instances[$name] = $file; + switch ($file->type) { + case 'image': + $this->images[$name] = $file; + break; + case 'video': + $this->videos[$name] = $file; + break; + case 'audio': + $this->audios[$name] = $file; + break; + default: + $this->files[$name] = $file; + } + } + + /** + * Get filename, extension and meta part. + * + * @param string $filename + * @return array + */ + protected function getFileParts($filename) + { + if (preg_match('/(.*)@(\d+)x\.(.*)$/', $filename, $matches)) { + $name = $matches[1]; + $extension = $matches[3]; + $extra = (int) $matches[2]; + $type = 'alternative'; + + if ($extra === 1) { + $type = 'base'; + $extra = null; + } + } else { + $fileParts = explode('.', $filename); + + $name = array_shift($fileParts); + $extension = null; + $extra = null; + $type = 'base'; + + while (($part = array_shift($fileParts)) !== null) { + if ($part != 'meta' && $part != 'thumb') { + if (isset($extension)) { + $name .= '.' . $extension; + } + $extension = $part; + } else { + $type = $part; + $extra = '.' . $part . '.' . implode('.', $fileParts); + break; + } + } + } + + return array($name, $extension, $type, $extra); + } +} diff --git a/system/src/Grav/Common/Page/Medium/GlobalMedia.php b/system/src/Grav/Common/Page/Medium/GlobalMedia.php new file mode 100644 index 000000000..6b5629eca --- /dev/null +++ b/system/src/Grav/Common/Page/Medium/GlobalMedia.php @@ -0,0 +1,117 @@ +resolveStream($offset)); + } + + /** + * @param mixed $offset + * + * @return mixed + */ + public function offsetGet($offset) + { + return parent::offsetGet($offset) ?: $this->addMedium($offset); + } + + /** + * @param string $filename + * @return string|null + */ + protected function resolveStream($filename) + { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + + return $locator->isStream($filename) ? ($locator->findResource($filename) ?: null) : null; + } + + /** + * @param string $stream + * @return Medium|null + */ + protected function addMedium($stream) + { + $filename = $this->resolveStream($stream); + if (!$filename) { + return null; + } + + $path = dirname($filename); + list($basename, $ext,, $extra) = $this->getFileParts(basename($filename)); + $medium = MediumFactory::fromFile($filename); + + if (empty($medium)) { + return null; + } + + $medium->set('size', filesize($filename)); + $scale = (int) ($extra ?: 1); + + if ($scale !== 1) { + $altMedium = $medium; + + // Create scaled down regular sized image. + $medium = MediumFactory::scaledFromMedium($altMedium, $scale, 1)['file']; + + if (empty($medium)) { + return null; + } + + // Add original sized image as alternative. + $medium->addAlternative($scale, $altMedium['file']); + + // Locate or generate smaller retina images. + for ($i = $scale-1; $i > 1; $i--) { + $altFilename = "{$path}/{$basename}@{$i}x.{$ext}"; + + if (file_exists($altFilename)) { + $scaled = MediumFactory::fromFile($altFilename); + } else { + $scaled = MediumFactory::scaledFromMedium($altMedium, $scale, $i)['file']; + } + + if ($scaled) { + $medium->addAlternative($i, $scaled); + } + } + } + + $meta = "{$path}/{$basename}.{$ext}.yaml"; + if (file_exists($meta)) { + $medium->addMetaFile($meta); + } + $meta = "{$path}/{$basename}.{$ext}.meta.yaml"; + if (file_exists($meta)) { + $medium->addMetaFile($meta); + } + + $thumb = "{$path}/{$basename}.thumb.{$ext}"; + if (file_exists($thumb)) { + $medium->set('thumbnails.page', $thumb); + } + + $this->add($stream, $medium); + + return $medium; + } +} diff --git a/system/src/Grav/Common/Page/Medium/Medium.php b/system/src/Grav/Common/Page/Medium/Medium.php index b9e338854..342efb3ae 100644 --- a/system/src/Grav/Common/Page/Medium/Medium.php +++ b/system/src/Grav/Common/Page/Medium/Medium.php @@ -150,8 +150,8 @@ class Medium extends Data implements RenderableInterface /** * Get/set querystring for the file's url * - * @param string $hash - * @param boolean $withHash + * @param string $querystring + * @param boolean $withQuestionmark * @return string */ public function querystring($querystring = null, $withQuestionmark = true) From 27ad9a24ebb4845c4b10ea15b030f4f3cdb9cfe1 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 7 Dec 2016 11:51:56 -0700 Subject: [PATCH 43/56] Updated vendor libraries --- CHANGELOG.md | 1 + composer.lock | 285 +++++++++++++++++++++++++------------------------- 2 files changed, 145 insertions(+), 141 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5584e98f2..f52621510 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * Added alias `selfupdate` to the `self-upgrade` `bin/gpm` CLI command * Synced `webserver-configs/htaccess.txt` with `.htaccess` * Use permissions field in group details. + * Updated vendor libraries 1. [](#bugfix) * Fix page collections problem with `@page.modular` [#1178](https://github.com/getgrav/grav/pull/1178) * Fix issue with using a multiple taxonomy filter of which one had no results, thanks to @hughbris [#1184](https://github.com/getgrav/grav/issues/1184) diff --git a/composer.lock b/composer.lock index 92c0cb53d..d00fccb24 100644 --- a/composer.lock +++ b/composer.lock @@ -53,16 +53,16 @@ }, { "name": "doctrine/cache", - "version": "v1.6.0", + "version": "v1.6.1", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6" + "reference": "b6f544a20f4807e81f7044d31e679ccbb1866dc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/f8af318d14bdb0eff0336795b428b547bd39ccb6", - "reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6", + "url": "https://api.github.com/repos/doctrine/cache/zipball/b6f544a20f4807e81f7044d31e679ccbb1866dc3", + "reference": "b6f544a20f4807e81f7044d31e679ccbb1866dc3", "shasum": "" }, "require": { @@ -119,7 +119,7 @@ "cache", "caching" ], - "time": "2015-12-31 16:37:02" + "time": "2016-10-29 11:16:17" }, { "name": "donatj/phpuseragentparser", @@ -178,12 +178,12 @@ "source": { "type": "git", "url": "https://github.com/erusev/parsedown.git", - "reference": "cbc4b3f6126e484acc033ec4edf3886f319a0c0f" + "reference": "20ff8bbb57205368b4b42d094642a3e52dac85fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/erusev/parsedown/zipball/cbc4b3f6126e484acc033ec4edf3886f319a0c0f", - "reference": "cbc4b3f6126e484acc033ec4edf3886f319a0c0f", + "url": "https://api.github.com/repos/erusev/parsedown/zipball/20ff8bbb57205368b4b42d094642a3e52dac85fb", + "reference": "20ff8bbb57205368b4b42d094642a3e52dac85fb", "shasum": "" }, "require": { @@ -212,7 +212,7 @@ "markdown", "parser" ], - "time": "2016-10-09 10:04:16" + "time": "2016-11-02 15:56:58" }, { "name": "erusev/parsedown-extra", @@ -466,16 +466,16 @@ }, { "name": "matthiasmullie/minify", - "version": "1.3.38", + "version": "1.3.42", "source": { "type": "git", "url": "https://github.com/matthiasmullie/minify.git", - "reference": "de4bcf23b6a3291bd828ce800aab834304eb50c5" + "reference": "b473affbb76ae6ec4e46d368b5081b5bfcdd3ed2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/de4bcf23b6a3291bd828ce800aab834304eb50c5", - "reference": "de4bcf23b6a3291bd828ce800aab834304eb50c5", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/b473affbb76ae6ec4e46d368b5081b5bfcdd3ed2", + "reference": "b473affbb76ae6ec4e46d368b5081b5bfcdd3ed2", "shasum": "" }, "require": { @@ -484,6 +484,7 @@ "php": ">=5.3.0" }, "require-dev": { + "friendsofphp/php-cs-fixer": "~1.0", "matthiasmullie/scrapbook": "~1.0", "phpunit/phpunit": "~4.8" }, @@ -518,7 +519,7 @@ "minifier", "minify" ], - "time": "2016-10-13 11:49:22" + "time": "2016-11-23 10:16:14" }, { "name": "matthiasmullie/path-converter", @@ -632,16 +633,16 @@ }, { "name": "monolog/monolog", - "version": "1.21.0", + "version": "1.22.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "f42fbdfd53e306bda545845e4dbfd3e72edb4952" + "reference": "bad29cb8d18ab0315e6c477751418a82c850d558" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f42fbdfd53e306bda545845e4dbfd3e72edb4952", - "reference": "f42fbdfd53e306bda545845e4dbfd3e72edb4952", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bad29cb8d18ab0315e6c477751418a82c850d558", + "reference": "bad29cb8d18ab0315e6c477751418a82c850d558", "shasum": "" }, "require": { @@ -652,7 +653,7 @@ "psr/log-implementation": "1.0.0" }, "require-dev": { - "aws/aws-sdk-php": "^2.4.9", + "aws/aws-sdk-php": "^2.4.9 || ^3.0", "doctrine/couchdb": "~1.0@dev", "graylog2/gelf-php": "~1.0", "jakub-onderka/php-parallel-lint": "0.9", @@ -706,7 +707,7 @@ "logging", "psr-3" ], - "time": "2016-07-29 03:23:52" + "time": "2016-11-26 00:15:39" }, { "name": "pimple/pimple", @@ -899,16 +900,16 @@ }, { "name": "symfony/console", - "version": "v2.8.12", + "version": "v2.8.14", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "d7a5a88178f94dcc29531ea4028ea614e35452d4" + "reference": "a871ba00e0f604dceac64c56c27f99fbeaf4854e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/d7a5a88178f94dcc29531ea4028ea614e35452d4", - "reference": "d7a5a88178f94dcc29531ea4028ea614e35452d4", + "url": "https://api.github.com/repos/symfony/console/zipball/a871ba00e0f604dceac64c56c27f99fbeaf4854e", + "reference": "a871ba00e0f604dceac64c56c27f99fbeaf4854e", "shasum": "" }, "require": { @@ -956,7 +957,7 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2016-09-28 00:10:16" + "time": "2016-11-15 23:02:12" }, { "name": "symfony/debug", @@ -1017,16 +1018,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v2.8.12", + "version": "v2.8.14", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "889983a79a043dfda68f38c38b6dba092dd49cd8" + "reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/889983a79a043dfda68f38c38b6dba092dd49cd8", - "reference": "889983a79a043dfda68f38c38b6dba092dd49cd8", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/25c576abd4e0f212e678fe8b2bd9a9a98c7ea934", + "reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934", "shasum": "" }, "require": { @@ -1073,20 +1074,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2016-07-28 16:56:28" + "time": "2016-10-13 01:43:15" }, { "name": "symfony/polyfill-iconv", - "version": "v1.2.0", + "version": "v1.3.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "b287e8554b1ffd9b5b20b5df940d906930ff4a10" + "reference": "cba36f3616d9866b3e52662e88da5c090fac1e97" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/b287e8554b1ffd9b5b20b5df940d906930ff4a10", - "reference": "b287e8554b1ffd9b5b20b5df940d906930ff4a10", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/cba36f3616d9866b3e52662e88da5c090fac1e97", + "reference": "cba36f3616d9866b3e52662e88da5c090fac1e97", "shasum": "" }, "require": { @@ -1098,7 +1099,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "1.3-dev" } }, "autoload": { @@ -1132,20 +1133,20 @@ "portable", "shim" ], - "time": "2016-05-18 14:26:46" + "time": "2016-11-14 01:06:16" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.2.0", + "version": "v1.3.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "dff51f72b0706335131b00a7f49606168c582594" + "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594", - "reference": "dff51f72b0706335131b00a7f49606168c582594", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4", + "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4", "shasum": "" }, "require": { @@ -1157,7 +1158,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "1.3-dev" } }, "autoload": { @@ -1191,20 +1192,20 @@ "portable", "shim" ], - "time": "2016-05-18 14:26:46" + "time": "2016-11-14 01:06:16" }, { "name": "symfony/var-dumper", - "version": "v2.8.12", + "version": "v2.8.14", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "08761341cc4a3b2d9d9578364f7c655b178254aa" + "reference": "195c6238ec319cde9204b2d7f271654ceb69b71b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/08761341cc4a3b2d9d9578364f7c655b178254aa", - "reference": "08761341cc4a3b2d9d9578364f7c655b178254aa", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/195c6238ec319cde9204b2d7f271654ceb69b71b", + "reference": "195c6238ec319cde9204b2d7f271654ceb69b71b", "shasum": "" }, "require": { @@ -1254,20 +1255,20 @@ "debug", "dump" ], - "time": "2016-09-29 14:06:15" + "time": "2016-11-03 07:52:58" }, { "name": "symfony/yaml", - "version": "v2.8.12", + "version": "v2.8.14", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "e7540734bad981fe59f8ef14b6fc194ae9df8d9c" + "reference": "befb26a3713c97af90d25dd12e75621ef14d91ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/e7540734bad981fe59f8ef14b6fc194ae9df8d9c", - "reference": "e7540734bad981fe59f8ef14b6fc194ae9df8d9c", + "url": "https://api.github.com/repos/symfony/yaml/zipball/befb26a3713c97af90d25dd12e75621ef14d91ff", + "reference": "befb26a3713c97af90d25dd12e75621ef14d91ff", "shasum": "" }, "require": { @@ -1303,20 +1304,20 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-09-02 01:57:56" + "time": "2016-11-14 16:15:57" }, { "name": "twig/twig", - "version": "v1.26.1", + "version": "v1.28.2", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "a09d8ee17ac1cfea29ed60c83960ad685c6a898d" + "reference": "b22ce0eb070e41f7cba65d78fe216de29726459c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/a09d8ee17ac1cfea29ed60c83960ad685c6a898d", - "reference": "a09d8ee17ac1cfea29ed60c83960ad685c6a898d", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/b22ce0eb070e41f7cba65d78fe216de29726459c", + "reference": "b22ce0eb070e41f7cba65d78fe216de29726459c", "shasum": "" }, "require": { @@ -1324,12 +1325,12 @@ }, "require-dev": { "symfony/debug": "~2.7", - "symfony/phpunit-bridge": "~2.7" + "symfony/phpunit-bridge": "~3.2@dev" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.26-dev" + "dev-master": "1.28-dev" } }, "autoload": { @@ -1364,22 +1365,22 @@ "keywords": [ "templating" ], - "time": "2016-10-05 18:57:41" + "time": "2016-11-23 18:41:40" } ], "packages-dev": [ { "name": "behat/gherkin", - "version": "v4.4.4", + "version": "v4.4.5", "source": { "type": "git", "url": "https://github.com/Behat/Gherkin.git", - "reference": "cf8cc94647101e02a33d690245896d83d880aea1" + "reference": "5c14cff4f955b17d20d088dec1bde61c0539ec74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/Gherkin/zipball/cf8cc94647101e02a33d690245896d83d880aea1", - "reference": "cf8cc94647101e02a33d690245896d83d880aea1", + "url": "https://api.github.com/repos/Behat/Gherkin/zipball/5c14cff4f955b17d20d088dec1bde61c0539ec74", + "reference": "5c14cff4f955b17d20d088dec1bde61c0539ec74", "shasum": "" }, "require": { @@ -1425,20 +1426,20 @@ "gherkin", "parser" ], - "time": "2016-09-18 12:16:14" + "time": "2016-10-30 11:50:56" }, { "name": "codeception/codeception", - "version": "2.2.5", + "version": "2.2.7", "source": { "type": "git", "url": "https://github.com/Codeception/Codeception.git", - "reference": "b4729341e469d0f174f3cade85718ff5bf8dd751" + "reference": "86770e89d266557c20dd0b1de5390e706f4770c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/Codeception/zipball/b4729341e469d0f174f3cade85718ff5bf8dd751", - "reference": "b4729341e469d0f174f3cade85718ff5bf8dd751", + "url": "https://api.github.com/repos/Codeception/Codeception/zipball/86770e89d266557c20dd0b1de5390e706f4770c1", + "reference": "86770e89d266557c20dd0b1de5390e706f4770c1", "shasum": "" }, "require": { @@ -1456,7 +1457,7 @@ "symfony/browser-kit": ">=2.7 <4.0", "symfony/console": ">=2.7 <4.0", "symfony/css-selector": ">=2.7 <4.0", - "symfony/dom-crawler": ">=2.7 <4.0", + "symfony/dom-crawler": ">=2.7.5 <4.0", "symfony/event-dispatcher": ">=2.7 <4.0", "symfony/finder": ">=2.7 <4.0", "symfony/yaml": ">=2.7 <4.0" @@ -1472,7 +1473,8 @@ "pda/pheanstalk": "~3.0", "php-amqplib/php-amqplib": "~2.4", "predis/predis": "^1.0", - "squizlabs/php_codesniffer": "~2.0" + "squizlabs/php_codesniffer": "~2.0", + "vlucas/phpdotenv": "^2.4.0" }, "suggest": { "codeception/specify": "BDD-style code blocks", @@ -1516,7 +1518,7 @@ "functional testing", "unit testing" ], - "time": "2016-09-29 01:29:59" + "time": "2016-12-05 04:12:24" }, { "name": "doctrine/instantiator", @@ -1731,16 +1733,16 @@ }, { "name": "guzzlehttp/promises", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579" + "reference": "2693c101803ca78b27972d84081d027fca790a1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/c10d860e2a9595f8883527fa0021c7da9e65f579", - "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579", + "url": "https://api.github.com/repos/guzzle/promises/zipball/2693c101803ca78b27972d84081d027fca790a1e", + "reference": "2693c101803ca78b27972d84081d027fca790a1e", "shasum": "" }, "require": { @@ -1778,7 +1780,7 @@ "keywords": [ "promise" ], - "time": "2016-05-18 16:56:05" + "time": "2016-11-18 17:47:58" }, { "name": "guzzlehttp/psr7", @@ -1939,16 +1941,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "0.2", + "version": "0.2.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443" + "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443", - "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", + "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", "shasum": "" }, "require": { @@ -1982,20 +1984,20 @@ "email": "me@mikevanriel.com" } ], - "time": "2016-06-10 07:14:17" + "time": "2016-11-25 06:54:22" }, { "name": "phpspec/prophecy", - "version": "v1.6.1", + "version": "v1.6.2", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "58a8137754bc24b25740d4281399a4a3596058e0" + "reference": "6c52c2722f8460122f96f86346600e1077ce22cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0", - "reference": "58a8137754bc24b25740d4281399a4a3596058e0", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb", + "reference": "6c52c2722f8460122f96f86346600e1077ce22cb", "shasum": "" }, "require": { @@ -2003,10 +2005,11 @@ "php": "^5.3|^7.0", "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", "sebastian/comparator": "^1.1", - "sebastian/recursion-context": "^1.0" + "sebastian/recursion-context": "^1.0|^2.0" }, "require-dev": { - "phpspec/phpspec": "^2.0" + "phpspec/phpspec": "^2.0", + "phpunit/phpunit": "^4.8 || ^5.6.5" }, "type": "library", "extra": { @@ -2044,7 +2047,7 @@ "spy", "stub" ], - "time": "2016-06-07 08:13:47" + "time": "2016-11-21 14:58:47" }, { "name": "phpunit/php-code-coverage", @@ -2110,16 +2113,16 @@ }, { "name": "phpunit/php-file-iterator", - "version": "1.4.1", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", "shasum": "" }, "require": { @@ -2153,7 +2156,7 @@ "filesystem", "iterator" ], - "time": "2015-06-21 13:08:43" + "time": "2016-10-03 07:40:28" }, { "name": "phpunit/php-text-template", @@ -2242,16 +2245,16 @@ }, { "name": "phpunit/php-token-stream", - "version": "1.4.8", + "version": "1.4.9", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" + "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b", + "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b", "shasum": "" }, "require": { @@ -2287,20 +2290,20 @@ "keywords": [ "tokenizer" ], - "time": "2015-09-15 10:49:45" + "time": "2016-11-15 14:06:22" }, { "name": "phpunit/phpunit", - "version": "4.8.27", + "version": "4.8.30", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "c062dddcb68e44b563f66ee319ddae2b5a322a90" + "reference": "a534e04d0bd39c557c2881c341efd06fa6f1292a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c062dddcb68e44b563f66ee319ddae2b5a322a90", - "reference": "c062dddcb68e44b563f66ee319ddae2b5a322a90", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a534e04d0bd39c557c2881c341efd06fa6f1292a", + "reference": "a534e04d0bd39c557c2881c341efd06fa6f1292a", "shasum": "" }, "require": { @@ -2316,7 +2319,7 @@ "phpunit/php-text-template": "~1.2", "phpunit/php-timer": "^1.0.6", "phpunit/phpunit-mock-objects": "~2.3", - "sebastian/comparator": "~1.1", + "sebastian/comparator": "~1.2.2", "sebastian/diff": "~1.2", "sebastian/environment": "~1.3", "sebastian/exporter": "~1.2", @@ -2359,7 +2362,7 @@ "testing", "xunit" ], - "time": "2016-07-21 06:48:14" + "time": "2016-12-01 17:05:48" }, { "name": "phpunit/phpunit-mock-objects", @@ -2469,22 +2472,22 @@ }, { "name": "sebastian/comparator", - "version": "1.2.0", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" + "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/6a1ed12e8b2409076ab22e3897126211ff8b1f7f", + "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f", "shasum": "" }, "require": { "php": ">=5.3.3", "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2" + "sebastian/exporter": "~1.2 || ~2.0" }, "require-dev": { "phpunit/phpunit": "~4.4" @@ -2529,7 +2532,7 @@ "compare", "equality" ], - "time": "2015-07-26 15:48:44" + "time": "2016-11-19 09:18:40" }, { "name": "sebastian/diff", @@ -2841,16 +2844,16 @@ }, { "name": "symfony/browser-kit", - "version": "v3.1.5", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "901319a31c9b3cee7857b4aeeb81b5d64dfa34fc" + "reference": "34348c2691ce6254e8e008026f4c5e72c22bb318" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/901319a31c9b3cee7857b4aeeb81b5d64dfa34fc", - "reference": "901319a31c9b3cee7857b4aeeb81b5d64dfa34fc", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/34348c2691ce6254e8e008026f4c5e72c22bb318", + "reference": "34348c2691ce6254e8e008026f4c5e72c22bb318", "shasum": "" }, "require": { @@ -2867,7 +2870,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2894,20 +2897,20 @@ ], "description": "Symfony BrowserKit Component", "homepage": "https://symfony.com", - "time": "2016-09-06 11:02:40" + "time": "2016-10-13 13:35:11" }, { "name": "symfony/css-selector", - "version": "v3.1.5", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "ca809c64072e0fe61c1c7fb3c76cdc32265042ac" + "reference": "e1241f275814827c411d922ba8e64cf2a00b2994" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/ca809c64072e0fe61c1c7fb3c76cdc32265042ac", - "reference": "ca809c64072e0fe61c1c7fb3c76cdc32265042ac", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/e1241f275814827c411d922ba8e64cf2a00b2994", + "reference": "e1241f275814827c411d922ba8e64cf2a00b2994", "shasum": "" }, "require": { @@ -2916,7 +2919,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2947,20 +2950,20 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2016-09-06 11:02:40" + "time": "2016-11-03 08:11:03" }, { "name": "symfony/dom-crawler", - "version": "v3.1.5", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "bb7395e8b1db3654de82b9f35d019958276de4d7" + "reference": "c6b6111f5aae7c58698cdc10220785627ac44a2c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/bb7395e8b1db3654de82b9f35d019958276de4d7", - "reference": "bb7395e8b1db3654de82b9f35d019958276de4d7", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/c6b6111f5aae7c58698cdc10220785627ac44a2c", + "reference": "c6b6111f5aae7c58698cdc10220785627ac44a2c", "shasum": "" }, "require": { @@ -2976,7 +2979,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -3003,20 +3006,20 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "time": "2016-08-05 08:37:39" + "time": "2016-11-25 12:32:42" }, { "name": "symfony/finder", - "version": "v3.1.5", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "205b5ffbb518a98ba2ae60a52656c4a31ab00c6f" + "reference": "4263e35a1e342a0f195c9349c0dee38148f8a14f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/205b5ffbb518a98ba2ae60a52656c4a31ab00c6f", - "reference": "205b5ffbb518a98ba2ae60a52656c4a31ab00c6f", + "url": "https://api.github.com/repos/symfony/finder/zipball/4263e35a1e342a0f195c9349c0dee38148f8a14f", + "reference": "4263e35a1e342a0f195c9349c0dee38148f8a14f", "shasum": "" }, "require": { @@ -3025,7 +3028,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -3052,24 +3055,24 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2016-09-28 00:11:12" + "time": "2016-11-03 08:11:03" }, { "name": "webmozart/assert", - "version": "1.1.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "bb2d123231c095735130cc8f6d31385a44c7b308" + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/bb2d123231c095735130cc8f6d31385a44c7b308", - "reference": "bb2d123231c095735130cc8f6d31385a44c7b308", + "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", "shasum": "" }, "require": { - "php": "^5.3.3|^7.0" + "php": "^5.3.3 || ^7.0" }, "require-dev": { "phpunit/phpunit": "^4.6", @@ -3078,7 +3081,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "1.3-dev" } }, "autoload": { @@ -3102,7 +3105,7 @@ "check", "validate" ], - "time": "2016-08-09 15:02:57" + "time": "2016-11-23 20:04:58" } ], "aliases": [ From 906c090bd4ccdf712c834878e6056223fde44eac Mon Sep 17 00:00:00 2001 From: Djamil Legato Date: Wed, 7 Dec 2016 12:56:00 -0800 Subject: [PATCH 44/56] Fixed issue with redirect of a page getting moved to a different location --- CHANGELOG.md | 1 + system/src/Grav/Common/Page/Page.php | 2 ++ 2 files changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f52621510..f4a7da838 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ * Fix page collections problem with `@page.modular` [#1178](https://github.com/getgrav/grav/pull/1178) * Fix issue with using a multiple taxonomy filter of which one had no results, thanks to @hughbris [#1184](https://github.com/getgrav/grav/issues/1184) * Fix saving permissions in group + * Fixed issue with redirect of a page getting moved to a different location # v1.1.9-rc.2 ## 11/26/2016 diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index a8703b9e7..fb683cae5 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -902,6 +902,8 @@ class Page $this->route(Grav::instance()['pages']->root()->route() . '/' . $this->slug()); } + $this->raw_route = null; + return $this; } From 7b2716dab1dff8bfb557289d6064ad5d798ac9cd Mon Sep 17 00:00:00 2001 From: Aaron Dalton Date: Wed, 7 Dec 2016 14:16:00 -0700 Subject: [PATCH 45/56] Added warning to command when new Grav version is available (#1194) --- system/src/Grav/Console/Gpm/UpdateCommand.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/system/src/Grav/Console/Gpm/UpdateCommand.php b/system/src/Grav/Console/Gpm/UpdateCommand.php index 6428e90a0..a0227fc2b 100644 --- a/system/src/Grav/Console/Gpm/UpdateCommand.php +++ b/system/src/Grav/Console/Gpm/UpdateCommand.php @@ -11,6 +11,7 @@ namespace Grav\Console\Gpm; use Grav\Common\GPM\GPM; use Grav\Common\GPM\Installer; use Grav\Console\ConsoleCommand; +use Grav\Common\GPM\Upgrader; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; @@ -109,6 +110,22 @@ class UpdateCommand extends ConsoleCommand */ protected function serve() { + $this->upgrader = new Upgrader($this->input->getOption('force')); + $local = $this->upgrader->getLocalVersion(); + $remote = $this->upgrader->getRemoteVersion(); + if ($local !== $remote) { + $this->output->writeln("WARNING: A new version of Grav is available. You should update Grav before updating plugins and themes. If you continue without updating Grav, some plugins or themes may stop working."); + $this->output->writeln(""); + $questionHelper = $this->getHelper('question'); + $question = new ConfirmationQuestion("Continue with the update process? [Y|n] ", true); + $answer = $questionHelper->ask($this->input, $this->output, $question); + + if (!$answer) { + $this->output->writeln("Update aborted. Exiting..."); + exit; + } + } + $this->gpm = new GPM($this->input->getOption('force')); $this->all_yes = $this->input->getOption('all-yes'); From 74c005d39c19ac81aeaf0103799237229384288c Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 7 Dec 2016 14:48:00 -0700 Subject: [PATCH 46/56] Added new `onBeforeCacheClear` event --- CHANGELOG.md | 2 ++ system/src/Grav/Common/Cache.php | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4a7da838..f018b458d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,11 +8,13 @@ * New retina Media image derivatives array support (`![](image.jpg?derivatives=[640,1024,1440])`) [#1147](https://github.com/getgrav/grav/pull/1147) * Added stream support for images (`![Sepia Image](image://image.jpg?sepia)`) * Added stream support for links (`[Download PDF](user://data/pdf/my.pdf)`) + * Added new `onBeforeCacheClear` event to add custom paths to cache clearing process 1. [](#improved) * Added alias `selfupdate` to the `self-upgrade` `bin/gpm` CLI command * Synced `webserver-configs/htaccess.txt` with `.htaccess` * Use permissions field in group details. * Updated vendor libraries + * Added a warning on GPM update to update Grav first if needed [#1194](https://github.com/getgrav/grav/pull/1194) 1. [](#bugfix) * Fix page collections problem with `@page.modular` [#1178](https://github.com/getgrav/grav/pull/1178) * Fix issue with using a multiple taxonomy filter of which one had no results, thanks to @hughbris [#1184](https://github.com/getgrav/grav/issues/1184) diff --git a/system/src/Grav/Common/Cache.php b/system/src/Grav/Common/Cache.php index 048260527..208e3d91e 100644 --- a/system/src/Grav/Common/Cache.php +++ b/system/src/Grav/Common/Cache.php @@ -11,7 +11,7 @@ namespace Grav\Common; use \Doctrine\Common\Cache as DoctrineCache; use Grav\Common\Config\Config; use Grav\Common\Filesystem\Folder; -use Grav\Common\Grav; +use RocketTheme\Toolbox\Event\Event; /** * The GravCache object is used throughout Grav to store and retrieve cached data. @@ -356,6 +356,8 @@ class Cache extends Getters $remove_paths = self::$standard_remove; } + // Clearing cache event to add paths to clear + Grav::instance()->fireEvent('onBeforeCacheClear', new Event(['paths' => &$remove_paths])); foreach ($remove_paths as $stream) { From 380157f9cc692943a47d6aef2cfa902c63f3136f Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 7 Dec 2016 16:05:12 -0700 Subject: [PATCH 47/56] prepare for release --- CHANGELOG.md | 4 ++-- system/defines.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f018b458d..f21089cf5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ -# v1.1.9-rc.X -## 11/xx/2016 +# v1.1.9-rc.3 +## 12/07/2016 1. [](#new) * Add `ignore_empty` property to be used on array fields, if positive only save options with a value diff --git a/system/defines.php b/system/defines.php index b3d0a24f2..23bc533ce 100644 --- a/system/defines.php +++ b/system/defines.php @@ -8,7 +8,7 @@ // Some standard defines define('GRAV', true); -define('GRAV_VERSION', '1.1.9-rc.2'); +define('GRAV_VERSION', '1.1.9-rc.3'); define('GRAV_TESTING', true); define('DS', '/'); define('GRAV_PHP_MIN', '5.5.9'); From 625f3d3a345e1358113f7587a1b919da70271f3d Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 8 Dec 2016 12:57:18 +0200 Subject: [PATCH 48/56] Better error handling in cache clear Added new parameter `remove` for `onBeforeCacheClear` event --- CHANGELOG.md | 8 +++++++ system/src/Grav/Common/Cache.php | 38 ++++++++++++++++---------------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f21089cf5..09a4a6a0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# v1.1.9-rc.4 +## XX/XX/2016 + +1. [](#improved) + * Better error handling in cache clear +1. [](#bugfix) + * Added new parameter `remove` for `onBeforeCacheClear` event + # v1.1.9-rc.3 ## 12/07/2016 diff --git a/system/src/Grav/Common/Cache.php b/system/src/Grav/Common/Cache.php index 208e3d91e..5891d75ed 100644 --- a/system/src/Grav/Common/Cache.php +++ b/system/src/Grav/Common/Cache.php @@ -357,37 +357,37 @@ class Cache extends Getters } // Clearing cache event to add paths to clear - Grav::instance()->fireEvent('onBeforeCacheClear', new Event(['paths' => &$remove_paths])); + Grav::instance()->fireEvent('onBeforeCacheClear', new Event(['remove' => $remove, 'paths' => &$remove_paths])); foreach ($remove_paths as $stream) { // Convert stream to a real path try { $path = $locator->findResource($stream, true, true); - } catch (\Exception $e) { - // stream not found.. - continue; - } - $anything = false; - $files = glob($path . '/*'); + $anything = false; + $files = glob($path . '/*'); - if (is_array($files)) { - foreach ($files as $file) { - if (is_file($file)) { - if (@unlink($file)) { - $anything = true; - } - } elseif (is_dir($file)) { - if (Folder::delete($file)) { - $anything = true; + if (is_array($files)) { + foreach ($files as $file) { + if (is_file($file)) { + if (@unlink($file)) { + $anything = true; + } + } elseif (is_dir($file)) { + if (Folder::delete($file)) { + $anything = true; + } } } } - } - if ($anything) { - $output[] = 'Cleared: ' . $path . '/*'; + if ($anything) { + $output[] = 'Cleared: ' . $path . '/*'; + } + } catch (\Exception $e) { + // stream not found or another error while deleting files. + $output[] = 'ERROR: ' . $e->getMessage(); } } From 833cd497bb79532e6560edaa6ec9e21c2c75c564 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 8 Dec 2016 12:57:40 +0200 Subject: [PATCH 49/56] YAML syntax fixes --- CHANGELOG.md | 1 + system/blueprints/pages/default.yaml | 2 +- system/blueprints/pages/external.yaml | 2 +- system/blueprints/pages/modular_new.yaml | 2 +- system/blueprints/pages/modular_raw.yaml | 2 +- system/blueprints/pages/move.yaml | 2 +- system/blueprints/pages/new.yaml | 2 +- system/blueprints/pages/new_folder.yaml | 2 +- system/blueprints/pages/raw.yaml | 2 +- system/src/Grav/Common/File/CompiledFile.php | 91 +++++++++++--------- 10 files changed, 57 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09a4a6a0c..97a9bc9bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Better error handling in cache clear 1. [](#bugfix) * Added new parameter `remove` for `onBeforeCacheClear` event + * YAML syntax fixes # v1.1.9-rc.3 ## 12/07/2016 diff --git a/system/blueprints/pages/default.yaml b/system/blueprints/pages/default.yaml index f54468082..f38957ccf 100644 --- a/system/blueprints/pages/default.yaml +++ b/system/blueprints/pages/default.yaml @@ -2,7 +2,7 @@ title: PLUGIN_ADMIN.DEFAULT rules: slug: - pattern: "[a-zа-я][a-zа-я0-9_\-]+" + pattern: '[a-zа-я][a-zа-я0-9_\-]+' min: 2 max: 80 diff --git a/system/blueprints/pages/external.yaml b/system/blueprints/pages/external.yaml index 568e2f61f..9f95d3e0c 100644 --- a/system/blueprints/pages/external.yaml +++ b/system/blueprints/pages/external.yaml @@ -5,7 +5,7 @@ title: PLUGIN_ADMIN:EXTERNAL rules: slug: - pattern: "[a-zа-я][a-zа-я0-9_\-]+" + pattern: '[a-zа-я][a-zа-я0-9_\-]+' min: 2 max: 80 diff --git a/system/blueprints/pages/modular_new.yaml b/system/blueprints/pages/modular_new.yaml index 8c19d8960..273292363 100644 --- a/system/blueprints/pages/modular_new.yaml +++ b/system/blueprints/pages/modular_new.yaml @@ -1,6 +1,6 @@ rules: slug: - pattern: "[a-z][a-z0-9_\-]+" + pattern: '[a-z][a-z0-9_\-]+' min: 2 max: 80 diff --git a/system/blueprints/pages/modular_raw.yaml b/system/blueprints/pages/modular_raw.yaml index 8e4647989..ed25992a3 100644 --- a/system/blueprints/pages/modular_raw.yaml +++ b/system/blueprints/pages/modular_raw.yaml @@ -1,6 +1,6 @@ rules: slug: - pattern: "[a-z][a-z0-9_\-]+" + pattern: '[a-z][a-z0-9_\-]+' min: 2 max: 80 diff --git a/system/blueprints/pages/move.yaml b/system/blueprints/pages/move.yaml index 518f21828..ed3c46312 100644 --- a/system/blueprints/pages/move.yaml +++ b/system/blueprints/pages/move.yaml @@ -1,6 +1,6 @@ rules: slug: - pattern: "[a-z][a-z0-9_\-]+" + pattern: '[a-z][a-z0-9_\-]+' min: 2 max: 80 diff --git a/system/blueprints/pages/new.yaml b/system/blueprints/pages/new.yaml index 71ca78a81..49b85b729 100644 --- a/system/blueprints/pages/new.yaml +++ b/system/blueprints/pages/new.yaml @@ -1,6 +1,6 @@ rules: slug: - pattern: "[a-z][a-z0-9_\-]+" + pattern: '[a-z][a-z0-9_\-]+' min: 2 max: 80 diff --git a/system/blueprints/pages/new_folder.yaml b/system/blueprints/pages/new_folder.yaml index ddf47a97d..16024b749 100644 --- a/system/blueprints/pages/new_folder.yaml +++ b/system/blueprints/pages/new_folder.yaml @@ -1,6 +1,6 @@ rules: slug: - pattern: "[a-z][a-z0-9_\-]+" + pattern: '[a-z][a-z0-9_\-]+' min: 2 max: 80 diff --git a/system/blueprints/pages/raw.yaml b/system/blueprints/pages/raw.yaml index 3b582eb14..60870eaf7 100644 --- a/system/blueprints/pages/raw.yaml +++ b/system/blueprints/pages/raw.yaml @@ -1,6 +1,6 @@ rules: slug: - pattern: "[a-z][a-z0-9_\-]+" + pattern: '[a-z][a-z0-9_\-]+' min: 2 max: 80 diff --git a/system/src/Grav/Common/File/CompiledFile.php b/system/src/Grav/Common/File/CompiledFile.php index fcb0de4d2..16e67f4ea 100644 --- a/system/src/Grav/Common/File/CompiledFile.php +++ b/system/src/Grav/Common/File/CompiledFile.php @@ -23,58 +23,63 @@ trait CompiledFile // Set some options $this->settings(['native' => true, 'compat' => true]); - // If nothing has been loaded, attempt to get pre-compiled version of the file first. - if ($var === null && $this->raw === null && $this->content === null) { - $key = md5($this->filename); - $file = PhpFile::instance(CACHE_DIR . DS . "compiled/files/{$key}{$this->extension}.php"); + try { + // If nothing has been loaded, attempt to get pre-compiled version of the file first. + if ($var === null && $this->raw === null && $this->content === null) { + $key = md5($this->filename); + $file = PhpFile::instance(CACHE_DIR . DS . "compiled/files/{$key}{$this->extension}.php"); - $modified = $this->modified(); + $modified = $this->modified(); - if (!$modified) { - return $this->decode($this->raw()); - } - - $class = get_class($this); - - $cache = $file->exists() ? $file->content() : null; - - // Load real file if cache isn't up to date (or is invalid). - if ( - !isset($cache['@class']) - || $cache['@class'] != $class - || $cache['modified'] != $modified - || $cache['filename'] != $this->filename - ) { - // Attempt to lock the file for writing. - try { - $file->lock(false); - } catch (\Exception $e) { - // Another process has locked the file; we will check this in a bit. + if (!$modified) { + return $this->decode($this->raw()); } - // Decode RAW file into compiled array. - $data = (array) $this->decode($this->raw()); - $cache = [ - '@class' => $class, - 'filename' => $this->filename, - 'modified' => $modified, - 'data' => $data - ]; + $class = get_class($this); - // If compiled file wasn't already locked by another process, save it. - if ($file->locked() !== false) { - $file->save($cache); - $file->unlock(); + $cache = $file->exists() ? $file->content() : null; - // Compile cached file into bytecode cache - if (function_exists('opcache_invalidate')) { - opcache_invalidate($file->filename(), true); + // Load real file if cache isn't up to date (or is invalid). + if ( + !isset($cache['@class']) + || $cache['@class'] != $class + || $cache['modified'] != $modified + || $cache['filename'] != $this->filename + ) { + // Attempt to lock the file for writing. + try { + $file->lock(false); + } catch (\Exception $e) { + // Another process has locked the file; we will check this in a bit. + } + + // Decode RAW file into compiled array. + $data = (array)$this->decode($this->raw()); + $cache = [ + '@class' => $class, + 'filename' => $this->filename, + 'modified' => $modified, + 'data' => $data + ]; + + // If compiled file wasn't already locked by another process, save it. + if ($file->locked() !== false) { + $file->save($cache); + $file->unlock(); + + // Compile cached file into bytecode cache + if (function_exists('opcache_invalidate')) { + opcache_invalidate($file->filename(), true); + } } } - } - $file->free(); + $file->free(); - $this->content = $cache['data']; + $this->content = $cache['data']; + } + + } catch (\Exception $e) { + throw new \RuntimeException(sprintf('Failed to read %s: %s', basename($this->filename), $e->getMessage()), 500, $e); } return parent::content($var); From 3c6df48b8b3d55de5407274982615b2c4ef118b4 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 8 Dec 2016 15:49:45 -0700 Subject: [PATCH 50/56] Insight fixes --- system/src/Grav/Common/Helpers/Base32.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/system/src/Grav/Common/Helpers/Base32.php b/system/src/Grav/Common/Helpers/Base32.php index db346e99d..eebb95b5d 100644 --- a/system/src/Grav/Common/Helpers/Base32.php +++ b/system/src/Grav/Common/Helpers/Base32.php @@ -33,11 +33,12 @@ class Base32 { public static function encode( $bytes ) { $i = 0; $index = 0; $digit = 0; $base32 = ""; - while( $i < strlen($bytes) ) { + $bytes_len = strlen($bytes); + while( $i < $bytes_len ) { $currByte = ord($bytes{$i}); /* Is the current digit going to span a byte boundary? */ if( $index > 3 ) { - if( ($i + 1) < strlen($bytes) ) { + if( ($i + 1) < $bytes_len ) { $nextByte = ord($bytes{$i+1}); } else { $nextByte = 0; @@ -65,10 +66,11 @@ class Base32 { */ public static function decode( $base32 ) { $bytes = array(); - for( $i=strlen($base32)*5/8-1; $i>=0; --$i ) { + $base32_len = strlen($base32); + for( $i=$base32_len*5/8-1; $i>=0; --$i ) { $bytes[] = 0; } - for( $i = 0, $index = 0, $offset = 0; $i < strlen($base32); $i++ ) { + for( $i = 0, $index = 0, $offset = 0; $i < $base32_len; $i++ ) { $lookup = ord($base32{$i}) - ord('0'); /* Skip chars outside the lookup table */ if( $lookup < 0 || $lookup >= count(self::$base32Lookup) ) { From 7ed078ce318d32cf40dfd6ccdfe098932554e250 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 8 Dec 2016 16:10:44 -0700 Subject: [PATCH 51/56] unused 'use' statements --- system/src/Grav/Common/Page/Media.php | 3 +-- system/src/Grav/Common/Page/Medium/AbstractMedia.php | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/system/src/Grav/Common/Page/Media.php b/system/src/Grav/Common/Page/Media.php index 7d1522f9e..eb12eeb1c 100644 --- a/system/src/Grav/Common/Page/Media.php +++ b/system/src/Grav/Common/Page/Media.php @@ -11,14 +11,13 @@ namespace Grav\Common\Page; use Grav\Common\Page\Medium\AbstractMedia; use Grav\Common\Page\Medium\GlobalMedia; use Grav\Common\Page\Medium\MediumFactory; -use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; class Media extends AbstractMedia { protected static $global; protected $path; - + /** * @param $path */ diff --git a/system/src/Grav/Common/Page/Medium/AbstractMedia.php b/system/src/Grav/Common/Page/Medium/AbstractMedia.php index 8d86ea027..d6d1dfe20 100644 --- a/system/src/Grav/Common/Page/Medium/AbstractMedia.php +++ b/system/src/Grav/Common/Page/Medium/AbstractMedia.php @@ -9,7 +9,6 @@ namespace Grav\Common\Page\Medium; use Grav\Common\Getters; -use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; abstract class AbstractMedia extends Getters { From d3b654bdb06d527124308ffab6a627580c6426db Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Sat, 10 Dec 2016 18:34:13 +0100 Subject: [PATCH 52/56] Added checks before accessing admin reference during `Page::blueprints()` call --- CHANGELOG.md | 3 ++- system/src/Grav/Common/Page/Pages.php | 27 ++++++++++++++++----------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97a9bc9bc..740c5ece1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,8 @@ 1. [](#bugfix) * Added new parameter `remove` for `onBeforeCacheClear` event * YAML syntax fixes - + * Added checks before accessing admin reference during `Page::blueprints()` call. Allows to access `page.blueprints` from Twig in the frontend + # v1.1.9-rc.3 ## 12/07/2016 diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 93656dcbb..2771d131d 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -571,17 +571,21 @@ class Pages */ public static function pageTypes() { - /** @var Admin $admin */ - $admin = Grav::instance()['admin']; + if (isset(Grav::instance()['admin'])) { + /** @var Admin $admin */ + $admin = Grav::instance()['admin']; - /** @var Page $page */ - $page = $admin->getPage($admin->route); + /** @var Page $page */ + $page = $admin->getPage($admin->route); - if ($page && $page->modular()) { - return static::modularTypes(); + if ($page && $page->modular()) { + return static::modularTypes(); + } + + return static::types(); } - return static::types(); + return []; } /** @@ -654,11 +658,12 @@ class Pages $parents = $pages->getList(null, 0, $rawRoutes); - /** @var Admin $admin */ - $admin = $grav['admin']; + if (isset($grav['admin'])) { + // Remove current route from parents + + /** @var Admin $admin */ + $admin = $grav['admin']; - // Remove current route from parents - if (isset($admin)) { $page = $admin->getPage($admin->route); $page_route = $page->route(); if (isset($parents[$page_route])) { From 156f645576a3df15eb985c127e082766b079a0d2 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 11 Dec 2016 18:22:54 -0700 Subject: [PATCH 53/56] Set Grav to be in 'testing' while in RC state --- system/config/system.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/config/system.yaml b/system/config/system.yaml index 54e4c4781..f5c475208 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -131,7 +131,7 @@ session: path: gpm: - releases: stable # Set to either 'stable' or 'testing' + releases: testing # Set to either 'stable' or 'testing' proxy_url: # Configure a manual proxy URL for GPM (eg 127.0.0.1:3128) method: 'auto' # Either 'curl', 'fopen' or 'auto'. 'auto' will try fopen first and if not available cURL verify_peer: true # Sometimes on some systems (Windows most commonly) GPM is unable to connect because the SSL certificate cannot be verified. Disabling this setting might help. From 9db04abd1cb9db74ed36420bf88f2254c5ceff0c Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Mon, 12 Dec 2016 09:31:33 +0200 Subject: [PATCH 54/56] Add support for calling Media object as function to get medium by filename --- CHANGELOG.md | 1 + system/src/Grav/Common/Page/Medium/AbstractMedia.php | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 740c5ece1..79e721676 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 1. [](#improved) * Better error handling in cache clear + * Add support for calling Media object as function to get medium by filename 1. [](#bugfix) * Added new parameter `remove` for `onBeforeCacheClear` event * YAML syntax fixes diff --git a/system/src/Grav/Common/Page/Medium/AbstractMedia.php b/system/src/Grav/Common/Page/Medium/AbstractMedia.php index d6d1dfe20..e3ad3e3cb 100644 --- a/system/src/Grav/Common/Page/Medium/AbstractMedia.php +++ b/system/src/Grav/Common/Page/Medium/AbstractMedia.php @@ -31,6 +31,17 @@ abstract class AbstractMedia extends Getters return $this->offsetGet($filename); } + /** + * Call object as function to get medium by filename. + * + * @param string $filename + * @return mixed + */ + public function __invoke($filename) + { + return $this->offsetGet($filename); + } + /** * Get a list of all media. * From 85bf215dc6c2cc929a22c71aaa2a30576fe64977 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Mon, 12 Dec 2016 09:37:02 +0200 Subject: [PATCH 55/56] Changelog update --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79e721676..d33f546cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,10 @@ 1. [](#improved) * Better error handling in cache clear + * YAML syntax fixes for the future compatibility + * Added new parameter `remove` for `onBeforeCacheClear` event * Add support for calling Media object as function to get medium by filename 1. [](#bugfix) - * Added new parameter `remove` for `onBeforeCacheClear` event - * YAML syntax fixes * Added checks before accessing admin reference during `Page::blueprints()` call. Allows to access `page.blueprints` from Twig in the frontend # v1.1.9-rc.3 From d23f8295596d1851d75e43b767c0907f1d789544 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 13 Dec 2016 13:05:57 -0700 Subject: [PATCH 56/56] prepare for release --- CHANGELOG.md | 6 ++++-- system/config/system.yaml | 2 +- system/defines.php | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d33f546cf..bdea66039 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ -# v1.1.9-rc.4 -## XX/XX/2016 +# v1.1.9 +## 12/13/2016 +1. [](#new) + * RC released as stable 1. [](#improved) * Better error handling in cache clear * YAML syntax fixes for the future compatibility diff --git a/system/config/system.yaml b/system/config/system.yaml index f5c475208..54e4c4781 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -131,7 +131,7 @@ session: path: gpm: - releases: testing # Set to either 'stable' or 'testing' + releases: stable # Set to either 'stable' or 'testing' proxy_url: # Configure a manual proxy URL for GPM (eg 127.0.0.1:3128) method: 'auto' # Either 'curl', 'fopen' or 'auto'. 'auto' will try fopen first and if not available cURL verify_peer: true # Sometimes on some systems (Windows most commonly) GPM is unable to connect because the SSL certificate cannot be verified. Disabling this setting might help. diff --git a/system/defines.php b/system/defines.php index 23bc533ce..956dd1b1d 100644 --- a/system/defines.php +++ b/system/defines.php @@ -8,8 +8,8 @@ // Some standard defines define('GRAV', true); -define('GRAV_VERSION', '1.1.9-rc.3'); -define('GRAV_TESTING', true); +define('GRAV_VERSION', '1.1.9'); +define('GRAV_TESTING', false); define('DS', '/'); define('GRAV_PHP_MIN', '5.5.9');