diff --git a/.gitignore b/.gitignore index 5842fcdd50..1349073ac4 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ user/plugins/* user/themes/* !user/themes/.* user/localhost/config/security.yaml +user/config/security.yaml # OS Generated .DS_Store* diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b35b90195..426449e002 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ +# v1.1.13 +## 01/17/2017 + +1. [](#new) + * Added new `never_cache_twig` page option in `system.yaml` and frontmatter. Allows dynamic Twig logic in regular and modular Twig templates [#1244](https://github.com/getgrav/grav/pull/1244) +1. [](#improved) + * Several improvements to aid theme development [#232](https://github.com/getgrav/grav/pull/1232) + * Added `hash` cache check option and made dropdown more descriptive [Admin #923](https://github.com/getgrav/grav-plugin-admin/issues/923) +1. [](#bugfix) + * Fixed cross volume file system operations [#635](https://github.com/getgrav/grav/issues/635) + * Fix issue with pages folders validation not accepting uppercase letters + * Fix renaming the folder name if the page, in the default language, had a custom slug set in its header + * Fixed issue with `Content-Encoding: none`. It should really be `Content-Encoding: identity` instead + * Fixed broken `hash` method on page modifications detection + * Fixed issue with multi-lang pages not caching independently without unique `.md` file [#1211](https://github.com/getgrav/grav/issues/1211) + * Fixed all `$_GET` parameters missing in Nginx (please update your nginx.conf) [#1245](https://github.com/getgrav/grav/issues/1245) + * Fixed issue in trying to process broken symlink [#1254](https://github.com/getgrav/grav/issues/1254) + # v1.1.12 ## 12/26/2016 @@ -23,8 +41,8 @@ * Fixed case where extracting a package would cause an error during rename * Fix issue with using `Yaml::parse` direcly on a filename, now deprecated * Add pattern for frontend validation of folder slugs [#891](https://github.com/getgrav/grav-plugin-admin/issues/891) - * Fix issue with Inflector when translation is disabled [https://github.com/getgrav/grav-plugin-simplesearch/issues/87](https://github.com/getgrav/grav-plugin-simplesearch/issues/87) - * Explicitly expose `array_unique` Twig filter [https://github.com/getgrav/grav-plugin-admin/issues/897](https://github.com/getgrav/grav-plugin-admin/issues/897) + * Fix issue with Inflector when translation is disabled [SimpleSearch #87](https://github.com/getgrav/grav-plugin-simplesearch/issues/87) + * Explicitly expose `array_unique` Twig filter [Admin #897](https://github.com/getgrav/grav-plugin-admin/issues/897) # v1.1.9 ## 12/13/2016 @@ -72,7 +90,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) + * Update class namespace for Admin class [Admin #874](https://github.com/getgrav/grav-plugin-admin/issues/874) # v1.1.9-rc.1 ## 11/09/2016 @@ -135,7 +153,7 @@ 1. [](#bugfix) * Fixed missing `progress` method in the DirectInstall Command * `Response` class now handles better unsuccessful requests such as 404 and 401 - * Fixed saving of `external` page types [admin #789](https://github.com/getgrav/grav-plugin-admin/issues/789) + * Fixed saving of `external` page types [Admin #789](https://github.com/getgrav/grav-plugin-admin/issues/789) * Fixed issue deleting parent folder of folder with `param_sep` in the folder name [admin #796](https://github.com/getgrav/grav-plugin-admin/issues/796) * Fixed an issue with streams in `bin/plugin` * Fixed `jpeg` file format support in Media @@ -940,7 +958,7 @@ * Added new `onImageMediumSaved()` event (useful for post-image processing) * Added `Vary: Accept-Encoding` option 2. [](#improved) - * Multilang-safe delimeter position + * Multilang-safe delimiter position * Refactored Twig classes and added optional umask setting * Removed `pageinit()` timing * `Page->routable()` now takes `published()` state into account diff --git a/composer.lock b/composer.lock index d00fccb247..5c0f30b962 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,6 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "d64399c5d93a4fb78a3e07a6d5483e2c", "content-hash": "4e5b9333d3ac2de823c68c9c8e0f2017", "packages": [ { @@ -49,7 +48,7 @@ } ], "description": "Composer package for DOMWordsIterator and DOMLettersIterator", - "time": "2015-11-04 17:33:14" + "time": "2015-11-04T17:33:14+00:00" }, { "name": "doctrine/cache", @@ -119,20 +118,20 @@ "cache", "caching" ], - "time": "2016-10-29 11:16:17" + "time": "2016-10-29T11:16:17+00:00" }, { "name": "donatj/phpuseragentparser", - "version": "v0.5.2", + "version": "v0.5.3", "source": { "type": "git", "url": "https://github.com/donatj/PhpUserAgent.git", - "reference": "d8e7b6a0c83a6e4aa9098360a99c6eeb763c004a" + "reference": "936f092e819bda25fcac120566f64139ff726432" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/donatj/PhpUserAgent/zipball/d8e7b6a0c83a6e4aa9098360a99c6eeb763c004a", - "reference": "d8e7b6a0c83a6e4aa9098360a99c6eeb763c004a", + "url": "https://api.github.com/repos/donatj/PhpUserAgent/zipball/936f092e819bda25fcac120566f64139ff726432", + "reference": "936f092e819bda25fcac120566f64139ff726432", "shasum": "" }, "require": { @@ -170,7 +169,7 @@ "user agent", "useragent" ], - "time": "2016-09-01 22:33:01" + "time": "2016-12-16T04:43:16+00:00" }, { "name": "erusev/parsedown", @@ -178,12 +177,12 @@ "source": { "type": "git", "url": "https://github.com/erusev/parsedown.git", - "reference": "20ff8bbb57205368b4b42d094642a3e52dac85fb" + "reference": "cc5b38ca39a5e09088ed6238415084732678e8dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/erusev/parsedown/zipball/20ff8bbb57205368b4b42d094642a3e52dac85fb", - "reference": "20ff8bbb57205368b4b42d094642a3e52dac85fb", + "url": "https://api.github.com/repos/erusev/parsedown/zipball/cc5b38ca39a5e09088ed6238415084732678e8dc", + "reference": "cc5b38ca39a5e09088ed6238415084732678e8dc", "shasum": "" }, "require": { @@ -212,7 +211,7 @@ "markdown", "parser" ], - "time": "2016-11-02 15:56:58" + "time": "2017-01-07 14:51:03" }, { "name": "erusev/parsedown-extra", @@ -256,20 +255,20 @@ "parsedown", "parser" ], - "time": "2015-11-01 10:19:22" + "time": "2015-11-01T10:19:22+00:00" }, { "name": "filp/whoops", - "version": "2.1.4", + "version": "2.1.5", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "3f5cbd0e6a2fc17bc40b0238025ef1ff4c8c3efa" + "reference": "2abce9d956589122c6443d6265f01cf7e9388e3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/3f5cbd0e6a2fc17bc40b0238025ef1ff4c8c3efa", - "reference": "3f5cbd0e6a2fc17bc40b0238025ef1ff4c8c3efa", + "url": "https://api.github.com/repos/filp/whoops/zipball/2abce9d956589122c6443d6265f01cf7e9388e3c", + "reference": "2abce9d956589122c6443d6265f01cf7e9388e3c", "shasum": "" }, "require": { @@ -316,7 +315,7 @@ "whoops", "zf2" ], - "time": "2016-10-11 15:32:23" + "time": "2016-12-26T16:13:31+00:00" }, { "name": "gregwar/cache", @@ -359,7 +358,7 @@ "file-system", "system" ], - "time": "2016-09-23 08:16:04" + "time": "2016-09-23T08:16:04+00:00" }, { "name": "gregwar/image", @@ -462,7 +461,7 @@ "php", "terminal" ], - "time": "2016-04-04 20:24:59" + "time": "2016-04-04T20:24:59+00:00" }, { "name": "matthiasmullie/minify", @@ -519,7 +518,7 @@ "minifier", "minify" ], - "time": "2016-11-23 10:16:14" + "time": "2016-11-23T10:16:14+00:00" }, { "name": "matthiasmullie/path-converter", @@ -568,20 +567,20 @@ "paths", "relative" ], - "time": "2016-04-27 10:38:05" + "time": "2016-04-27T10:38:05+00:00" }, { "name": "maximebf/debugbar", - "version": "v1.13.0", + "version": "1.13.1", "source": { "type": "git", "url": "https://github.com/maximebf/php-debugbar.git", - "reference": "5f49a5ed6cfde81d31d89378806670d77462526e" + "reference": "afee79a236348e39a44cb837106b7c5b4897ac2a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/5f49a5ed6cfde81d31d89378806670d77462526e", - "reference": "5f49a5ed6cfde81d31d89378806670d77462526e", + "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/afee79a236348e39a44cb837106b7c5b4897ac2a", + "reference": "afee79a236348e39a44cb837106b7c5b4897ac2a", "shasum": "" }, "require": { @@ -629,7 +628,7 @@ "debug", "debugbar" ], - "time": "2016-09-15 14:01:59" + "time": "2017-01-05T08:46:19+00:00" }, { "name": "monolog/monolog", @@ -707,7 +706,7 @@ "logging", "psr-3" ], - "time": "2016-11-26 00:15:39" + "time": "2016-11-26T00:15:39+00:00" }, { "name": "pimple/pimple", @@ -753,7 +752,7 @@ "container", "dependency injection" ], - "time": "2015-09-11 15:10:35" + "time": "2015-09-11T15:10:35+00:00" }, { "name": "psr/log", @@ -800,7 +799,7 @@ "psr", "psr-3" ], - "time": "2016-10-10 12:19:37" + "time": "2016-10-10T12:19:37+00:00" }, { "name": "rockettheme/toolbox", @@ -848,7 +847,7 @@ "php", "rockettheme" ], - "time": "2016-10-06 18:02:45" + "time": "2016-10-06T18:02:45+00:00" }, { "name": "seld/cli-prompt", @@ -896,20 +895,20 @@ "input", "prompt" ], - "time": "2016-04-18 09:31:41" + "time": "2016-04-18T09:31:41+00:00" }, { "name": "symfony/console", - "version": "v2.8.14", + "version": "v2.8.16", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "a871ba00e0f604dceac64c56c27f99fbeaf4854e" + "reference": "2e18b8903d9c498ba02e1dfa73f64d4894bb6912" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/a871ba00e0f604dceac64c56c27f99fbeaf4854e", - "reference": "a871ba00e0f604dceac64c56c27f99fbeaf4854e", + "url": "https://api.github.com/repos/symfony/console/zipball/2e18b8903d9c498ba02e1dfa73f64d4894bb6912", + "reference": "2e18b8903d9c498ba02e1dfa73f64d4894bb6912", "shasum": "" }, "require": { @@ -957,7 +956,7 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2016-11-15 23:02:12" + "time": "2017-01-08T20:43:03+00:00" }, { "name": "symfony/debug", @@ -1014,20 +1013,20 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2016-07-30 07:22:48" + "time": "2016-07-30T07:22:48+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v2.8.14", + "version": "v2.8.16", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934" + "reference": "74877977f90fb9c3e46378d5764217c55f32df34" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/25c576abd4e0f212e678fe8b2bd9a9a98c7ea934", - "reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/74877977f90fb9c3e46378d5764217c55f32df34", + "reference": "74877977f90fb9c3e46378d5764217c55f32df34", "shasum": "" }, "require": { @@ -1074,7 +1073,7 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2016-10-13 01:43:15" + "time": "2017-01-02T20:30:24+00:00" }, { "name": "symfony/polyfill-iconv", @@ -1133,7 +1132,7 @@ "portable", "shim" ], - "time": "2016-11-14 01:06:16" + "time": "2016-11-14T01:06:16+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -1192,20 +1191,20 @@ "portable", "shim" ], - "time": "2016-11-14 01:06:16" + "time": "2016-11-14T01:06:16+00:00" }, { "name": "symfony/var-dumper", - "version": "v2.8.14", + "version": "v2.8.16", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "195c6238ec319cde9204b2d7f271654ceb69b71b" + "reference": "8d2df79c132df0b14df305727fb2c26d33ab5492" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/195c6238ec319cde9204b2d7f271654ceb69b71b", - "reference": "195c6238ec319cde9204b2d7f271654ceb69b71b", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/8d2df79c132df0b14df305727fb2c26d33ab5492", + "reference": "8d2df79c132df0b14df305727fb2c26d33ab5492", "shasum": "" }, "require": { @@ -1255,20 +1254,20 @@ "debug", "dump" ], - "time": "2016-11-03 07:52:58" + "time": "2017-01-02T20:30:24+00:00" }, { "name": "symfony/yaml", - "version": "v2.8.14", + "version": "v2.8.16", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "befb26a3713c97af90d25dd12e75621ef14d91ff" + "reference": "dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/befb26a3713c97af90d25dd12e75621ef14d91ff", - "reference": "befb26a3713c97af90d25dd12e75621ef14d91ff", + "url": "https://api.github.com/repos/symfony/yaml/zipball/dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2", + "reference": "dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2", "shasum": "" }, "require": { @@ -1304,20 +1303,20 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-11-14 16:15:57" + "time": "2017-01-03T13:49:52+00:00" }, { "name": "twig/twig", - "version": "v1.28.2", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "b22ce0eb070e41f7cba65d78fe216de29726459c" + "reference": "ddc9e3e20ee9c0b6908f401ac8353635b750eca7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/b22ce0eb070e41f7cba65d78fe216de29726459c", - "reference": "b22ce0eb070e41f7cba65d78fe216de29726459c", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/ddc9e3e20ee9c0b6908f401ac8353635b750eca7", + "reference": "ddc9e3e20ee9c0b6908f401ac8353635b750eca7", "shasum": "" }, "require": { @@ -1325,12 +1324,12 @@ }, "require-dev": { "symfony/debug": "~2.7", - "symfony/phpunit-bridge": "~3.2@dev" + "symfony/phpunit-bridge": "~3.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.28-dev" + "dev-master": "1.31-dev" } }, "autoload": { @@ -1365,7 +1364,7 @@ "keywords": [ "templating" ], - "time": "2016-11-23 18:41:40" + "time": "2017-01-11T19:36:15+00:00" } ], "packages-dev": [ @@ -1426,7 +1425,7 @@ "gherkin", "parser" ], - "time": "2016-10-30 11:50:56" + "time": "2016-10-30T11:50:56+00:00" }, { "name": "codeception/codeception", @@ -1518,7 +1517,7 @@ "functional testing", "unit testing" ], - "time": "2016-12-05 04:12:24" + "time": "2016-12-05T04:12:24+00:00" }, { "name": "doctrine/instantiator", @@ -1572,30 +1571,32 @@ "constructor", "instantiate" ], - "time": "2015-06-14 21:17:01" + "time": "2015-06-14T21:17:01+00:00" }, { "name": "facebook/webdriver", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/facebook/php-webdriver.git", - "reference": "af21de3ae5306a8ca0bcc02a19735dadc43e83f3" + "reference": "77300c4ab2025d4316635f592ec849ca7323bd8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/af21de3ae5306a8ca0bcc02a19735dadc43e83f3", - "reference": "af21de3ae5306a8ca0bcc02a19735dadc43e83f3", + "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/77300c4ab2025d4316635f592ec849ca7323bd8c", + "reference": "77300c4ab2025d4316635f592ec849ca7323bd8c", "shasum": "" }, "require": { "ext-curl": "*", - "php": "^5.5 || ~7.0" + "php": "^5.5 || ~7.0", + "symfony/process": "^2.8 || ^3.1" }, "require-dev": { "friendsofphp/php-cs-fixer": "^1.11", "php-mock/php-mock-phpunit": "^1.1", "phpunit/phpunit": "4.6.* || ~5.0", + "satooshi/php-coveralls": "^1.0", "squizlabs/php_codesniffer": "^2.6" }, "suggest": { @@ -1619,7 +1620,7 @@ "selenium", "webdriver" ], - "time": "2016-10-14 15:16:51" + "time": "2017-01-13T15:48:08+00:00" }, { "name": "fzaninotto/faker", @@ -1667,7 +1668,7 @@ "faker", "fixtures" ], - "time": "2016-04-29 12:21:54" + "time": "2016-04-29T12:21:54+00:00" }, { "name": "guzzlehttp/guzzle", @@ -1729,32 +1730,32 @@ "rest", "web service" ], - "time": "2016-10-08 15:01:37" + "time": "2016-10-08T15:01:37+00:00" }, { "name": "guzzlehttp/promises", - "version": "1.3.0", + "version": "v1.3.1", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "2693c101803ca78b27972d84081d027fca790a1e" + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/2693c101803ca78b27972d84081d027fca790a1e", - "reference": "2693c101803ca78b27972d84081d027fca790a1e", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", "shasum": "" }, "require": { "php": ">=5.5.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^4.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -1780,7 +1781,7 @@ "keywords": [ "promise" ], - "time": "2016-11-18 17:47:58" + "time": "2016-12-20T10:07:11+00:00" }, { "name": "guzzlehttp/psr7", @@ -1838,7 +1839,7 @@ "stream", "uri" ], - "time": "2016-06-24 23:00:38" + "time": "2016-06-24T23:00:38+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -1892,7 +1893,7 @@ "reflection", "static analysis" ], - "time": "2015-12-27 11:43:31" + "time": "2015-12-27T11:43:31+00:00" }, { "name": "phpdocumentor/reflection-docblock", @@ -1937,7 +1938,7 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2016-09-30 07:12:33" + "time": "2016-09-30T07:12:33+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -1984,7 +1985,7 @@ "email": "me@mikevanriel.com" } ], - "time": "2016-11-25 06:54:22" + "time": "2016-11-25T06:54:22+00:00" }, { "name": "phpspec/prophecy", @@ -2047,7 +2048,7 @@ "spy", "stub" ], - "time": "2016-11-21 14:58:47" + "time": "2016-11-21T14:58:47+00:00" }, { "name": "phpunit/php-code-coverage", @@ -2109,7 +2110,7 @@ "testing", "xunit" ], - "time": "2015-10-06 15:47:00" + "time": "2015-10-06T15:47:00+00:00" }, { "name": "phpunit/php-file-iterator", @@ -2156,7 +2157,7 @@ "filesystem", "iterator" ], - "time": "2016-10-03 07:40:28" + "time": "2016-10-03T07:40:28+00:00" }, { "name": "phpunit/php-text-template", @@ -2197,7 +2198,7 @@ "keywords": [ "template" ], - "time": "2015-06-21 13:50:34" + "time": "2015-06-21T13:50:34+00:00" }, { "name": "phpunit/php-timer", @@ -2241,7 +2242,7 @@ "keywords": [ "timer" ], - "time": "2016-05-12 18:03:57" + "time": "2016-05-12T18:03:57+00:00" }, { "name": "phpunit/php-token-stream", @@ -2290,20 +2291,20 @@ "keywords": [ "tokenizer" ], - "time": "2016-11-15 14:06:22" + "time": "2016-11-15T14:06:22+00:00" }, { "name": "phpunit/phpunit", - "version": "4.8.30", + "version": "4.8.31", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "a534e04d0bd39c557c2881c341efd06fa6f1292a" + "reference": "98b2b39a520766bec663ff5b7ff1b729db9dbfe3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a534e04d0bd39c557c2881c341efd06fa6f1292a", - "reference": "a534e04d0bd39c557c2881c341efd06fa6f1292a", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/98b2b39a520766bec663ff5b7ff1b729db9dbfe3", + "reference": "98b2b39a520766bec663ff5b7ff1b729db9dbfe3", "shasum": "" }, "require": { @@ -2362,7 +2363,7 @@ "testing", "xunit" ], - "time": "2016-12-01 17:05:48" + "time": "2016-12-09T02:45:31+00:00" }, { "name": "phpunit/phpunit-mock-objects", @@ -2418,7 +2419,7 @@ "mock", "xunit" ], - "time": "2015-10-02 06:51:40" + "time": "2015-10-02T06:51:40+00:00" }, { "name": "psr/http-message", @@ -2468,7 +2469,7 @@ "request", "response" ], - "time": "2016-08-06 14:39:51" + "time": "2016-08-06T14:39:51+00:00" }, { "name": "sebastian/comparator", @@ -2532,7 +2533,7 @@ "compare", "equality" ], - "time": "2016-11-19 09:18:40" + "time": "2016-11-19T09:18:40+00:00" }, { "name": "sebastian/diff", @@ -2584,7 +2585,7 @@ "keywords": [ "diff" ], - "time": "2015-12-08 07:14:41" + "time": "2015-12-08T07:14:41+00:00" }, { "name": "sebastian/environment", @@ -2634,7 +2635,7 @@ "environment", "hhvm" ], - "time": "2016-08-18 05:49:44" + "time": "2016-08-18T05:49:44+00:00" }, { "name": "sebastian/exporter", @@ -2701,7 +2702,7 @@ "export", "exporter" ], - "time": "2016-06-17 09:04:28" + "time": "2016-06-17T09:04:28+00:00" }, { "name": "sebastian/global-state", @@ -2752,7 +2753,7 @@ "keywords": [ "global state" ], - "time": "2015-10-12 03:26:01" + "time": "2015-10-12T03:26:01+00:00" }, { "name": "sebastian/recursion-context", @@ -2805,7 +2806,7 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2015-11-11 19:50:13" + "time": "2015-11-11T19:50:13+00:00" }, { "name": "sebastian/version", @@ -2840,20 +2841,20 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2015-06-21 13:59:46" + "time": "2015-06-21T13:59:46+00:00" }, { "name": "symfony/browser-kit", - "version": "v3.2.0", + "version": "v3.2.2", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "34348c2691ce6254e8e008026f4c5e72c22bb318" + "reference": "548f8230bad9f77463b20b15993a008f03e96db5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/34348c2691ce6254e8e008026f4c5e72c22bb318", - "reference": "34348c2691ce6254e8e008026f4c5e72c22bb318", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/548f8230bad9f77463b20b15993a008f03e96db5", + "reference": "548f8230bad9f77463b20b15993a008f03e96db5", "shasum": "" }, "require": { @@ -2897,20 +2898,20 @@ ], "description": "Symfony BrowserKit Component", "homepage": "https://symfony.com", - "time": "2016-10-13 13:35:11" + "time": "2017-01-02T20:32:22+00:00" }, { "name": "symfony/css-selector", - "version": "v3.2.0", + "version": "v3.2.2", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "e1241f275814827c411d922ba8e64cf2a00b2994" + "reference": "f0e628f04fc055c934b3211cfabdb1c59eefbfaa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/e1241f275814827c411d922ba8e64cf2a00b2994", - "reference": "e1241f275814827c411d922ba8e64cf2a00b2994", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/f0e628f04fc055c934b3211cfabdb1c59eefbfaa", + "reference": "f0e628f04fc055c934b3211cfabdb1c59eefbfaa", "shasum": "" }, "require": { @@ -2950,20 +2951,20 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2016-11-03 08:11:03" + "time": "2017-01-02T20:32:22+00:00" }, { "name": "symfony/dom-crawler", - "version": "v3.2.0", + "version": "v3.2.2", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "c6b6111f5aae7c58698cdc10220785627ac44a2c" + "reference": "27d9790840a4efd3b7bb8f5f4f9efc27b36b7024" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/c6b6111f5aae7c58698cdc10220785627ac44a2c", - "reference": "c6b6111f5aae7c58698cdc10220785627ac44a2c", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/27d9790840a4efd3b7bb8f5f4f9efc27b36b7024", + "reference": "27d9790840a4efd3b7bb8f5f4f9efc27b36b7024", "shasum": "" }, "require": { @@ -3006,20 +3007,20 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "time": "2016-11-25 12:32:42" + "time": "2017-01-02T20:32:22+00:00" }, { "name": "symfony/finder", - "version": "v3.2.0", + "version": "v3.2.2", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "4263e35a1e342a0f195c9349c0dee38148f8a14f" + "reference": "8c71141cae8e2957946b403cc71a67213c0380d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/4263e35a1e342a0f195c9349c0dee38148f8a14f", - "reference": "4263e35a1e342a0f195c9349c0dee38148f8a14f", + "url": "https://api.github.com/repos/symfony/finder/zipball/8c71141cae8e2957946b403cc71a67213c0380d6", + "reference": "8c71141cae8e2957946b403cc71a67213c0380d6", "shasum": "" }, "require": { @@ -3055,7 +3056,56 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2016-11-03 08:11:03" + "time": "2017-01-02T20:32:22+00:00" + }, + { + "name": "symfony/process", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "350e810019fc52dd06ae844b6a6d382f8a0e8893" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/350e810019fc52dd06ae844b6a6d382f8a0e8893", + "reference": "350e810019fc52dd06ae844b6a6d382f8a0e8893", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "time": "2017-01-02T20:32:22+00:00" }, { "name": "webmozart/assert", @@ -3105,7 +3155,7 @@ "check", "validate" ], - "time": "2016-11-23 20:04:58" + "time": "2016-11-23T20:04:58+00:00" } ], "aliases": [ diff --git a/system/blueprints/config/site.yaml b/system/blueprints/config/site.yaml index f21121b887..fe783f084a 100644 --- a/system/blueprints/config/site.yaml +++ b/system/blueprints/config/site.yaml @@ -16,6 +16,13 @@ form: placeholder: PLUGIN_ADMIN.SITE_TITLE_PLACEHOLDER help: PLUGIN_ADMIN.SITE_TITLE_HELP + default_lang: + type: text + label: PLUGIN_ADMIN.SITE_DEFAULT_LANG + size: vsmall + placeholder: PLUGIN_ADMIN.SITE_DEFAULT_LANG_PLACEHOLDER + help: PLUGIN_ADMIN.SITE_DEFAULT_LANG_HELP + author.name: type: text size: large diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml index a55c1e1ded..d8b0a24a62 100644 --- a/system/blueprints/config/system.yaml +++ b/system/blueprints/config/system.yaml @@ -244,6 +244,17 @@ form: validate: type: bool + pages.never_cache_twig: + type: toggle + label: PLUGIN_ADMIN.NEVER_CACHE_TWIG + help: PLUGIN_ADMIN.NEVER_CACHE_TWIG_HELP + highlight: 0 + options: + 1: PLUGIN_ADMIN.YES + 0: PLUGIN_ADMIN.NO + validate: + type: bool + pages.frontmatter.process_twig: type: toggle label: PLUGIN_ADMIN.FRONTMATTER_PROCESS_TWIG @@ -461,14 +472,15 @@ form: cache.check.method: type: select - size: small + size: medium classes: fancy label: PLUGIN_ADMIN.CACHE_CHECK_METHOD help: PLUGIN_ADMIN.CACHE_CHECK_METHOD_HELP options: - file: File - folder: Folder - none: None + file: Markdown + Yaml file timestamps + folder: Folder timestamps + hash: All files timestamps + none: No timestamp checking cache.driver: type: select diff --git a/system/blueprints/pages/default.yaml b/system/blueprints/pages/default.yaml index 86302a65af..4fd60722d6 100644 --- a/system/blueprints/pages/default.yaml +++ b/system/blueprints/pages/default.yaml @@ -133,7 +133,7 @@ form: label: PLUGIN_ADMIN.FOLDER_NAME validate: type: slug - pattern: '[a-zа-я0-9_\-]+' + pattern: '[a-zA-Zа-яA-Я0-9_\-]+' route: type: select @@ -225,6 +225,30 @@ form: twig: Twig use: keys + header.twig_first: + type: toggle + toggleable: true + label: PLUGIN_ADMIN.TWIG_FIRST + help: PLUGIN_ADMIN.TWIG_FIRST_HELP + highlight: 0 + options: + 1: PLUGIN_ADMIN.YES + 0: PLUGIN_ADMIN.NO + validate: + type: bool + + header.never_cache_twig: + type: toggle + toggleable: true + label: PLUGIN_ADMIN.NEVER_CACHE_TWIG + help: PLUGIN_ADMIN.NEVER_CACHE_TWIG_HELP + highlight: 0 + options: + 1: PLUGIN_ADMIN.YES + 0: PLUGIN_ADMIN.NO + validate: + type: bool + header.child_type: type: select toggleable: true diff --git a/system/blueprints/pages/modular_new.yaml b/system/blueprints/pages/modular_new.yaml index 0a2a3817db..9e1e21319e 100644 --- a/system/blueprints/pages/modular_new.yaml +++ b/system/blueprints/pages/modular_new.yaml @@ -24,7 +24,7 @@ form: validate: type: slug required: true - pattern: '[a-zа-я0-9_\-]+' + pattern: '[a-zA-Zа-яA-Я0-9_\-]+' route: type: select diff --git a/system/blueprints/pages/modular_raw.yaml b/system/blueprints/pages/modular_raw.yaml index fc61e486ff..2a7b912689 100644 --- a/system/blueprints/pages/modular_raw.yaml +++ b/system/blueprints/pages/modular_raw.yaml @@ -73,7 +73,7 @@ form: validate: type: slug required: true - pattern: '[a-zа-я0-9_\-]+' + pattern: '[a-zA-Zа-яA-Я0-9_\-]+' route: type: select diff --git a/system/blueprints/pages/new.yaml b/system/blueprints/pages/new.yaml index 9f628c027f..719c4bc153 100644 --- a/system/blueprints/pages/new.yaml +++ b/system/blueprints/pages/new.yaml @@ -26,7 +26,7 @@ form: validate: type: slug required: true - pattern: '[a-zа-я0-9_\-]+' + pattern: '[a-zA-Zа-яA-Я0-9_\-]+' route: type: select diff --git a/system/blueprints/pages/new_folder.yaml b/system/blueprints/pages/new_folder.yaml index 3eee46e234..d255c7bc74 100644 --- a/system/blueprints/pages/new_folder.yaml +++ b/system/blueprints/pages/new_folder.yaml @@ -19,7 +19,7 @@ form: validate: type: slug required: true - pattern: '[a-zа-я0-9_\-]+' + pattern: '[a-zA-Zа-яA-Я0-9_\-]+' route: type: select diff --git a/system/blueprints/pages/raw.yaml b/system/blueprints/pages/raw.yaml index 2214601980..245a0b0759 100644 --- a/system/blueprints/pages/raw.yaml +++ b/system/blueprints/pages/raw.yaml @@ -73,7 +73,7 @@ form: validate: type: slug required: true - pattern: '[a-zа-я0-9_\-]+' + pattern: '[a-zA-Zа-яA-Я0-9_\-]+' route: type: select diff --git a/system/config/site.yaml b/system/config/site.yaml index 9bf28526ae..1142a5dd24 100644 --- a/system/config/site.yaml +++ b/system/config/site.yaml @@ -1,4 +1,5 @@ title: Grav # Name of the site +default_lang: en # Default language for site (potentially used by theme) author: name: John Appleseed # Default author name diff --git a/system/config/system.yaml b/system/config/system.yaml index 54e4c47816..7f7ba4baf5 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -36,6 +36,7 @@ pages: markdown: true # Process Markdown twig: false # Process Twig twig_first: false # Process Twig before markdown when processing both on a page + never_cache_twig: false # Only cache content, never cache twig processed in content (incompatible with `twig_first: true`) events: page: true # Enable page level events twig: true # Enable Twig level events diff --git a/system/defines.php b/system/defines.php index bdfb9d2ec3..9426009db8 100644 --- a/system/defines.php +++ b/system/defines.php @@ -8,7 +8,7 @@ // Some standard defines define('GRAV', true); -define('GRAV_VERSION', '1.1.12'); +define('GRAV_VERSION', '1.1.13'); define('GRAV_TESTING', false); define('DS', '/'); define('GRAV_PHP_MIN', '5.5.9'); diff --git a/system/src/Grav/Common/Filesystem/Folder.php b/system/src/Grav/Common/Filesystem/Folder.php index a1bcc0883d..402e1ed5fe 100644 --- a/system/src/Grav/Common/Filesystem/Folder.php +++ b/system/src/Grav/Common/Filesystem/Folder.php @@ -70,9 +70,13 @@ public static function lastModifiedFile($path, $extensions = 'md|yaml') /** @var \RecursiveDirectoryIterator $file */ foreach ($iterator as $filepath => $file) { - $file_modified = $file->getMTime(); - if ($file_modified > $last_modified) { - $last_modified = $file_modified; + try { + $file_modified = $file->getMTime(); + if ($file_modified > $last_modified) { + $last_modified = $file_modified; + } + } catch (\Exception $e) { + Grav::instance()['log']->error('Could not process file: ' . $e->getMessage()); } } @@ -340,12 +344,10 @@ public static function move($source, $target) // Make sure that path to the target exists before moving. self::create(dirname($target)); - // Just rename the directory. $success = @rename($source, $target); - if (!$success) { - $error = error_get_last(); - throw new \RuntimeException($error['message']); + self::copy($source, $target); + self::delete($source); } // Make sure that the change will be detected when caching. diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index c18fa4c2aa..44ca7d331a 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -306,7 +306,7 @@ public function shutdown() } else { // Without gzip we have no other choice than to prevent server from compressing the output. // This action turns off mod_deflate which would prevent us from closing the connection. - header('Content-Encoding: none'); + header('Content-Encoding: identity'); } diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index ff295b6e93..013a3ab324 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -572,16 +572,16 @@ public function content($var = null) $twig_first = isset($this->header->twig_first) ? $this->header->twig_first : $config->get('system.pages.twig_first', true); + // never cache twig means it's always run after content + $never_cache_twig = isset($this->header->never_cache_twig) ? $this->header->never_cache_twig : $config->get('system.pages.never_cache_twig', + false); // if no cached-content run everything - if ($this->content === false || $cache_enable === false) { - $this->content = $this->raw_content; - Grav::instance()->fireEvent('onPageContentRaw', new Event(['page' => $this])); + if ($never_cache_twig) { + if ($this->content === false || $cache_enable === false) { + $this->content = $this->raw_content; + Grav::instance()->fireEvent('onPageContentRaw', new Event(['page' => $this])); - if ($twig_first) { - if ($process_twig) { - $this->processTwig(); - } if ($process_markdown) { $this->processMarkdown(); } @@ -589,21 +589,47 @@ public function content($var = null) // Content Processed but not cached yet Grav::instance()->fireEvent('onPageContentProcessed', new Event(['page' => $this])); - } else { - if ($process_markdown) { - $this->processMarkdown(); + if ($cache_enable) { + $this->cachePageContent(); } + } - // Content Processed but not cached yet - Grav::instance()->fireEvent('onPageContentProcessed', new Event(['page' => $this])); + if ($process_twig) { + $this->processTwig(); + } + + } else { + if ($this->content === false || $cache_enable === false) { + $this->content = $this->raw_content; + Grav::instance()->fireEvent('onPageContentRaw', new Event(['page' => $this])); + + if ($twig_first) { + if ($process_twig) { + $this->processTwig(); + } + if ($process_markdown) { + $this->processMarkdown(); + } + + // Content Processed but not cached yet + Grav::instance()->fireEvent('onPageContentProcessed', new Event(['page' => $this])); + + } else { + if ($process_markdown) { + $this->processMarkdown(); + } + + // Content Processed but not cached yet + Grav::instance()->fireEvent('onPageContentProcessed', new Event(['page' => $this])); - if ($process_twig) { - $this->processTwig(); + if ($process_twig) { + $this->processTwig(); + } } - } - if ($cache_enable) { - $this->cachePageContent(); + if ($cache_enable) { + $this->cachePageContent(); + } } } @@ -1458,44 +1484,58 @@ public function order($var = null) { if ($var !== null) { $order = !empty($var) ? sprintf('%02d.', (int)$var) : ''; - $this->folder($order . $this->slug()); + $this->folder($order . preg_replace(PAGE_ORDER_PREFIX_REGEX, '', $this->folder)); + + return $order; } + preg_match(PAGE_ORDER_PREFIX_REGEX, $this->folder, $order); return isset($order[0]) ? $order[0] : false; } + /** + * Gets the URL for a page - alias of url(). + * + * @param bool $include_host + * + * @return string the permalink + */ + public function link($include_host = false) + { + return $this->url($include_host); + } + /** * Gets the URL with host information, aka Permalink. * @return string The permalink. */ public function permalink() { - return $this->url(true); + return $this->url(true, false, true, true); } /** - * Gets the URL for a page - alias of url(). + * Returns the canonical URL for a page * - * @param bool $include_host - * - * @return string the permalink + * @param bool $include_lang + * @return string */ - public function link($include_host = false) + public function canonical($include_lang = true) { - return $this->url($include_host); + return $this->url(true, true, $include_lang); } /** * Gets the url for the Page. * * @param bool $include_host Defaults false, but true would include http://yourhost.com - * @param bool $canonical true to return the canonical URL + * @param bool $canonical true to return the canonical URL * @param bool $include_lang - * + * @param bool $raw_route * @return string The url. */ - public function url($include_host = false, $canonical = false, $include_lang = true) + public function url($include_host = false, $canonical = false, $include_lang = true, $raw_route = false) { $grav = Grav::instance(); @@ -1531,6 +1571,8 @@ public function url($include_host = false, $canonical = false, $include_lang = t // get canonical route if requested if ($canonical) { $route = $pre_route . $this->routeCanonical(); + } elseif ($raw_route) { + $route = $pre_route . $this->rawRoute(); } else { $route = $pre_route . $this->route(); } @@ -1671,7 +1713,10 @@ public function routeCanonical($var = null) public function id($var = null) { if ($var !== null) { - $this->id = $var; + // store unique per language + $active_lang = Grav::instance()['language']->getLanguage() ?: ''; + $id = $active_lang . $var; + $this->id = $id; } return $this->id; @@ -2298,7 +2343,9 @@ public function collection($params = 'content', $pagination = true) 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 + $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); @@ -2422,7 +2469,7 @@ public function evaluate($value) case 'modular': $results = new Collection(); foreach ($page->children() as $child) { - $results = $results->addPage($child); + $results = $results->addPage($child); } $results->modular(); break; @@ -2610,7 +2657,7 @@ protected function doRelocation($reorder) protected function setPublishState() { - // Handle publishing dates if no explict published option set + // Handle publishing dates if no explicit published option set if (Grav::instance()['config']->get('system.pages.publish_dates') && !isset($this->header->published)) { // unpublish if required, if not clear cache right before page should be unpublished if ($this->unpublishDate()) { diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 2771d131d7..43e9a388e7 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -764,6 +764,7 @@ protected function buildPages() break; case 'hash': $hash = Folder::hashAllFiles($pages_dir); + break; default: $hash = Folder::lastModifiedFile($pages_dir); } diff --git a/system/src/Grav/Common/Plugin.php b/system/src/Grav/Common/Plugin.php index e90e91e204..0c31a435ec 100644 --- a/system/src/Grav/Common/Plugin.php +++ b/system/src/Grav/Common/Plugin.php @@ -246,21 +246,23 @@ protected function parseLinks($content, $function, $internal_regex = '(.*)') /** * Merge global and page configurations. * - * @param Page $page The page to merge the configurations with the + * @param Page $page The page to merge the configurations with the * plugin settings. - * @param bool $deep Should you use deep or shallow merging - * @param array $params Array of additional configuration options to + * @param mixed $deep false = shallow|true = recursive|merge = recursive+unique + * @param array $params Array of additional configuration options to * merge with the plugin settings. + * @param string $type Is this 'plugins' or 'themes' * - * @return \Grav\Common\Data\Data + * @return Data */ - protected function mergeConfig(Page $page, $deep = false, $params = []) + protected function mergeConfig(Page $page, $deep = false, $params = [], $type = 'plugins') { $class_name = $this->name; $class_name_merged = $class_name . '.merged'; - $defaults = $this->config->get('plugins.' . $class_name, []); + $defaults = $this->config->get($type . '.' . $class_name, []); $page_header = $page->header(); $header = []; + if (!isset($page_header->$class_name_merged) && isset($page_header->$class_name)) { // Get default plugin configurations and retrieve page header configuration $config = $page_header->$class_name; @@ -269,11 +271,8 @@ protected function mergeConfig(Page $page, $deep = false, $params = []) $config = ['enabled' => $config]; } // Merge page header settings using deep or shallow merging technique - if ($deep) { - $header = array_replace_recursive($defaults, $config); - } else { - $header = array_merge($defaults, $config); - } + $header = $this->mergeArrays($deep, $defaults, $config); + // Create new config object and set it on the page object so it's cached for next time $page->modifyHeader($class_name_merged, new Data($header)); } else if (isset($page_header->$class_name_merged)) { @@ -284,16 +283,31 @@ protected function mergeConfig(Page $page, $deep = false, $params = []) $header = $defaults; } // Merge additional parameter with configuration options - if ($deep) { - $header = array_replace_recursive($header, $params); - } else { - $header = array_merge($header, $params); - } + $header = $this->mergeArrays($deep, $header, $params); // Return configurations as a new data config class return new Data($header); } + /** + * Merge arrays based on deepness + * + * @param bool $deep + * @param $array1 + * @param $array2 + * @return array|mixed + */ + private function mergeArrays($deep = false, $array1, $array2) + { + if ($deep == 'merge') { + return Utils::arrayMergeRecursiveUnique($array1, $array2); + } elseif ($deep == true) { + return array_replace_recursive($array1, $array2); + } else { + return array_merge($array1, $array2); + } + } + /** * Persists to disk the plugin parameters currently stored in the Grav Config object * diff --git a/system/src/Grav/Common/Theme.php b/system/src/Grav/Common/Theme.php index 1cfe362801..9063e5fc7c 100644 --- a/system/src/Grav/Common/Theme.php +++ b/system/src/Grav/Common/Theme.php @@ -8,6 +8,7 @@ namespace Grav\Common; +use Grav\Common\Page\Page; use Grav\Common\Config\Config; use RocketTheme\Toolbox\File\YamlFile; @@ -59,6 +60,13 @@ public static function saveConfig($theme_name) return true; } + /** + * Override the mergeConfig method to work for themes + */ + protected function mergeConfig(Page $page, $deep = 'merge', $params = [], $type = 'themes') { + return parent::mergeConfig($page, $deep, $params, $type); + } + /** * Simpler getter for the theme blueprint * diff --git a/system/src/Grav/Common/Twig/Twig.php b/system/src/Grav/Common/Twig/Twig.php index 2af6b0a46a..9ef9e3e6de 100644 --- a/system/src/Grav/Common/Twig/Twig.php +++ b/system/src/Grav/Common/Twig/Twig.php @@ -152,21 +152,28 @@ public function init() $this->grav->fireEvent('onTwigExtensions'); + $base_url = $this->grav['base_url'] . $path_append; + // Set some standard variables for twig $this->twig_vars = $this->twig_vars + [ 'config' => $config, + 'system' => $config->get('system'), + 'theme' => $config->get('theme'), + 'site' => $config->get('site'), 'uri' => $this->grav['uri'], + 'assets' => $this->grav['assets'], + 'taxonomy' => $this->grav['taxonomy'], + 'browser' => $this->grav['browser'], 'base_dir' => rtrim(ROOT_DIR, '/'), - 'base_url' => $this->grav['base_url'] . $path_append, + 'base_url' => $base_url, 'base_url_simple' => $this->grav['base_url'], 'base_url_absolute' => $this->grav['base_url_absolute'] . $path_append, 'base_url_relative' => $this->grav['base_url_relative'] . $path_append, + 'home_url' => $base_url == '' ? '/' : $base_url, 'theme_dir' => $locator->findResource('theme://'), 'theme_url' => $this->grav['base_url'] . '/' . $locator->findResource('theme://', false), - 'site' => $config->get('site'), - 'assets' => $this->grav['assets'], - 'taxonomy' => $this->grav['taxonomy'], - 'browser' => $this->grav['browser'], + 'html_lang' => $this->grav['language']->getActive() ?: $config->get('site.default_lang', 'en'), + ]; } } @@ -320,6 +327,7 @@ public function processSite($format = null) $twig_vars = $this->twig_vars; + $twig_vars['theme'] = $this->grav['config']->get('theme'); $twig_vars['pages'] = $pages->root(); $twig_vars['page'] = $page; $twig_vars['header'] = $page->header(); diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index c7b9bb4e2a..825abe9cd9 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -109,6 +109,26 @@ public static function mergeObjects($obj1, $obj2) return (object)array_merge((array)$obj1, (array)$obj2); } + /** + * Recursive Merge with uniqueness + * + * @param $array1 + * @param $array2 + * @return mixed + */ + public static function arrayMergeRecursiveUnique($array1, $array2) + { + if (empty($array1)) return $array2; //optimize the base case + + foreach ($array2 as $key => $value) { + if (is_array($value) && is_array(@$array1[$key])) { + $value = static::arrayMergeRecursiveUnique($array1[$key], $value); + } + $array1[$key] = $value; + } + return $array1; + } + /** * Return the Grav date formats allowed * @@ -813,4 +833,13 @@ public static function setDotNotation(&$array, $key, $value, $merge = false) return $array; } + + /** + * Utility method to determine if the current OS is Windows + * + * @return bool + */ + public static function isWindows() { + return strncasecmp(PHP_OS, 'WIN', 3) == 0; + } } diff --git a/webserver-configs/nginx.conf b/webserver-configs/nginx.conf index 640964a6d3..4c74a70db9 100644 --- a/webserver-configs/nginx.conf +++ b/webserver-configs/nginx.conf @@ -12,7 +12,7 @@ server { # `location /subfolder {` # and the rewrite to use `/subfolder/index.php` location / { - try_files $uri $uri/ /index.php?_url=$uri; + try_files $uri $uri/ /index.php?_url=$uri&$query_string; } ## End - Index