diff --git a/.travis.yml b/.travis.yml index 74dcfa60f..6b91d20bd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,6 +55,7 @@ before_install: fi - if [ $TRAVIS_BRANCH != 'develop' ] && [ $TRAVIS_PHP_VERSION == "5.6" ] && [ $TRAVIS_PULL_REQUEST == "false" ]; then export TRAVIS_TAG=$(curl --fail --user "${GH_API_USER}" -s https://api.github.com/repos/getgrav/grav/releases/latest | grep tag_name | head -n 1 | cut -d '"' -f 4); + eval "$(curl -sL https://raw.githubusercontent.com/travis-ci/gimme/master/gimme | GIMME_GO_VERSION=1.8 bash)"; go get github.com/aktau/github-release; git clone --quiet --depth=50 --branch=master https://${BB_TOKEN}bitbucket.org/rockettheme/grav-devtools.git $RT_DEVTOOLS &>/dev/null; if [ ! -z "$TRAVIS_TAG" ]; then diff --git a/CHANGELOG.md b/CHANGELOG.md index 6745ca6e2..0136c0a73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,61 @@ -# v1.1.18 -## 02/xx/2017 +# v1.2.2 +## 04/11/2017 + +1. [](#bugfix) + * Fix for redirects breaking [#1420](https://github.com/getgrav/grav/issues/1420) + * Fix issue in direct-install with github-style dependencies [#1405](https://github.com/getgrav/grav/issues/1405) + +# v1.2.1 +## 04/10/2017 + +1. [](#improved) + * Added various `ancestor` helper methods in Page and Pages classes [#1362](https://github.com/getgrav/grav/pull/1362) + * Added new `parents` field and switched Page blueprints to use this + * Added `isajaxrequest()` Twig function [#1400](https://github.com/getgrav/grav/issues/1400) + * Added ability to inline CSS and JS code via Asset manager [#1377](https://github.com/getgrav/grav/pull/1377) + * Add query string in lighttpd default config [#1393](https://github.com/getgrav/grav/issues/1393) + * Add `--all-yes` and `--destination` options for `bin/gpm direct-install` [#1397](https://github.com/getgrav/grav/pull/1397) +1. [](#bugfix) + * Fix for direct-install of plugins with `languages.yaml` [#1396](https://github.com/getgrav/grav/issues/1396) + * When determining language from HTTP_ACCEPT_LANGUAGE, also try base language only [#1402](https://github.com/getgrav/grav/issues/1402) + * Fixed a bad method signature causing warning when running tests on `GPMTest` object + +# v1.2.0 +## 03/31/2017 + +1. [](#new) + * Added file upload for user avatar in user/admin blueprint +1. [](#improved) + * Analysis fixes + * Switched to stable composer lib versions + +# v1.2.0-rc.3 +## 03/22/2017 + +1. [](#new) + * Refactored Page re-ordering to handle all siblings at once + * Added `language_codes` to Twig init to allow for easy language name/code/native-name lookup +1. [](#improved) + * Added an _Admin Overrides_ section with option to choose the order of children in Pages Management +1. [](#bugfix) + * Fixed loading issues with improperly named themes (use old broken method first) [#1373](https://github.com/getgrav/grav/issues/1373) + * Simplified modular/twig processing logic and fixed an issue with system process config [#1351](https://github.com/getgrav/grav/issues/1351) + * Cleanup package files via GPM install to make them more windows-friendly [#1361](https://github.com/getgrav/grav/pull/1361) + * Fix for page-level debugger override changing the option site-wide + * Allow `url()` twig function to pass-through external links + +# v1.2.0-rc.2 +## 03/17/2017 + +1. [](#improved) + * Updated vendor libraries to latest + * Added the ability to disable debugger on a per-page basis with `debugger: false` in page frontmatter +1. [](#bugfix) + * Fixed an issue with theme inheritance and hyphenated base themes [#1353](https://github.com/getgrav/grav/issues/1353) + * Fixed an issue when trying to use an `@2x` derivative on a non-image media file [#1341](https://github.com/getgrav/grav/issues/1341) + +# v1.2.0-rc.1 +## 03/13/2017 1. [](#new) * Added default setting to only allow `direct-installs` from official GPM. Can be configured in `system.yaml` @@ -7,6 +63,7 @@ * Added optional parameter to `|markdown(false)` filter to toggle block/line processing (default|true = `block`) * Added new `Page::folderExists()` method 1. [](#improved) + * `Twig::evaluate()` now takes current environment and context into account * Genericized `direct-install` so it can be called via Admin plugin 1. [](#bugfix) * Fixed a minor bug in Number validation [#1329](https://github.com/getgrav/grav/issues/1329) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5d5c52774..22362c8a5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -110,7 +110,7 @@ Good pull requests - patches, improvements, new features - are a fantastic help. They should remain focused in scope and avoid containing unrelated commits. -**Please ask first** in Gitter or in the Forum before embarking on any significant pull request (e.g. +**Please ask first** in [Slack](https://getgrav.org/slack) or in the Forum before embarking on any significant pull request (e.g. implementing features, refactoring code..), otherwise you risk spending a lot of time working on something that the project's developers might not want to merge into the project. diff --git a/composer.json b/composer.json index bddc05f67..1f299804e 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,7 @@ "require": { "php": ">=5.5.9", "twig/twig": "~1.24", - "erusev/parsedown": "dev-master as 1.6.0", + "erusev/parsedown": "~1.6", "erusev/parsedown-extra": "~0.7", "symfony/yaml": "~2.8", "symfony/console": "~2.8", @@ -20,7 +20,7 @@ "filp/whoops": "~2.0", "matthiasmullie/minify": "^1.3", "monolog/monolog": "~1.0", - "gregwar/image": "dev-master#72568cfbeb77515278f2ccb386fc344e874b7ae8", + "gregwar/image": "~2.0", "donatj/phpuseragentparser": "~0.3", "pimple/pimple": "~3.0", "rockettheme/toolbox": "~1.0", diff --git a/composer.lock b/composer.lock index e248b3bcd..426d66135 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "d71bd78770ae90cfdd59960d2829cb75", - "content-hash": "7f68c667c95b191cfd0b6eeef614dc3d", + "content-hash": "acef808d0660c4938b26a2348ca26191", "packages": [ { "name": "antoligy/dom-string-iterators", @@ -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,7 +118,7 @@ "cache", "caching" ], - "time": "2016-10-29 11:16:17" + "time": "2016-10-29T11:16:17+00:00" }, { "name": "doctrine/collections", @@ -186,20 +185,20 @@ "collections", "iterator" ], - "time": "2017-01-03 10:49:41" + "time": "2017-01-03T10:49:41+00:00" }, { "name": "donatj/phpuseragentparser", - "version": "v0.6.0", + "version": "v0.7.0", "source": { "type": "git", "url": "https://github.com/donatj/PhpUserAgent.git", - "reference": "a4f515619c8d9697f34dd8da2eb353bb4c57c5dc" + "reference": "73c819d4c7de034f1bfb7c7a36259192d7d7472a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/donatj/PhpUserAgent/zipball/a4f515619c8d9697f34dd8da2eb353bb4c57c5dc", - "reference": "a4f515619c8d9697f34dd8da2eb353bb4c57c5dc", + "url": "https://api.github.com/repos/donatj/PhpUserAgent/zipball/73c819d4c7de034f1bfb7c7a36259192d7d7472a", + "reference": "73c819d4c7de034f1bfb7c7a36259192d7d7472a", "shasum": "" }, "require": { @@ -237,20 +236,20 @@ "user agent", "useragent" ], - "time": "2017-01-23 19:32:09" + "time": "2017-03-01T22:19:13+00:00" }, { "name": "erusev/parsedown", - "version": "dev-master", + "version": "1.6.2", "source": { "type": "git", "url": "https://github.com/erusev/parsedown.git", - "reference": "4b6493999acfa7792efa3cb252d90168e6f266b9" + "reference": "1bf24f7334fe16c88bf9d467863309ceaf285b01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/erusev/parsedown/zipball/4b6493999acfa7792efa3cb252d90168e6f266b9", - "reference": "4b6493999acfa7792efa3cb252d90168e6f266b9", + "url": "https://api.github.com/repos/erusev/parsedown/zipball/1bf24f7334fe16c88bf9d467863309ceaf285b01", + "reference": "1bf24f7334fe16c88bf9d467863309ceaf285b01", "shasum": "" }, "require": { @@ -279,7 +278,7 @@ "markdown", "parser" ], - "time": "2017-01-23 07:45:19" + "time": "2017-03-29T16:04:15+00:00" }, { "name": "erusev/parsedown-extra", @@ -323,24 +322,25 @@ "parsedown", "parser" ], - "time": "2015-11-01 10:19:22" + "time": "2015-11-01T10:19:22+00:00" }, { "name": "filp/whoops", - "version": "2.1.5", + "version": "2.1.8", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "2abce9d956589122c6443d6265f01cf7e9388e3c" + "reference": "f2950be7da8b8d6c4e77821b6c9d486e36cdc4f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/2abce9d956589122c6443d6265f01cf7e9388e3c", - "reference": "2abce9d956589122c6443d6265f01cf7e9388e3c", + "url": "https://api.github.com/repos/filp/whoops/zipball/f2950be7da8b8d6c4e77821b6c9d486e36cdc4f3", + "reference": "f2950be7da8b8d6c4e77821b6c9d486e36cdc4f3", "shasum": "" }, "require": { - "php": "^5.5.9 || ^7.0" + "php": "^5.5.9 || ^7.0", + "psr/log": "^1.0.1" }, "require-dev": { "mockery/mockery": "0.9.*", @@ -383,7 +383,7 @@ "whoops", "zf2" ], - "time": "2016-12-26 16:13:31" + "time": "2017-03-07T09:04:45+00:00" }, { "name": "gregwar/cache", @@ -426,21 +426,21 @@ "file-system", "system" ], - "time": "2016-09-23 08:16:04" + "time": "2016-09-23T08:16:04+00:00" }, { "name": "gregwar/image", - "version": "dev-master", + "version": "v2.0.21", "target-dir": "Gregwar/Image", "source": { "type": "git", "url": "https://github.com/Gregwar/Image.git", - "reference": "72568cfbeb77515278f2ccb386fc344e874b7ae8" + "reference": "c9899e4c71009338f89a8c63c12c681692533ede" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Gregwar/Image/zipball/72568cfbeb77515278f2ccb386fc344e874b7ae8", - "reference": "72568cfbeb77515278f2ccb386fc344e874b7ae8", + "url": "https://api.github.com/repos/Gregwar/Image/zipball/c9899e4c71009338f89a8c63c12c681692533ede", + "reference": "c9899e4c71009338f89a8c63c12c681692533ede", "shasum": "" }, "require": { @@ -478,7 +478,7 @@ "gd", "image" ], - "time": "2016-07-12 17:02:18" + "time": "2017-01-24T09:29:39+00:00" }, { "name": "league/climate", @@ -529,20 +529,20 @@ "php", "terminal" ], - "time": "2016-04-04 20:24:59" + "time": "2016-04-04T20:24:59+00:00" }, { "name": "matthiasmullie/minify", - "version": "1.3.43", + "version": "1.3.44", "source": { "type": "git", "url": "https://github.com/matthiasmullie/minify.git", - "reference": "aa50b2dab6fa7bfd402d334fe51005d6f2526ad7" + "reference": "a7fc4a98ef8f2cf38bba701b51f1a84a1d67bc5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/aa50b2dab6fa7bfd402d334fe51005d6f2526ad7", - "reference": "aa50b2dab6fa7bfd402d334fe51005d6f2526ad7", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/a7fc4a98ef8f2cf38bba701b51f1a84a1d67bc5c", + "reference": "a7fc4a98ef8f2cf38bba701b51f1a84a1d67bc5c", "shasum": "" }, "require": { @@ -586,7 +586,7 @@ "minifier", "minify" ], - "time": "2017-01-26 15:48:07" + "time": "2017-03-16T16:42:50+00:00" }, { "name": "matthiasmullie/path-converter", @@ -635,7 +635,7 @@ "paths", "relative" ], - "time": "2017-01-26 08:54:49" + "time": "2017-01-26T08:54:49+00:00" }, { "name": "maximebf/debugbar", @@ -696,20 +696,20 @@ "debug", "debugbar" ], - "time": "2017-01-05 08:46:19" + "time": "2017-01-05T08:46:19+00:00" }, { "name": "monolog/monolog", - "version": "1.22.0", + "version": "1.22.1", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "bad29cb8d18ab0315e6c477751418a82c850d558" + "reference": "1e044bc4b34e91743943479f1be7a1d5eb93add0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bad29cb8d18ab0315e6c477751418a82c850d558", - "reference": "bad29cb8d18ab0315e6c477751418a82c850d558", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/1e044bc4b34e91743943479f1be7a1d5eb93add0", + "reference": "1e044bc4b34e91743943479f1be7a1d5eb93add0", "shasum": "" }, "require": { @@ -774,7 +774,7 @@ "logging", "psr-3" ], - "time": "2016-11-26 00:15:39" + "time": "2017-03-13T07:08:03+00:00" }, { "name": "pimple/pimple", @@ -820,7 +820,7 @@ "container", "dependency injection" ], - "time": "2015-09-11 15:10:35" + "time": "2015-09-11T15:10:35+00:00" }, { "name": "psr/log", @@ -867,7 +867,7 @@ "psr", "psr-3" ], - "time": "2016-10-10 12:19:37" + "time": "2016-10-10T12:19:37+00:00" }, { "name": "rockettheme/toolbox", @@ -915,20 +915,20 @@ "php", "rockettheme" ], - "time": "2016-10-06 18:02:45" + "time": "2016-10-06T18:02:45+00:00" }, { "name": "seld/cli-prompt", - "version": "1.0.2", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/Seldaek/cli-prompt.git", - "reference": "8cbe10923cae5bcd7c5a713f6703fc4727c8c1b4" + "reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/8cbe10923cae5bcd7c5a713f6703fc4727c8c1b4", - "reference": "8cbe10923cae5bcd7c5a713f6703fc4727c8c1b4", + "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/a19a7376a4689d4d94cab66ab4f3c816019ba8dd", + "reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd", "shasum": "" }, "require": { @@ -963,25 +963,25 @@ "input", "prompt" ], - "time": "2016-04-18 09:31:41" + "time": "2017-03-18T11:32:45+00:00" }, { "name": "symfony/console", - "version": "v2.8.17", + "version": "v2.8.19", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "f3c234cd8db9f7e520a91d695db7d8bb5daeb7a4" + "reference": "86407ff20855a5eaa2a7219bd815e9c40a88633e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/f3c234cd8db9f7e520a91d695db7d8bb5daeb7a4", - "reference": "f3c234cd8db9f7e520a91d695db7d8bb5daeb7a4", + "url": "https://api.github.com/repos/symfony/console/zipball/86407ff20855a5eaa2a7219bd815e9c40a88633e", + "reference": "86407ff20855a5eaa2a7219bd815e9c40a88633e", "shasum": "" }, "require": { "php": ">=5.3.9", - "symfony/debug": "~2.7,>=2.7.2|~3.0.0", + "symfony/debug": "^2.7.2|~3.0.0", "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { @@ -1024,7 +1024,7 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2017-02-06 12:04:06" + "time": "2017-04-03T20:37:06+00:00" }, { "name": "symfony/debug", @@ -1081,20 +1081,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.17", + "version": "v2.8.19", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "74877977f90fb9c3e46378d5764217c55f32df34" + "reference": "88b65f0ac25355090e524aba4ceb066025df8bd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/74877977f90fb9c3e46378d5764217c55f32df34", - "reference": "74877977f90fb9c3e46378d5764217c55f32df34", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/88b65f0ac25355090e524aba4ceb066025df8bd2", + "reference": "88b65f0ac25355090e524aba4ceb066025df8bd2", "shasum": "" }, "require": { @@ -1102,7 +1102,7 @@ }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~2.0,>=2.0.5|~3.0.0", + "symfony/config": "^2.0.5|~3.0.0", "symfony/dependency-injection": "~2.6|~3.0.0", "symfony/expression-language": "~2.6|~3.0.0", "symfony/stopwatch": "~2.3|~3.0.0" @@ -1141,7 +1141,7 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2017-01-02 20:30:24" + "time": "2017-04-03T20:37:06+00:00" }, { "name": "symfony/polyfill-iconv", @@ -1200,7 +1200,7 @@ "portable", "shim" ], - "time": "2016-11-14 01:06:16" + "time": "2016-11-14T01:06:16+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -1259,26 +1259,29 @@ "portable", "shim" ], - "time": "2016-11-14 01:06:16" + "time": "2016-11-14T01:06:16+00:00" }, { "name": "symfony/var-dumper", - "version": "v2.8.17", + "version": "v2.8.19", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "eb4526a20ba9e691f50a7510ea3db3728ada958f" + "reference": "f8ff23ad5352f96e66c1df5468d492d2f37f3ac4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/eb4526a20ba9e691f50a7510ea3db3728ada958f", - "reference": "eb4526a20ba9e691f50a7510ea3db3728ada958f", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/f8ff23ad5352f96e66c1df5468d492d2f37f3ac4", + "reference": "f8ff23ad5352f96e66c1df5468d492d2f37f3ac4", "shasum": "" }, "require": { "php": ">=5.3.9", "symfony/polyfill-mbstring": "~1.0" }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" + }, "require-dev": { "twig/twig": "~1.20|~2.0" }, @@ -1322,20 +1325,20 @@ "debug", "dump" ], - "time": "2017-01-24 13:02:12" + "time": "2017-03-12T16:01:59+00:00" }, { "name": "symfony/yaml", - "version": "v2.8.17", + "version": "v2.8.19", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "322a8c2dfbca15ad6b1b27e182899f98ec0e0153" + "reference": "286d84891690b0e2515874717e49360d1c98a703" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/322a8c2dfbca15ad6b1b27e182899f98ec0e0153", - "reference": "322a8c2dfbca15ad6b1b27e182899f98ec0e0153", + "url": "https://api.github.com/repos/symfony/yaml/zipball/286d84891690b0e2515874717e49360d1c98a703", + "reference": "286d84891690b0e2515874717e49360d1c98a703", "shasum": "" }, "require": { @@ -1371,33 +1374,34 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2017-01-21 16:40:50" + "time": "2017-03-20T09:41:44+00:00" }, { "name": "twig/twig", - "version": "v1.31.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "ddc9e3e20ee9c0b6908f401ac8353635b750eca7" + "reference": "05cf49921b13f6f01d3cfdf9018cfa7a8086fd5a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/ddc9e3e20ee9c0b6908f401ac8353635b750eca7", - "reference": "ddc9e3e20ee9c0b6908f401ac8353635b750eca7", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/05cf49921b13f6f01d3cfdf9018cfa7a8086fd5a", + "reference": "05cf49921b13f6f01d3cfdf9018cfa7a8086fd5a", "shasum": "" }, "require": { "php": ">=5.2.7" }, "require-dev": { + "psr/container": "^1.0", "symfony/debug": "~2.7", - "symfony/phpunit-bridge": "~3.2" + "symfony/phpunit-bridge": "~3.3@dev" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.31-dev" + "dev-master": "1.33-dev" } }, "autoload": { @@ -1432,7 +1436,7 @@ "keywords": [ "templating" ], - "time": "2017-01-11 19:36:15" + "time": "2017-03-22T15:40:09+00:00" } ], "packages-dev": [ @@ -1493,20 +1497,20 @@ "gherkin", "parser" ], - "time": "2016-10-30 11:50:56" + "time": "2016-10-30T11:50:56+00:00" }, { "name": "codeception/codeception", - "version": "2.2.9", + "version": "2.2.10", "source": { "type": "git", "url": "https://github.com/Codeception/Codeception.git", - "reference": "0204f1362040d3e408404af2545e5fa27e8964e2" + "reference": "c32a3f92834db08ceedb4666ea2265c3aa43396e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/Codeception/zipball/0204f1362040d3e408404af2545e5fa27e8964e2", - "reference": "0204f1362040d3e408404af2545e5fa27e8964e2", + "url": "https://api.github.com/repos/Codeception/Codeception/zipball/c32a3f92834db08ceedb4666ea2265c3aa43396e", + "reference": "c32a3f92834db08ceedb4666ea2265c3aa43396e", "shasum": "" }, "require": { @@ -1521,6 +1525,7 @@ "phpunit/phpunit": ">4.8.20 <6.0", "sebastian/comparator": "~1.1", "sebastian/diff": "^1.4", + "stecman/symfony-console-completion": "^0.7.0", "symfony/browser-kit": ">=2.7 <4.0", "symfony/console": ">=2.7 <4.0", "symfony/css-selector": ">=2.7 <4.0", @@ -1585,7 +1590,7 @@ "functional testing", "unit testing" ], - "time": "2017-02-04 02:04:21" + "time": "2017-03-25T03:19:52+00:00" }, { "name": "doctrine/instantiator", @@ -1639,38 +1644,41 @@ "constructor", "instantiate" ], - "time": "2015-06-14 21:17:01" + "time": "2015-06-14T21:17:01+00:00" }, { "name": "facebook/webdriver", - "version": "1.3.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/facebook/php-webdriver.git", - "reference": "77300c4ab2025d4316635f592ec849ca7323bd8c" + "reference": "3ea034c056189e11c0ce7985332a9f4b5b2b5db2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/77300c4ab2025d4316635f592ec849ca7323bd8c", - "reference": "77300c4ab2025d4316635f592ec849ca7323bd8c", + "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/3ea034c056189e11c0ce7985332a9f4b5b2b5db2", + "reference": "3ea034c056189e11c0ce7985332a9f4b5b2b5db2", "shasum": "" }, "require": { "ext-curl": "*", + "ext-zip": "*", "php": "^5.5 || ~7.0", "symfony/process": "^2.8 || ^3.1" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^1.11", + "friendsofphp/php-cs-fixer": "^2.0", "php-mock/php-mock-phpunit": "^1.1", "phpunit/phpunit": "4.6.* || ~5.0", "satooshi/php-coveralls": "^1.0", "squizlabs/php_codesniffer": "^2.6" }, - "suggest": { - "phpdocumentor/phpdocumentor": "2.*" - }, "type": "library", + "extra": { + "branch-alias": { + "dev-community": "1.5-dev" + } + }, "autoload": { "psr-4": { "Facebook\\WebDriver\\": "lib/" @@ -1680,7 +1688,7 @@ "license": [ "Apache-2.0" ], - "description": "A PHP client for WebDriver", + "description": "A PHP client for Selenium WebDriver", "homepage": "https://github.com/facebook/php-webdriver", "keywords": [ "facebook", @@ -1688,7 +1696,7 @@ "selenium", "webdriver" ], - "time": "2017-01-13 15:48:08" + "time": "2017-03-22T10:56:03+00:00" }, { "name": "fzaninotto/faker", @@ -1736,25 +1744,25 @@ "faker", "fixtures" ], - "time": "2016-04-29 12:21:54" + "time": "2016-04-29T12:21:54+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "6.2.2", + "version": "6.2.3", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "ebf29dee597f02f09f4d5bbecc68230ea9b08f60" + "reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/ebf29dee597f02f09f4d5bbecc68230ea9b08f60", - "reference": "ebf29dee597f02f09f4d5bbecc68230ea9b08f60", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/8d6c6cc55186db87b7dc5009827429ba4e9dc006", + "reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006", "shasum": "" }, "require": { "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.3.1", + "guzzlehttp/psr7": "^1.4", "php": ">=5.5" }, "require-dev": { @@ -1798,7 +1806,7 @@ "rest", "web service" ], - "time": "2016-10-08 15:01:37" + "time": "2017-02-28T22:50:30+00:00" }, { "name": "guzzlehttp/promises", @@ -1849,20 +1857,20 @@ "keywords": [ "promise" ], - "time": "2016-12-20 10:07:11" + "time": "2016-12-20T10:07:11+00:00" }, { "name": "guzzlehttp/psr7", - "version": "1.3.1", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "5c6447c9df362e8f8093bda8f5d8873fe5c7f65b" + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/5c6447c9df362e8f8093bda8f5d8873fe5c7f65b", - "reference": "5c6447c9df362e8f8093bda8f5d8873fe5c7f65b", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c", "shasum": "" }, "require": { @@ -1898,16 +1906,23 @@ "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" } ], - "description": "PSR-7 message implementation", + "description": "PSR-7 message implementation that also provides common utility methods", "keywords": [ "http", "message", + "request", + "response", "stream", - "uri" + "uri", + "url" ], - "time": "2016-06-24 23:00:38" + "time": "2017-03-20T17:10:46+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -1961,7 +1976,7 @@ "reflection", "static analysis" ], - "time": "2015-12-27 11:43:31" + "time": "2015-12-27T11:43:31+00:00" }, { "name": "phpdocumentor/reflection-docblock", @@ -2006,7 +2021,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", @@ -2053,31 +2068,31 @@ "email": "me@mikevanriel.com" } ], - "time": "2016-11-25 06:54:22" + "time": "2016-11-25T06:54:22+00:00" }, { "name": "phpspec/prophecy", - "version": "v1.6.2", + "version": "v1.7.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "6c52c2722f8460122f96f86346600e1077ce22cb" + "reference": "93d39f1f7f9326d746203c7c056f300f7f126073" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb", - "reference": "6c52c2722f8460122f96f86346600e1077ce22cb", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073", + "reference": "93d39f1f7f9326d746203c7c056f300f7f126073", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.3|^7.0", "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", - "sebastian/comparator": "^1.1", - "sebastian/recursion-context": "^1.0|^2.0" + "sebastian/comparator": "^1.1|^2.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" }, "require-dev": { - "phpspec/phpspec": "^2.0", + "phpspec/phpspec": "^2.5|^3.2", "phpunit/phpunit": "^4.8 || ^5.6.5" }, "type": "library", @@ -2116,7 +2131,7 @@ "spy", "stub" ], - "time": "2016-11-21 14:58:47" + "time": "2017-03-02T20:05:34+00:00" }, { "name": "phpunit/php-code-coverage", @@ -2178,7 +2193,7 @@ "testing", "xunit" ], - "time": "2015-10-06 15:47:00" + "time": "2015-10-06T15:47:00+00:00" }, { "name": "phpunit/php-file-iterator", @@ -2225,7 +2240,7 @@ "filesystem", "iterator" ], - "time": "2016-10-03 07:40:28" + "time": "2016-10-03T07:40:28+00:00" }, { "name": "phpunit/php-text-template", @@ -2266,29 +2281,34 @@ "keywords": [ "template" ], - "time": "2015-06-21 13:50:34" + "time": "2015-06-21T13:50:34+00:00" }, { "name": "phpunit/php-timer", - "version": "1.0.8", + "version": "1.0.9", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260" + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260", - "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^5.3.3 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4|~5" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, "autoload": { "classmap": [ "src/" @@ -2310,20 +2330,20 @@ "keywords": [ "timer" ], - "time": "2016-05-12 18:03:57" + "time": "2017-02-26T11:10:40+00:00" }, { "name": "phpunit/php-token-stream", - "version": "1.4.9", + "version": "1.4.11", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b" + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b", - "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7", + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7", "shasum": "" }, "require": { @@ -2359,7 +2379,7 @@ "keywords": [ "tokenizer" ], - "time": "2016-11-15 14:06:22" + "time": "2017-02-27T10:12:30+00:00" }, { "name": "phpunit/phpunit", @@ -2431,7 +2451,7 @@ "testing", "xunit" ], - "time": "2017-02-06 05:18:07" + "time": "2017-02-06T05:18:07+00:00" }, { "name": "phpunit/phpunit-mock-objects", @@ -2487,7 +2507,7 @@ "mock", "xunit" ], - "time": "2015-10-02 06:51:40" + "time": "2015-10-02T06:51:40+00:00" }, { "name": "psr/http-message", @@ -2537,7 +2557,7 @@ "request", "response" ], - "time": "2016-08-06 14:39:51" + "time": "2016-08-06T14:39:51+00:00" }, { "name": "sebastian/comparator", @@ -2601,7 +2621,7 @@ "compare", "equality" ], - "time": "2017-01-29 09:50:25" + "time": "2017-01-29T09:50:25+00:00" }, { "name": "sebastian/diff", @@ -2653,7 +2673,7 @@ "keywords": [ "diff" ], - "time": "2015-12-08 07:14:41" + "time": "2015-12-08T07:14:41+00:00" }, { "name": "sebastian/environment", @@ -2703,7 +2723,7 @@ "environment", "hhvm" ], - "time": "2016-08-18 05:49:44" + "time": "2016-08-18T05:49:44+00:00" }, { "name": "sebastian/exporter", @@ -2770,7 +2790,7 @@ "export", "exporter" ], - "time": "2016-06-17 09:04:28" + "time": "2016-06-17T09:04:28+00:00" }, { "name": "sebastian/global-state", @@ -2821,20 +2841,20 @@ "keywords": [ "global state" ], - "time": "2015-10-12 03:26:01" + "time": "2015-10-12T03:26:01+00:00" }, { "name": "sebastian/recursion-context", - "version": "1.0.2", + "version": "1.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "913401df809e99e4f47b27cdd781f4a258d58791" + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", - "reference": "913401df809e99e4f47b27cdd781f4a258d58791", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", "shasum": "" }, "require": { @@ -2874,7 +2894,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": "2016-10-03T07:41:43+00:00" }, { "name": "sebastian/version", @@ -2909,20 +2929,65 @@ ], "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.3", + "name": "stecman/symfony-console-completion", + "version": "0.7.0", "source": { "type": "git", - "url": "https://github.com/symfony/browser-kit.git", - "reference": "394a2475a3a89089353fde5714a7f402fbb83880" + "url": "https://github.com/stecman/symfony-console-completion.git", + "reference": "5461d43e53092b3d3b9dbd9d999f2054730f4bbb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/394a2475a3a89089353fde5714a7f402fbb83880", - "reference": "394a2475a3a89089353fde5714a7f402fbb83880", + "url": "https://api.github.com/repos/stecman/symfony-console-completion/zipball/5461d43e53092b3d3b9dbd9d999f2054730f4bbb", + "reference": "5461d43e53092b3d3b9dbd9d999f2054730f4bbb", + "shasum": "" + }, + "require": { + "php": ">=5.3.2", + "symfony/console": "~2.3 || ~3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Stecman\\Component\\Symfony\\Console\\BashCompletion\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Stephen Holdaway", + "email": "stephen@stecman.co.nz" + } + ], + "description": "Automatic BASH completion for Symfony Console Component based applications.", + "time": "2016-02-24T05:08:54+00:00" + }, + { + "name": "symfony/browser-kit", + "version": "v3.2.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/browser-kit.git", + "reference": "2fe0caa60c1a1dfeefd0425741182687a9b382b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/2fe0caa60c1a1dfeefd0425741182687a9b382b8", + "reference": "2fe0caa60c1a1dfeefd0425741182687a9b382b8", "shasum": "" }, "require": { @@ -2966,20 +3031,20 @@ ], "description": "Symfony BrowserKit Component", "homepage": "https://symfony.com", - "time": "2017-01-31 21:49:23" + "time": "2017-02-21T09:12:04+00:00" }, { "name": "symfony/css-selector", - "version": "v3.2.3", + "version": "v3.2.7", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "f0e628f04fc055c934b3211cfabdb1c59eefbfaa" + "reference": "a48f13dc83c168f1253a5d2a5a4fb46c36244c4c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/f0e628f04fc055c934b3211cfabdb1c59eefbfaa", - "reference": "f0e628f04fc055c934b3211cfabdb1c59eefbfaa", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/a48f13dc83c168f1253a5d2a5a4fb46c36244c4c", + "reference": "a48f13dc83c168f1253a5d2a5a4fb46c36244c4c", "shasum": "" }, "require": { @@ -3019,20 +3084,20 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2017-01-02 20:32:22" + "time": "2017-02-21T09:12:04+00:00" }, { "name": "symfony/dom-crawler", - "version": "v3.2.3", + "version": "v3.2.7", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "b814b41373fc4e535aff8c765abe39545216f391" + "reference": "403944e294cf4ceb3b8447f54cbad88ea7b99cee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/b814b41373fc4e535aff8c765abe39545216f391", - "reference": "b814b41373fc4e535aff8c765abe39545216f391", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/403944e294cf4ceb3b8447f54cbad88ea7b99cee", + "reference": "403944e294cf4ceb3b8447f54cbad88ea7b99cee", "shasum": "" }, "require": { @@ -3075,20 +3140,20 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "time": "2017-01-21 17:14:11" + "time": "2017-02-21T09:12:04+00:00" }, { "name": "symfony/finder", - "version": "v3.2.3", + "version": "v3.2.7", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "8c71141cae8e2957946b403cc71a67213c0380d6" + "reference": "b20900ce5ea164cd9314af52725b0bb5a758217a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/8c71141cae8e2957946b403cc71a67213c0380d6", - "reference": "8c71141cae8e2957946b403cc71a67213c0380d6", + "url": "https://api.github.com/repos/symfony/finder/zipball/b20900ce5ea164cd9314af52725b0bb5a758217a", + "reference": "b20900ce5ea164cd9314af52725b0bb5a758217a", "shasum": "" }, "require": { @@ -3124,20 +3189,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2017-01-02 20:32:22" + "time": "2017-03-20T09:32:19+00:00" }, { "name": "symfony/process", - "version": "v3.2.3", + "version": "v3.2.7", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "32646a7cf53f3956c76dcb5c82555224ae321858" + "reference": "57fdaa55827ae14d617550ebe71a820f0a5e2282" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/32646a7cf53f3956c76dcb5c82555224ae321858", - "reference": "32646a7cf53f3956c76dcb5c82555224ae321858", + "url": "https://api.github.com/repos/symfony/process/zipball/57fdaa55827ae14d617550ebe71a820f0a5e2282", + "reference": "57fdaa55827ae14d617550ebe71a820f0a5e2282", "shasum": "" }, "require": { @@ -3173,7 +3238,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2017-02-03 12:11:38" + "time": "2017-03-27T18:07:02+00:00" }, { "name": "webmozart/assert", @@ -3223,22 +3288,12 @@ "check", "validate" ], - "time": "2016-11-23 20:04:58" - } - ], - "aliases": [ - { - "alias": "1.6.0", - "alias_normalized": "1.6.0.0", - "version": "9999999-dev", - "package": "erusev/parsedown" + "time": "2016-11-23T20:04:58+00:00" } ], + "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "erusev/parsedown": 20, - "gregwar/image": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/system/blueprints/config/site.yaml b/system/blueprints/config/site.yaml index fe783f084..57fd3c57a 100644 --- a/system/blueprints/config/site.yaml +++ b/system/blueprints/config/site.yaml @@ -19,7 +19,7 @@ form: default_lang: type: text label: PLUGIN_ADMIN.SITE_DEFAULT_LANG - size: vsmall + size: x-small placeholder: PLUGIN_ADMIN.SITE_DEFAULT_LANG_PLACEHOLDER help: PLUGIN_ADMIN.SITE_DEFAULT_LANG_HELP diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml index 03f6b898e..4a7f69849 100644 --- a/system/blueprints/config/system.yaml +++ b/system/blueprints/config/system.yaml @@ -102,7 +102,7 @@ form: pages.order.by: type: select - size: long + size: large classes: fancy label: PLUGIN_ADMIN.DEFAULT_ORDERING help: PLUGIN_ADMIN.DEFAULT_ORDERING_HELP @@ -155,6 +155,7 @@ form: pages.append_url_extension: type: text + size: x-small placeholder: "e.g. .html" label: PLUGIN_ADMIN.APPEND_URL_EXT help: PLUGIN_ADMIN.APPEND_URL_EXT_HELP @@ -856,13 +857,12 @@ form: fields: images.default_image_quality: - type: text + type: range append: '%' label: PLUGIN_ADMIN.DEFAULT_IMAGE_QUALITY help: PLUGIN_ADMIN.DEFAULT_IMAGE_QUALITY_HELP classes: x-small validate: - type: number min: 1 max: 100 diff --git a/system/blueprints/pages/default.yaml b/system/blueprints/pages/default.yaml index 4b96ac6a2..929a067c3 100644 --- a/system/blueprints/pages/default.yaml +++ b/system/blueprints/pages/default.yaml @@ -117,17 +117,6 @@ form: title: PLUGIN_ADMIN.SETTINGS underline: true - ordering: - type: toggle - label: PLUGIN_ADMIN.FOLDER_NUMERIC_PREFIX - help: PLUGIN_ADMIN.FOLDER_NUMERIC_PREFIX_HELP - highlight: 1 - options: - 1: PLUGIN_ADMIN.ENABLED - 0: PLUGIN_ADMIN.DISABLED - validate: - type: bool - folder: type: text label: PLUGIN_ADMIN.FOLDER_NAME @@ -135,13 +124,9 @@ form: rule: slug route: - type: select + type: parents label: PLUGIN_ADMIN.PARENT classes: fancy - data-options@: '\Grav\Common\Page\Pages::parentsRawRoutes' - data-default@: '\Grav\Plugin\Admin\Admin::rawRoute' - options: - '/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT name: type: select @@ -165,9 +150,20 @@ form: title: PLUGIN_ADMIN.ORDERING underline: true + ordering: + type: toggle + label: PLUGIN_ADMIN.FOLDER_NUMERIC_PREFIX + help: PLUGIN_ADMIN.FOLDER_NUMERIC_PREFIX_HELP + highlight: 1 + options: + 1: PLUGIN_ADMIN.ENABLED + 0: PLUGIN_ADMIN.DISABLED + validate: + type: bool + order: type: order - label: PLUGIN_ADMIN.PAGE_ORDER + label: PLUGIN_ADMIN.SORTABLE_PAGES sitemap: overrides: @@ -291,6 +287,18 @@ form: validate: type: bool + header.debugger: + type: toggle + toggleable: true + label: PLUGIN_ADMIN.DEBUGGER + help: PLUGIN_ADMIN.DEBUGGER_HELP + highlight: 1 + options: + 1: PLUGIN_ADMIN.ENABLED + 0: PLUGIN_ADMIN.DISABLED + validate: + type: bool + header.template: type: text toggleable: true @@ -302,6 +310,25 @@ form: toggleable: true help: PLUGIN_ADMIN.APPEND_URL_EXT_HELP + admin_only: + type: section + title: PLUGIN_ADMIN.ADMIN_SPECIFIC_OVERRIDES + underline: true + + fields: + + header.admin.children_display_order: + type: select + label: PLUGIN_ADMIN.ADMIN_CHILDREN_DISPLAY_ORDER + help: PLUGIN_ADMIN.ADMIN_CHILDREN_DISPLAY_ORDER_HELP + toggleable: true + classes: fancy + default: 'collection' + options: + 'default': 'Ordered by Folder name (default)' + 'collection': 'Ordered by Collection definition' + + header.order_by: type: hidden diff --git a/system/blueprints/pages/modular_new.yaml b/system/blueprints/pages/modular_new.yaml deleted file mode 100644 index 966b5cbd4..000000000 --- a/system/blueprints/pages/modular_new.yaml +++ /dev/null @@ -1,54 +0,0 @@ -rules: - slug: - pattern: '[a-zA-Zа-яA-Я0-9_\-]+' - min: 1 - max: 200 - -form: - validation: loose - fields: - - section: - type: section - title: PLUGIN_ADMIN.ADD_MODULAR_CONTENT - - title: - type: text - label: PLUGIN_ADMIN.PAGE_TITLE - validate: - required: true - - folder: - type: text - label: PLUGIN_ADMIN.FOLDER_NAME - validate: - rule: slug - required: true - - route: - type: select - label: PLUGIN_ADMIN.PAGE - classes: fancy - data-options@: '\Grav\Common\Page\Pages::parentsRawRoutes' - data-default@: '\Grav\Plugin\Admin\Admin::rawRoute' - validate: - required: true - - name: - type: select - classes: fancy - label: PLUGIN_ADMIN.MODULAR_TEMPLATE - help: PLUGIN_ADMIN.PAGE_FILE_HELP - default: default - data-options@: '\Grav\Common\Page\Pages::modularTypes' - validate: - required: true - - modular: - type: hidden - default: 1 - validate: - type: bool - - blueprint: - type: blueprint diff --git a/system/blueprints/pages/modular_raw.yaml b/system/blueprints/pages/modular_raw.yaml deleted file mode 100644 index 110866677..000000000 --- a/system/blueprints/pages/modular_raw.yaml +++ /dev/null @@ -1,106 +0,0 @@ -rules: - slug: - pattern: '[a-zA-Zа-яA-Я0-9_\-]+' - min: 1 - max: 200 - -form: - validation: loose - fields: - - tabs: - type: tabs - active: 1 - - fields: - content: - type: tab - title: PLUGIN_ADMIN.CONTENT - - fields: - frontmatter: - classes: frontmatter - type: editor - label: PLUGIN_ADMIN.FRONTMATTER - autofocus: true - codemirror: - mode: 'yaml' - indentUnit: 4 - autofocus: true - indentWithTabs: false - lineNumbers: true - styleActiveLine: true - gutters: ['CodeMirror-lint-markers'] - lint: true - - content: - type: markdown - - uploads: - type: pagemedia - label: PLUGIN_ADMIN.PAGE_MEDIA - - - options: - type: tab - title: PLUGIN_ADMIN.OPTIONS - - fields: - - columns: - type: columns - - fields: - column1: - type: column - - fields: - - ordering: - type: toggle - label: PLUGIN_ADMIN.FOLDER_NUMERIC_PREFIX - help: PLUGIN_ADMIN.FOLDER_NUMERIC_PREFIX_HELP - highlight: 1 - options: - 1: PLUGIN_ADMIN.ENABLED - 0: PLUGIN_ADMIN.DISABLED - validate: - type: bool - - folder: - type: text - label: PLUGIN_ADMIN.FILENAME - validate: - rule: slug - required: true - - route: - type: select - label: PLUGIN_ADMIN.PARENT - classes: fancy - data-options@: '\Grav\Common\Page\Pages::parentsRawRoutes' - data-default@: '\Grav\Plugin\Admin\Admin::rawRoute' - options: - '': PLUGIN_ADMIN.DEFAULT_OPTION_SELECT - validate: - required: true - - name: - type: select - classes: fancy - label: PLUGIN_ADMIN.MODULAR_TEMPLATE - default: default - data-options@: '\Grav\Common\Page\Pages::modularTypes' - validate: - required: true - - column2: - type: column - - fields: - order: - type: order - label: PLUGIN_ADMIN.ORDERING - - blueprint: - type: blueprint diff --git a/system/blueprints/pages/move.yaml b/system/blueprints/pages/move.yaml deleted file mode 100644 index 3f9eda1f7..000000000 --- a/system/blueprints/pages/move.yaml +++ /dev/null @@ -1,11 +0,0 @@ -form: - validation: loose - fields: - route: - type: select - label: PLUGIN_ADMIN.PARENT - classes: fancy - data-options@: '\Grav\Common\Page\Pages::parentsRawRoutes' - 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 deleted file mode 100644 index 78c7cecb6..000000000 --- a/system/blueprints/pages/new.yaml +++ /dev/null @@ -1,66 +0,0 @@ -rules: - slug: - pattern: '[a-zA-Zа-яA-Я0-9_\-]+' - min: 1 - max: 200 - -form: - validation: loose - fields: - - section: - type: section - title: PLUGIN_ADMIN.ADD_PAGE - - title: - type: text - label: PLUGIN_ADMIN.PAGE_TITLE - help: PLUGIN_ADMIN.PAGE_TITLE_HELP - validate: - required: true - - folder: - type: text - label: PLUGIN_ADMIN.FOLDER_NAME - help: PLUGIN_ADMIN.FOLDER_NAME_HELP - validate: - rule: slug - required: true - - route: - type: select - label: PLUGIN_ADMIN.PARENT_PAGE - classes: fancy - data-options@: '\Grav\Common\Page\Pages::parentsRawRoutes' - data-default@: '\Grav\Plugin\Admin\Admin::getLastPageRoute' - options: - '/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT - validate: - required: true - - name: - type: select - classes: fancy - label: PLUGIN_ADMIN.PAGE_FILE - help: PLUGIN_ADMIN.PAGE_FILE_HELP - data-options@: '\Grav\Common\Page\Pages::types' - data-default@: '\Grav\Plugin\Admin\Admin::getLastPageName' - validate: - required: true - - visible: - type: toggle - label: PLUGIN_ADMIN.VISIBLE - help: PLUGIN_ADMIN.VISIBLE_HELP - highlight: '' - default: '' - options: - '': Auto - 1: PLUGIN_ADMIN.YES - 0: PLUGIN_ADMIN.NO - validate: - type: bool - required: true - - blueprint: - type: blueprint diff --git a/system/blueprints/pages/new_folder.yaml b/system/blueprints/pages/new_folder.yaml deleted file mode 100644 index 44d53fc8c..000000000 --- a/system/blueprints/pages/new_folder.yaml +++ /dev/null @@ -1,35 +0,0 @@ -rules: - slug: - pattern: '[a-zA-Zа-яA-Я0-9_\-]+' - min: 1 - max: 200 - -form: - validation: loose - fields: - - section: - type: section - title: PLUGIN_ADMIN.ADD_FOLDER - - folder: - type: text - label: PLUGIN_ADMIN.FOLDER_NAME - help: PLUGIN_ADMIN.FOLDER_NAME_HELP - validate: - rule: slug - required: true - - route: - type: select - label: PLUGIN_ADMIN.PARENT_PAGE - classes: fancy - data-options@: '\Grav\Common\Page\Pages::parentsRawRoutes' - data-default@: '\Grav\Plugin\Admin\Admin::getLastPageRoute' - options: - '/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT - validate: - required: true - - blueprint: - type: blueprint diff --git a/system/blueprints/pages/raw.yaml b/system/blueprints/pages/raw.yaml deleted file mode 100644 index f61cf95f6..000000000 --- a/system/blueprints/pages/raw.yaml +++ /dev/null @@ -1,105 +0,0 @@ -rules: - slug: - pattern: '[a-zA-Zа-яA-Я0-9_\-]+' - min: 1 - max: 200 - -form: - validation: loose - fields: - - tabs: - type: tabs - active: 1 - - fields: - content: - type: tab - title: PLUGIN_ADMIN.CONTENT - - fields: - frontmatter: - classes: frontmatter - type: editor - label: PLUGIN_ADMIN.FRONTMATTER - autofocus: true - codemirror: - mode: 'yaml' - indentUnit: 4 - autofocus: true - indentWithTabs: false - lineNumbers: true - styleActiveLine: true - gutters: ['CodeMirror-lint-markers'] - lint: true - - content: - type: markdown - - uploads: - type: pagemedia - label: PLUGIN_ADMIN.PAGE_MEDIA - - options: - type: tab - title: PLUGIN_ADMIN.OPTIONS - - fields: - - columns: - type: columns - - fields: - column1: - type: column - - fields: - - ordering: - type: toggle - label: PLUGIN_ADMIN.FOLDER_NUMERIC_PREFIX - help: PLUGIN_ADMIN.FOLDER_NUMERIC_PREFIX_HELP - highlight: 1 - options: - 1: PLUGIN_ADMIN.ENABLED - 0: PLUGIN_ADMIN.DISABLED - validate: - type: bool - - folder: - type: text - label: PLUGIN_ADMIN.FOLDER_NAME - help: PLUGIN_ADMIN.FOLDER_NAME_HELP - validate: - rule: slug - required: true - - route: - type: select - label: PLUGIN_ADMIN.PARENT - classes: fancy - data-options@: '\Grav\Common\Page\Pages::parentsRawRoutes' - data-default@: '\Grav\Plugin\Admin\Admin::rawRoute' - options: - '/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT - - name: - type: select - classes: fancy - label: PLUGIN_ADMIN.DISPLAY_TEMPLATE - help: PLUGIN_ADMIN.DISPLAY_TEMPLATE_HELP - default: default - data-options@: '\Grav\Common\Page\Pages::types' - validate: - required: true - - column2: - type: column - - fields: - order: - type: order - label: PLUGIN_ADMIN.ORDERING - - blueprint: - type: blueprint diff --git a/system/blueprints/user/account.yaml b/system/blueprints/user/account.yaml index ff657b4c4..7a7c82b57 100644 --- a/system/blueprints/user/account.yaml +++ b/system/blueprints/user/account.yaml @@ -8,6 +8,13 @@ form: type: userinfo size: large + avatar: + type: file + size: large + destination: 'user://accounts/avatars' + multiple: false + random_name: true + content: type: section title: PLUGIN_ADMIN.ACCOUNT diff --git a/system/defines.php b/system/defines.php index 387435b35..fb565e9ec 100644 --- a/system/defines.php +++ b/system/defines.php @@ -8,7 +8,7 @@ // Some standard defines define('GRAV', true); -define('GRAV_VERSION', '1.1.17'); +define('GRAV_VERSION', '1.2.2'); define('GRAV_TESTING', false); define('DS', '/'); diff --git a/system/src/Grav/Common/Assets.php b/system/src/Grav/Common/Assets.php index eeb3adabf..12efc1ae3 100644 --- a/system/src/Grav/Common/Assets.php +++ b/system/src/Grav/Common/Assets.php @@ -255,28 +255,32 @@ class Assets } /** - * Add a CSS asset. + * Add an asset to its assembly. * * It checks for duplicates. * You may add more than one asset passing an array as argument. + * The third argument may alternatively contain an array of options which take precedence over positional + * arguments. * - * @param mixed $asset - * @param int $priority the priority, bigger comes first - * @param bool $pipeline false if this should not be pipelined - * @param null $group + * @param array $assembly the array assembling the assets + * @param mixed $asset + * @param int $priority the priority, bigger comes first + * @param bool $pipeline false if this should not be pipelined + * @param string $loading how the asset is loaded (async/defer/inline, for CSS: only inline) + * @param string $group name of the group * * @return $this */ - public function addCss($asset, $priority = null, $pipeline = true, $group = null) + public function addTo(&$assembly, $asset, $priority = null, $pipeline = true, $loading = null, $group = null) { if (is_array($asset)) { foreach ($asset as $a) { - $this->addCss($a, $priority, $pipeline, $group); + $this->addTo($assembly, $a, $priority, $pipeline, $loading, $group); } return $this; } elseif (isset($this->collections[$asset])) { - $this->addCss($this->collections[$asset], $priority, $pipeline, $group); + $this->addTo($assembly, $this->collections[$asset], $priority, $pipeline, $loading, $group); return $this; } @@ -297,15 +301,16 @@ class Assets 'asset' => $asset, 'remote' => $remote, 'priority' => intval($priority ?: 10), - 'order' => count($this->css), + 'order' => count($assembly), 'pipeline' => (bool) $pipeline, + 'loading' => $loading ?: '', 'group' => $group ?: 'head', 'modified' => $modified ]; // check for dynamic array and merge with defaults - if (func_num_args() > 1) { - $dynamic_arg = func_get_arg(1); + if (func_num_args() > 2) { + $dynamic_arg = func_get_arg(2); if (is_array($dynamic_arg)) { $data = array_merge($data, $dynamic_arg); } @@ -313,17 +318,40 @@ class Assets $key = md5($asset); if ($asset) { - $this->css[$key] = $data; + $assembly[$key] = $data; } return $this; } + /** + * Add a CSS asset. + * + * It checks for duplicates. + * You may add more than one asset passing an array as argument. + * The second argument may alternatively contain an array of options which take precedence over positional + * arguments. + * + * @param mixed $asset + * @param int $priority the priority, bigger comes first + * @param bool $pipeline false if this should not be pipelined + * @param string $group + * @param string $loading how the asset is loaded (async/defer/inline, for CSS: only inline) + * + * @return $this + */ + public function addCss($asset, $priority = null, $pipeline = true, $group = null, $loading = null) + { + return $this->addTo($this->css, $asset, $priority, $pipeline, $loading, $group); + } + /** * Add a JavaScript asset. * * It checks for duplicates. * You may add more than one asset passing an array as argument. + * The second argument may alternatively contain an array of options which take precedence over positional + * arguments. * * @param mixed $asset * @param int $priority the priority, bigger comes first @@ -335,55 +363,7 @@ class Assets */ public function addJs($asset, $priority = null, $pipeline = true, $loading = null, $group = null) { - if (is_array($asset)) { - foreach ($asset as $a) { - $this->addJs($a, $priority, $pipeline, $loading, $group); - } - - return $this; - } elseif (isset($this->collections[$asset])) { - $this->addJs($this->collections[$asset], $priority, $pipeline, $loading, $group); - - return $this; - } - - $modified = false; - $remote = $this->isRemoteLink($asset); - if (!$remote) { - $modified = $this->getLastModificationTime($asset); - $asset = $this->buildLocalLink($asset); - } - - // Check for existence - if ($asset === false) { - return $this; - } - - $data = [ - 'asset' => $asset, - 'remote' => $remote , - 'priority' => intval($priority ?: 10), - 'order' => count($this->js), - 'pipeline' => (bool) $pipeline, - 'loading' => $loading ?: '', - 'group' => $group ?: 'head', - 'modified' => $modified - ]; - - // check for dynamic array and merge with defaults - if (func_num_args() > 1) { - $dynamic_arg = func_get_arg(1); - if (is_array($dynamic_arg)) { - $data = array_merge($data, $dynamic_arg); - } - } - - $key = md5($asset); - if ($asset) { - $this->js[$key] = $data; - } - - return $this; + return $this->addTo($this->js, $asset, $priority, $pipeline, $loading, $group); } /** @@ -547,32 +527,54 @@ class Assets $this->css = array_reverse($this->css); $this->inline_css = array_reverse($this->inline_css); + $inlineGroup = array_key_exists('loading', $attributes) && $attributes['loading'] === 'inline'; + $attributes = $this->attributes(array_merge(['type' => 'text/css', 'rel' => 'stylesheet'], $attributes)); $output = ''; $inline_css = ''; if ($this->css_pipeline) { - $pipeline_result = $this->pipelineCss($group); - $pipeline_html = '' . "\n"; + $pipeline_result = $this->pipelineCss($group, !$inlineGroup); + $pipeline_html = ($inlineGroup ? '' : '' . "\n"); if ($this->css_pipeline_before_excludes && $pipeline_result) { - $output .= $pipeline_html; + if ($inlineGroup) { + $inline_css .= $pipeline_result; + } + else { + $output .= $pipeline_html; + } } foreach ($this->css_no_pipeline as $file) { if ($group && $file['group'] == $group) { - $media = isset($file['media']) ? sprintf(' media="%s"', $file['media']) : ''; - $output .= '' . "\n"; + if ($file['loading'] === 'inline') { + $inline_css .= $this->gatherLinks([$file], CSS_ASSET) . "\n"; + } + else { + $media = isset($file['media']) ? sprintf(' media="%s"', $file['media']) : ''; + $output .= '' . "\n"; + } } } if (!$this->css_pipeline_before_excludes && $pipeline_result) { - $output .= $pipeline_html; + if ($inlineGroup) { + $inline_css .= $pipeline_result; + } + else { + $output .= $pipeline_html; + } } } else { foreach ($this->css as $file) { if ($group && $file['group'] == $group) { - $media = isset($file['media']) ? sprintf(' media="%s"', $file['media']) : ''; - $output .= '' . "\n"; + if ($inlineGroup || $file['loading'] === 'inline') { + $inline_css .= $this->gatherLinks([$file], CSS_ASSET) . "\n"; + } + else { + $media = isset($file['media']) ? sprintf(' media="%s"', $file['media']) : ''; + $output .= '' . "\n"; + } } } } @@ -626,30 +628,52 @@ class Assets $this->js = array_reverse($this->js); $this->inline_js = array_reverse($this->inline_js); + $inlineGroup = array_key_exists('loading', $attributes) && $attributes['loading'] === 'inline'; + $attributes = $this->attributes(array_merge(['type' => 'text/javascript'], $attributes)); $output = ''; $inline_js = ''; if ($this->js_pipeline) { - $pipeline_result = $this->pipelineJs($group); - $pipeline_html = '' . "\n"; + $pipeline_result = $this->pipelineJs($group, !$inlineGroup); + $pipeline_html = ($inlineGroup ? '' : '' . "\n"); if ($this->js_pipeline_before_excludes && $pipeline_result) { - $output .= $pipeline_html; + if ($inlineGroup) { + $inline_js .= $pipeline_result; + } + else { + $output .= $pipeline_html; + } } foreach ($this->js_no_pipeline as $file) { if ($group && $file['group'] == $group) { - $output .= '' . "\n"; + if ($file['loading'] === 'inline') { + $inline_js .= $this->gatherLinks([$file], JS_ASSET) . "\n"; + } + else { + $output .= '' . "\n"; + } } } if (!$this->js_pipeline_before_excludes && $pipeline_result) { - $output .= $pipeline_html; + if ($inlineGroup) { + $inline_js .= $pipeline_result; + } + else { + $output .= $pipeline_html; + } } } else { foreach ($this->js as $file) { if ($group && $file['group'] == $group) { - $output .= '' . "\n"; + if ($inlineGroup || $file['loading'] === 'inline') { + $inline_js .= $this->gatherLinks([$file], JS_ASSET) . "\n"; + } + else { + $output .= '' . "\n"; + } } } } @@ -672,10 +696,11 @@ class Assets * Minify and concatenate CSS * * @param string $group + * @param bool $returnURL true if pipeline should return the URL, otherwise the content * - * @return bool|string + * @return bool|string URL or generated content if available, else false */ - protected function pipelineCss($group = 'head') + protected function pipelineCss($group = 'head', $returnURL = true) { // temporary list of assets to pipeline $temp_css = []; @@ -695,9 +720,14 @@ class Assets $this->css_no_pipeline = json_decode(file_get_contents($this->assets_dir . $inline_file), true); } - // If pipeline exist return it + // If pipeline exist return its URL or content if (file_exists($this->assets_dir . $file)) { - return $relative_path . $this->getTimestamp(); + if ($returnURL) { + return $relative_path . $this->getTimestamp(); + } + else { + return file_get_contents($this->assets_dir . $file) . "\n"; + } } // Remove any non-pipeline files @@ -744,7 +774,12 @@ class Assets if (strlen(trim($buffer)) > 0) { file_put_contents($this->assets_dir . $file, $buffer); - return $relative_path . $this->getTimestamp(); + if ($returnURL) { + return $relative_path . $this->getTimestamp(); + } + else { + return $buffer . "\n"; + } } else { return false; } @@ -754,10 +789,11 @@ class Assets * Minify and concatenate JS files. * * @param string $group + * @param bool $returnURL true if pipeline should return the URL, otherwise the content * - * @return string + * @return bool|string URL or generated content if available, else false */ - protected function pipelineJs($group = 'head') + protected function pipelineJs($group = 'head', $returnURL = true) { // temporary list of assets to pipeline $temp_js = []; @@ -777,9 +813,14 @@ class Assets $this->js_no_pipeline = json_decode(file_get_contents($this->assets_dir . $inline_file), true); } - // If pipeline exist return it + // If pipeline exist return its URL or content if (file_exists($this->assets_dir . $file)) { - return $relative_path . $this->getTimestamp(); + if ($returnURL) { + return $relative_path . $this->getTimestamp(); + } + else { + return file_get_contents($this->assets_dir . $file) . "\n"; + } } // Remove any non-pipeline files @@ -816,7 +857,12 @@ class Assets if (strlen(trim($buffer)) > 0) { file_put_contents($this->assets_dir . $file, $buffer); - return $relative_path . $this->getTimestamp(); + if ($returnURL) { + return $relative_path . $this->getTimestamp(); + } + else { + return $buffer . "\n"; + } } else { return false; } @@ -1255,13 +1301,8 @@ class Assets $old_url = $matches[2]; - // ensure this is not a data url - if (strpos($old_url, 'data:') === 0) { - return $matches[0]; - } - - // ensure this is not a remote url - if ($this->isRemoteLink($old_url)) { + // Ensure link is not rooted to webserver, a data URL, or to a remote host + if (Utils::startsWith($old_url, '/') || Utils::startsWith($old_url, 'data:') || $this->isRemoteLink($old_url)) { return $matches[0]; } diff --git a/system/src/Grav/Common/GPM/GPM.php b/system/src/Grav/Common/GPM/GPM.php index 584adbdd7..99ce448ee 100644 --- a/system/src/Grav/Common/GPM/GPM.php +++ b/system/src/Grav/Common/GPM/GPM.php @@ -599,9 +599,11 @@ class GPM extends Iterator */ public static function getPackageName($source) { + $ignore_yaml_files = ['blueprints', 'languages']; + foreach (glob($source . "*.yaml") as $filename) { $name = strtolower(basename($filename, '.yaml')); - if ($name == 'blueprints') { + if (in_array($name, $ignore_yaml_files)) { continue; } return $name; diff --git a/system/src/Grav/Common/Language/Language.php b/system/src/Grav/Common/Language/Language.php index a8363816e..dbf2b95ba 100644 --- a/system/src/Grav/Common/Language/Language.php +++ b/system/src/Grav/Common/Language/Language.php @@ -203,6 +203,15 @@ class Language } } + // repeat if not found, try base language only - fixes Safari sending the language code always + // with a locale (e.g. it-it or fr-fr) + foreach ($preferred as $lang) { + $lang = substr($lang, 0, 2); + if ($this->validate($lang)) { + $this->active = $lang; + break; + } + } } } } diff --git a/system/src/Grav/Common/Page/Media.php b/system/src/Grav/Common/Page/Media.php index eb12eeb1c..34396bff3 100644 --- a/system/src/Grav/Common/Page/Media.php +++ b/system/src/Grav/Common/Page/Media.php @@ -141,8 +141,12 @@ class Media extends AbstractMedia foreach ($types['alternative'] as $altMedium) { if ($altMedium['file'] != $medium) { - $ratio = $altMedium['file']->get('width') / $medium->get('width'); - $medium->addAlternative($ratio, $altMedium['file']); + $altWidth = $altMedium['file']->get('width'); + $medWidth = $medium->get('width'); + if ($altWidth && $medWidth) { + $ratio = $altWidth / $medWidth; + $medium->addAlternative($ratio, $altMedium['file']); + } } } } diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index d35aff821..695489942 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -86,6 +86,7 @@ class Page protected $hide_home_route; protected $ssl; protected $template_format; + protected $debugger; /** * @var Page Unmodified (original) version of the page. Used for copying and moving the page. @@ -424,6 +425,9 @@ class Page if (isset($this->header->template_format)) { $this->template_format = $this->header->template_format; } + if (isset($this->header->debugger)) { + $this->debugger = (bool)$this->header->debugger; + } } return $this->header; @@ -566,7 +570,8 @@ class Page $process_markdown = $this->shouldProcess('markdown'); - $process_twig = $this->shouldProcess('twig'); + $process_twig = $this->shouldProcess('twig') || $this->modularTwig() ; + $cache_enable = isset($this->header->cache_enable) ? $this->header->cache_enable : $config->get('system.cache.enabled', true); $twig_first = isset($this->header->twig_first) ? $this->header->twig_first : $config->get('system.pages.twig_first', @@ -799,6 +804,9 @@ class Page if ($name == 'folder') { return preg_replace(PAGE_ORDER_PREFIX_REGEX, '', $this->folder); } + if ($name == 'slug') { + return $this->slug(); + } if ($name == 'name') { $language = $this->language() ? '.' . $this->language() : ''; $name_val = str_replace($language . '.md', '', $this->name()); @@ -882,12 +890,12 @@ class Page /** * Save page if there's a file assigned to it. * - * @param bool $reorder Internal use. + * @param bool|mixed $reorder Internal use. */ public function save($reorder = true) { - // Perform move, copy or reordering if needed. - $this->doRelocation($reorder); + // Perform move, copy [or reordering] if needed. + $this->doRelocation(); $file = $this->file(); if ($file) { @@ -896,6 +904,13 @@ class Page $file->markdown($this->raw_content); $file->save(); } + + // Perform reorder if required + if ($reorder && is_array($reorder)) { + $this->doReorder($reorder); + } + + $this->_original = null; } /** @@ -1111,7 +1126,7 @@ class Page */ public function childType() { - return isset($this->header->child_type) ? (string)$this->header->child_type : 'default'; + return isset($this->header->child_type) ? (string)$this->header->child_type : ''; } /** @@ -1373,6 +1388,20 @@ class Page return $this->process; } + /** + * Returns the state of the debugger override etting for this page + * + * @return mixed + */ + public function debugger() + { + if (isset($this->debugger) && $this->debugger === false) { + return false; + } else { + return true; + } + } + /** * Function to merge page metadata tags and build an array of Metadata objects * that can then be rendered in the page. @@ -2027,7 +2056,6 @@ class Page if ($var !== null) { $this->modular_twig = (bool)$var; if ($var) { - $this->process['twig'] = true; $this->visible(false); // some routable logic if (empty($this->header->routable)) { @@ -2254,6 +2282,74 @@ class Page } } + /** + * Helper method to return an ancestor page. + * + * @param string $url The url of the page + * @param bool $lookup Name of the parent folder + * + * @return \Grav\Common\Page\Page page you were looking for if it exists + */ + public function ancestor($lookup = null) + { + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + + return $pages->ancestor($this->route, $lookup); + } + + /** + * Helper method to return an ancestor page to inherit from. The current + * page object is returned. + * + * @param string $field Name of the parent folder + * + * @return Page + */ + public function inherited($field) + { + list($inherited, $currentParams) = $this->getInheritedParams($field); + + $this->modifyHeader($field, $currentParams); + + return $inherited; + } + /** + * Helper method to return an ancestor field only to inherit from. The + * first occurrence of an ancestor field will be returned if at all. + * + * @param string $field Name of the parent folder + * + * @return array + */ + public function inheritedField($field) + { + list($inherited, $currentParams) = $this->getInheritedParams($field); + + return $currentParams; + } + + /** + * Method that contains shared logic for inherited() and inheritedField() + * + * @param string $field Name of the parent folder + * + * @return array + */ + protected function getInheritedParams($field) + { + $pages = Grav::instance()['pages']; + + /** @var Pages $pages */ + $inherited = $pages->inherited($this->route, $field); + $inheritedParams = (array) $inherited->value('header.' . $field); + $currentParams = (array) $this->value('header.' . $field); + if($inheritedParams && is_array($inheritedParams)) { + $currentParams = array_replace_recursive($inheritedParams, $currentParams); + } + return [$inherited, $currentParams]; + } + /** * Helper method to return a page. * @@ -2588,65 +2684,62 @@ class Page } /** - * Moves or copies the page in filesystem. + * Reorders all siblings according to a defined order * - * @internal - * - * @param bool $reorder - * - * @throws Exception + * @param $new_order */ - protected function doRelocation($reorder) + protected function doReorder($new_order) { if (!$this->_original) { return; } - // Do reordering. - if ($reorder && $this->order() != $this->_original->order()) { - /** @var Pages $pages */ - $pages = Grav::instance()['pages']; + $pages = Grav::instance()['pages']; + $pages->init(); - $parent = $this->parent(); + $this->_original->path($this->path()); - // Extract visible children from the parent page. - $list = []; - /** @var Page $page */ - foreach ($parent->children()->visible() as $page) { - if ($page->order()) { - $list[$page->slug] = $page->path(); - } - } + $siblings = $this->parent()->children(); + $siblings->order('slug', 'asc', $new_order); - // If page was moved, take it out of the list. - if ($this->_action == 'move') { - unset($list[$this->slug()]); - } + $counter = 0; - $list = array_values($list); + // Reorder all moved pages. + foreach ($siblings as $slug => $page) { + $order = intval(trim($page->order(),'.')); + $counter++; - // Then add it back to the new location (if needed). - if ($this->order()) { - array_splice($list, min($this->order() - 1, count($list)), 0, [$this->path()]); - } - - // Reorder all moved pages. - foreach ($list as $order => $path) { - if ($path == $this->path()) { + if ($order) { + if ($page->path() == $this->path() && $this->folderExists()) { // Handle current page; we do want to change ordering number, but nothing else. - $this->order($order + 1); + $this->order($counter); + $this->save(false); } else { // Handle all the other pages. - $page = $pages->get($path); - - if ($page && $page->exists() && !$page->_action && $page->order() != $order + 1) { - $page = $page->move($parent); - $page->order($order + 1); + $page = $pages->get($page->path()); + if ($page && $page->folderExists() && !$page->_action) { + $page = $page->move($this->parent()); + $page->order($counter); $page->save(false); } } } } + } + + /** + * Moves or copies the page in filesystem. + * + * @internal + * + * @throws Exception + */ + protected function doRelocation() + { + if (!$this->_original) { + return; + } + if (is_dir($this->_original->path())) { if ($this->_action == 'move') { Folder::move($this->_original->path(), $this->path()); @@ -2662,7 +2755,6 @@ class Page } } - $this->_original = null; } protected function setPublishState() diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 4e8614aec..ab8825538 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -291,36 +291,86 @@ class Pages return new Collection($children, [], $this); } + /** + * Get a page ancestor. + * + * @param string $route The relative URL of the page + * @param string $path The relative path of the ancestor folder + * + * @return Page|null + */ + public function ancestor($route, $path = null) + { + if (!is_null($path)) { + + $page = $this->dispatch($route, true); + + if ($page->path() == $path) { + return $page; + } elseif (!$page->parent()->root()) { + return $this->ancestor($page->parent()->route(), $path); + } + } + + return null; + } + + /** + * Get a page ancestor trait. + * + * @param string $route The relative route of the page + * @param string $field The field name of the ancestor to query for + * + * @return Page|null + */ + public function inherited($route, $field = null) + { + if (!is_null($field)) { + + $page = $this->dispatch($route, true); + + $ancestorField = $page->parent()->value('header.' . $field); + + if ($ancestorField != null) { + return $page->parent(); + } elseif (!$page->parent()->root()) { + return $this->inherited($page->parent()->route(), $field); + } + } + + return null; + } + /** * alias method to return find a page. * - * @param string $url The relative URL of the page + * @param string $route The relative URL of the page * @param bool $all * * @return Page|null */ - public function find($url, $all = false) + public function find($route, $all = false) { - return $this->dispatch($url, $all, false); + return $this->dispatch($route, $all, false); } /** * Dispatch URI to a page. * - * @param string $url The relative URL of the page + * @param string $route The relative URL of the page * @param bool $all * * @param bool $redirect * @return Page|null * @throws \Exception */ - public function dispatch($url, $all = false, $redirect = true) + public function dispatch($route, $all = false, $redirect = true) { // Fetch page if there's a defined route to it. - $page = isset($this->routes[$url]) ? $this->get($this->routes[$url]) : null; + $page = isset($this->routes[$route]) ? $this->get($this->routes[$route]) : null; // Try without trailing slash - if (!$page && Utils::endsWith($url, '/')) { - $page = isset($this->routes[rtrim($url, '/')]) ? $this->get($this->routes[rtrim($url, '/')]) : null; + if (!$page && Utils::endsWith($route, '/')) { + $page = isset($this->routes[rtrim($route, '/')]) ? $this->get($this->routes[rtrim($route, '/')]) : null; } // Are we in the admin? this is important! @@ -340,13 +390,13 @@ class Pages $config = $this->grav['config']; // See if route matches one in the site configuration - $route = $config->get("site.routes.{$url}"); - if ($route) { - $page = $this->dispatch($route, $all); + $site_route = $config->get("site.routes.{$route}"); + if ($site_route) { + $page = $this->dispatch($site_route, $all); } else { // Try Regex style redirects $uri = $this->grav['uri']; - $source_url = $url; + $source_url = $route; $extension = $uri->extension(); if (isset($extension) && !Utils::endsWith($uri->url(), $extension)) { $source_url.= '.' . $extension; diff --git a/system/src/Grav/Common/Service/PageServiceProvider.php b/system/src/Grav/Common/Service/PageServiceProvider.php index 0db18a298..a363411a1 100644 --- a/system/src/Grav/Common/Service/PageServiceProvider.php +++ b/system/src/Grav/Common/Service/PageServiceProvider.php @@ -39,6 +39,11 @@ class PageServiceProvider implements ServiceProviderInterface /** @var Language $language */ $language = $c['language']; + // some debugger override logic + if ($page->debugger() === false) { + Grav::instance()['debugger']->enabled(false); + } + if ($c['config']->get('system.force_ssl')) { if (!isset($_SERVER['HTTPS']) || $_SERVER["HTTPS"] != "on") { $url = "https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]; diff --git a/system/src/Grav/Common/Themes.php b/system/src/Grav/Common/Themes.php index e1db8d7db..4ce6162b7 100644 --- a/system/src/Grav/Common/Themes.php +++ b/system/src/Grav/Common/Themes.php @@ -311,17 +311,23 @@ class Themes extends Iterator */ protected function autoloadTheme($class) { - /** @var UniformResourceLocator $locator */ - $locator = $this->grav['locator']; - $prefix = "Grav\\Theme"; if (false !== strpos($class, $prefix)) { // Remove prefix from class $class = substr($class, strlen($prefix)); - // Replace namespace tokens to directory separators + // Try Old style theme classes $path = strtolower(ltrim(preg_replace('#\\\|_(?!.+\\\)#', '/', $class), '/')); - $file = $locator->findResource("themes://{$path}/{$path}.php"); + $file = $this->grav['locator']->findResource("themes://{$path}/{$path}.php"); + + // Load class + if (file_exists($file)) { + return include_once($file); + } + + // Replace namespace tokens to directory separators + $path = $this->grav['inflector']->hyphenize(ltrim($class,"\\")); + $file = $this->grav['locator']->findResource("themes://{$path}/{$path}.php"); // Load class if (file_exists($file)) { diff --git a/system/src/Grav/Common/Twig/Twig.php b/system/src/Grav/Common/Twig/Twig.php index 9ef9e3e6d..7eec5b775 100644 --- a/system/src/Grav/Common/Twig/Twig.php +++ b/system/src/Grav/Common/Twig/Twig.php @@ -11,6 +11,7 @@ namespace Grav\Common\Twig; use Grav\Common\Grav; use Grav\Common\Config\Config; use Grav\Common\Language\Language; +use Grav\Common\Language\LanguageCodes; use Grav\Common\Page\Page; use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; use RocketTheme\Toolbox\Event\Event; @@ -173,7 +174,7 @@ class Twig 'theme_dir' => $locator->findResource('theme://'), 'theme_url' => $this->grav['base_url'] . '/' . $locator->findResource('theme://', false), 'html_lang' => $this->grav['language']->getActive() ?: $config->get('site.default_lang', 'en'), - + 'language_codes' => new LanguageCodes, ]; } } @@ -229,25 +230,22 @@ class Twig $twig_vars['header'] = $item->header(); $local_twig = clone($this->twig); - $modular_twig = $item->modularTwig(); - $process_twig = isset($item->header()->process['twig']) ? $item->header()->process['twig'] : false; - - $output = ''; try { // Process Modular Twig - if ($modular_twig) { + if ($item->modularTwig()) { $twig_vars['content'] = $content; $template = $item->template() . TEMPLATE_EXT; $output = $content = $local_twig->render($template, $twig_vars); } // Process in-page Twig - if (!$modular_twig || ($modular_twig && $process_twig)) { + if ($item->shouldProcess('twig')) { $name = '@Page:' . $item->path(); $this->setTemplate($name, $content); $output = $local_twig->render($name, $twig_vars); } + } catch (\Twig_Error_Loader $e) { throw new \RuntimeException($e->getRawMessage(), 404, $e); } diff --git a/system/src/Grav/Common/Twig/TwigExtension.php b/system/src/Grav/Common/Twig/TwigExtension.php index 6b3f0b1dc..eff3e53fd 100644 --- a/system/src/Grav/Common/Twig/TwigExtension.php +++ b/system/src/Grav/Common/Twig/TwigExtension.php @@ -104,7 +104,8 @@ class TwigExtension extends \Twig_Extension new \Twig_simpleFunction('authorize', [$this, 'authorize']), new \Twig_SimpleFunction('debug', [$this, 'dump'], ['needs_context' => true, 'needs_environment' => true]), new \Twig_SimpleFunction('dump', [$this, 'dump'], ['needs_context' => true, 'needs_environment' => true]), - new \Twig_SimpleFunction('evaluate', [$this, 'evaluateFunc']), + new \Twig_SimpleFunction('evaluate', [$this, 'evaluateStringFunc'], ['needs_context' => true, 'needs_environment' => true]), + new \Twig_SimpleFunction('evaluate_twig', [$this, 'evaluateTwigFunc'], ['needs_context' => true, 'needs_environment' => true]), new \Twig_SimpleFunction('gist', [$this, 'gistFunc']), new \Twig_SimpleFunction('nonce_field', [$this, 'nonceFieldFunc']), new \Twig_simpleFunction('random_string', [$this, 'randomStringFunc']), @@ -118,6 +119,7 @@ class TwigExtension extends \Twig_Extension new \Twig_SimpleFunction('get_cookie', [$this, 'getCookie']), new \Twig_SimpleFunction('redirect_me', [$this, 'redirectFunc']), new \Twig_SimpleFunction('range', [$this, 'rangeFunc']), + new \Twig_SimpleFunction('isajaxrequest', [$this, 'isAjaxFunc']), ]; } @@ -569,15 +571,22 @@ class TwigExtension extends \Twig_Extension $domain = true; } + if (Grav::instance()['uri']->isExternal($input)) { + return $input; + } - if (strpos((string)$input, '://')) { + $input = ltrim((string)$input, '/'); + + if (Utils::contains((string)$input, '://')) { /** @var UniformResourceLocator $locator */ $locator = $this->grav['locator']; + + // Get relative path to the resource (or false if not found). - $resource = $locator->findResource((string)$input, false); + $resource = $locator->findResource($input, false); } else { - $resource = (string)$input; + $resource = $input; } /** @var Uri $uri */ @@ -587,22 +596,51 @@ class TwigExtension extends \Twig_Extension } /** - * Evaluate a string + * This function will evaluate Twig $twig through the $environment, and return its results. * - * @example {{ evaluate('grav.language.getLanguage') }} - * - * @param string $input String to be evaluated - * - * @return string Returns the evaluated string + * @param \Twig_Environment $environment + * @param array $context + * @param string $twig + * @return mixed */ - public function evaluateFunc($input) - { - if (!$input) { //prevent an obscure Twig error if $input is not set - $input = '""'; - } - return $this->grav['twig']->processString("{{ $input }}"); + public function evaluateTwigFunc( \Twig_Environment $environment, $context, $twig ) { + $loader = $environment->getLoader( ); + + $parsed = $this->parseString( $environment, $context, $twig ); + + $environment->setLoader( $loader ); + return $parsed; } + /** + * This function will evaluate a $string through the $environment, and return its results. + * + * @param \Twig_Environment $environment + * @param $context + * @param $string + * @return mixed + */ + public function evaluateStringFunc(\Twig_Environment $environment, $context, $string ) + { + $parsed = $this->evaluateTwigFunc($environment, $context, "{{ $string }}"); + return $parsed; + } + + /** + * Sets the parser for the environment to Twig_Loader_String, and parsed the string $string. + * + * @param \Twig_Environment $environment + * @param array $context + * @param string $string + * @return string + */ + protected function parseString( \Twig_Environment $environment, $context, $string ) { + $environment->setLoader( new \Twig_Loader_String( ) ); + return $environment->render( $string, $context ); + } + + + /** * Based on Twig_Extension_Debug / twig_var_dump * (c) 2011 Fabien Potencier @@ -855,4 +893,17 @@ class TwigExtension extends \Twig_Extension { return range($start, $end, $step); } + + /** + * Check if HTTP_X_REQUESTED_WITH has been set to xmlhttprequest, + * in which case we may unsafely assume ajax. Non critical use only. + * + * @return true if HTTP_X_REQUESTED_WITH exists and has been set to xmlhttprequest + */ + public function isAjaxFunc() + { + return ( + !empty($_SERVER['HTTP_X_REQUESTED_WITH']) + && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'); + } } diff --git a/system/src/Grav/Common/User/User.php b/system/src/Grav/Common/User/User.php index d5c108ff8..d0c35eb31 100644 --- a/system/src/Grav/Common/User/User.php +++ b/system/src/Grav/Common/User/User.php @@ -239,4 +239,20 @@ class User extends Data { return $this->authorize($action); } + + /** + * Return the User's avatar URL + * + * @return string + */ + public function avatarUrl() + { + if ($this->avatar) { + $avatar = $this->avatar; + $avatar = array_shift($avatar); + return Grav::instance()['base_url'] . '/' . $avatar['path']; + } else { + return 'https://www.gravatar.com/avatar/' . md5($this->email); + } + } } diff --git a/system/src/Grav/Console/Gpm/DirectInstallCommand.php b/system/src/Grav/Console/Gpm/DirectInstallCommand.php index 202840289..0b368cafe 100644 --- a/system/src/Grav/Console/Gpm/DirectInstallCommand.php +++ b/system/src/Grav/Console/Gpm/DirectInstallCommand.php @@ -15,6 +15,7 @@ use Grav\Common\GPM\Installer; use Grav\Common\GPM\Response; use Grav\Console\ConsoleCommand; use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Question\ConfirmationQuestion; class DirectInstallCommand extends ConsoleCommand @@ -31,7 +32,20 @@ class DirectInstallCommand extends ConsoleCommand ->addArgument( 'package-file', InputArgument::REQUIRED, - 'The local location or remote URL to an installable package file' + 'Installable package local or remote . Can install specific version' + ) + ->addOption( + 'all-yes', + 'y', + InputOption::VALUE_NONE, + 'Assumes yes (or best approach) instead of prompting' + ) + ->addOption( + 'destination', + 'd', + InputOption::VALUE_OPTIONAL, + 'The destination where the package should be installed at. By default this would be where the grav instance has been launched from', + GRAV_ROOT ) ->setDescription("Installs Grav, plugin, or theme directly from a file or a URL") ->setHelp('The direct-install command installs Grav, plugin, or theme directly from a file or a URL'); @@ -42,12 +56,26 @@ class DirectInstallCommand extends ConsoleCommand */ protected function serve() { + // Making sure the destination is usable + $this->destination = realpath($this->input->getOption('destination')); + + if ( + !Installer::isGravInstance($this->destination) || + !Installer::isValidDestination($this->destination, [Installer::EXISTS, Installer::IS_LINK]) + ) { + $this->output->writeln("ERROR: " . Installer::lastErrorMsg()); + exit; + } + + + $this->all_yes = $this->input->getOption('all-yes'); + $package_file = $this->input->getArgument('package-file'); $helper = $this->getHelper('question'); $question = new ConfirmationQuestion('Are you sure you want to direct-install '.$package_file.' [y|N] ', false); - $answer = $helper->ask($this->input, $this->output, $question); + $answer = $this->all_yes ? true : $helper->ask($this->input, $this->output, $question); if (!$answer) { $this->output->writeln("exiting..."); @@ -72,7 +100,7 @@ class DirectInstallCommand extends ConsoleCommand $this->output->writeln(''); exit; } - + if ($zip) { $this->output->write("\x0D"); $this->output->write(" |- Downloading package... 100%"); @@ -97,6 +125,8 @@ class DirectInstallCommand extends ConsoleCommand if (!$extracted) { $this->output->write("\x0D"); $this->output->writeln(" |- Extracting package... failed"); + Folder::delete($tmp_source); + Folder::delete($tmp_zip); exit; } @@ -109,6 +139,8 @@ class DirectInstallCommand extends ConsoleCommand if (!$type) { $this->output->writeln(" '- ERROR: Not a valid Grav package"); $this->output->writeln(''); + Folder::delete($tmp_source); + Folder::delete($tmp_zip); exit; } @@ -117,22 +149,27 @@ class DirectInstallCommand extends ConsoleCommand if (isset($blueprint['dependencies'])) { $depencencies = []; foreach ($blueprint['dependencies'] as $dependency) { - if (is_array($dependency) && isset($dependency['name'])) { - $depencencies[] = $dependency['name']; + if (is_array($dependency)){ + if (isset($dependency['name'])) { + $depencencies[] = $dependency['name']; + } + if (isset($dependency['github'])) { + $depencencies[] = $dependency['github']; + } } else { - $depencencies[] = $dependency; + $depencencies[] = $dependency; } } $this->output->writeln(" |- Dependencies found... [" . implode(',', $depencencies) . "]"); - - $question = new ConfirmationQuestion(" | '- Dependencies will not be satisfied. Continue ? [y|N] ", false); - $answer = $helper->ask($this->input, $this->output, $question); + $answer = $this->all_yes ? true : $helper->ask($this->input, $this->output, $question); if (!$answer) { $this->output->writeln("exiting..."); $this->output->writeln(''); + Folder::delete($tmp_source); + Folder::delete($tmp_zip); exit; } } @@ -147,6 +184,8 @@ class DirectInstallCommand extends ConsoleCommand $this->output->writeln(" |- Checking destination... symbolic link"); $this->output->writeln(" '- ERROR: symlinks found... " . GRAV_ROOT.""); $this->output->writeln(''); + Folder::delete($tmp_source); + Folder::delete($tmp_zip); exit; } @@ -161,6 +200,8 @@ class DirectInstallCommand extends ConsoleCommand if (!$name) { $this->output->writeln("ERROR: Name could not be determined. Please specify with --name|-n"); $this->output->writeln(''); + Folder::delete($tmp_source); + Folder::delete($tmp_zip); exit; } @@ -175,6 +216,8 @@ class DirectInstallCommand extends ConsoleCommand $this->output->writeln(" |- Checking destination... symbolic link"); $this->output->writeln(" '- ERROR: symlink found... " . GRAV_ROOT . DS . $install_path . ''); $this->output->writeln(''); + Folder::delete($tmp_source); + Folder::delete($tmp_zip); exit; } else { @@ -184,7 +227,16 @@ class DirectInstallCommand extends ConsoleCommand $this->output->write(" |- Installing package... "); - Installer::install($zip, GRAV_ROOT, ['install_path' => $install_path, 'theme' => (($type == 'theme')), 'is_update' => $is_update], $extracted); + Installer::install( + $zip, + $this->destination, + $options = [ + 'install_path' => $install_path, + 'theme' => (($type == 'theme')), + 'is_update' => $is_update + ], + $extracted + ); } Folder::delete($tmp_source); diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php index abf5e8163..bd01ead2b 100644 --- a/system/src/Grav/Console/Gpm/InstallCommand.php +++ b/system/src/Grav/Console/Gpm/InstallCommand.php @@ -80,7 +80,7 @@ class InstallCommand extends ConsoleCommand ->addArgument( 'package', InputArgument::IS_ARRAY | InputArgument::REQUIRED, - 'The package(s) that are desired to be installed. Use the "index" command for a list of packages' + 'Package(s) to install. Use "bin/gpm index" to list packages. Use "bin/gpm direct-install" to install a specific version' ) ->setDescription("Performs the installation of plugins and themes") ->setHelp('The install command allows to install plugins and themes'); @@ -563,6 +563,7 @@ class InstallCommand extends ConsoleCommand $tmp_dir = Grav::instance()['locator']->findResource('tmp://', true, true); $this->tmp = $tmp_dir . '/Grav-' . uniqid(); $filename = $package->slug . basename($package->zipball_url); + $filename = preg_replace('/[\\\\\/:"*?&<>|]+/mi', '-', $filename); $query = ''; if ($package->premium) { diff --git a/tests/functional/Grav/Console/DirectInstallCommandTest.php b/tests/functional/Grav/Console/DirectInstallCommandTest.php new file mode 100644 index 000000000..d1bc6cf76 --- /dev/null +++ b/tests/functional/Grav/Console/DirectInstallCommandTest.php @@ -0,0 +1,40 @@ +grav = Fixtures::get('grav'); + $this->directInstallCommand = new DirectInstallCommand(); + } + +} + +/** + * Why this test file is empty + * + * Wasn't able to call a symfony\console. Kept having $output problem. + * symfony console \NullOutput didn't cut it. + * + * We would also need to Mock tests since downloading packages would + * make tests slow and unreliable. But it's not worth the time ATM. + * + * Look at Gpm/InstallCommandTest.php + * + * For the full story: https://git.io/vSlI3 + */ diff --git a/tests/unit/Grav/Common/AssetsTest.php b/tests/unit/Grav/Common/AssetsTest.php index e02593cf9..e4b055cc6 100644 --- a/tests/unit/Grav/Common/AssetsTest.php +++ b/tests/unit/Grav/Common/AssetsTest.php @@ -41,6 +41,7 @@ class AssetsTest extends \Codeception\TestCase\Test 'priority' => 10, 'order' => 0, 'pipeline' => true, + 'loading' => '', 'group' => 'head', 'modified' => false ], reset($array)); @@ -56,6 +57,7 @@ class AssetsTest extends \Codeception\TestCase\Test 'priority' => 10, 'order' => 0, 'pipeline' => true, + 'loading' => '', 'group' => 'head', 'modified' => false ], reset($array)); @@ -73,6 +75,7 @@ class AssetsTest extends \Codeception\TestCase\Test 'priority' => 10, 'order' => 0, 'pipeline' => true, + 'loading' => '', 'group' => 'head', 'modified' => false ], reset($array)); @@ -90,6 +93,7 @@ class AssetsTest extends \Codeception\TestCase\Test 'priority' => 10, 'order' => 0, 'pipeline' => true, + 'loading' => '', 'group' => 'head', 'modified' => false ], reset($array)); @@ -133,6 +137,7 @@ class AssetsTest extends \Codeception\TestCase\Test 'priority' => 10, 'order' => 0, 'pipeline' => true, + 'loading' => '', 'group' => 'footer', 'modified' => false ], reset($array)); @@ -192,6 +197,22 @@ class AssetsTest extends \Codeception\TestCase\Test 'modified' => false ], reset($array)); + //Test inline + $this->assets->reset(); + $this->assets->addJs('/system/assets/jquery/jquery-2.x.min.js', null, true, 'inline', null); + $js = $this->assets->js(); + $this->assertContains('jQuery Foundation', $js); + + $this->assets->reset(); + $this->assets->addCss('/system/assets/debugger.css', null, true, null, 'inline'); + $css = $this->assets->css(); + $this->assertContains('div.phpdebugbar', $css); + + $this->assets->reset(); + $this->assets->addCss('https://fonts.googleapis.com/css?family=Roboto', null, true, null, 'inline'); + $css = $this->assets->css(); + $this->assertContains('font-family: \'Roboto\';', $css); + //Test adding media queries $this->assets->reset(); $this->assets->add('test.css', ['media' => 'only screen and (min-width: 640px)']); @@ -336,6 +357,24 @@ class AssetsTest extends \Codeception\TestCase\Test $this->assertContains($this->assets->getTimestamp(), $css); } + public function testInlinePipeline() + { + $this->assets->reset(); + + //File not existing. Pipeline searches for that file without reaching it. Output is empty. + $this->assets->add('test.css', null, true); + $this->assets->setCssPipeline(true); + $css = $this->assets->css('head', ['loading' => 'inline']); + $this->assertSame('', $css); + + //Add a core Grav CSS file, which is found. Pipeline will now return its content. + $this->assets->addCss('https://fonts.googleapis.com/css?family=Roboto', null, true); + $this->assets->add('/system/assets/debugger.css', null, true); + $css = $this->assets->css('head', ['loading' => 'inline']); + $this->assertContains('font-family:\'Roboto\';', $css); + $this->assertContains('div.phpdebugbar', $css); + } + public function testAddAsyncJs() { $this->assets->reset(); diff --git a/tests/unit/Grav/Common/GPM/GPMTest.php b/tests/unit/Grav/Common/GPM/GPMTest.php index 1597dd872..aba4a8cf2 100644 --- a/tests/unit/Grav/Common/GPM/GPMTest.php +++ b/tests/unit/Grav/Common/GPM/GPMTest.php @@ -11,7 +11,7 @@ class GpmStub extends GPM { public $data; - public function findPackage($packageName) + public function findPackage($packageName, $ignore_exception = false) { if (isset($this->data[$packageName])) { return $this->data[$packageName]; @@ -320,4 +320,4 @@ class GpmTest extends \Codeception\TestCase\Test $this->assertSame(null, $this->gpm->calculateVersionNumberFromDependencyVersion('*')); $this->assertSame('2.0.2', $this->gpm->calculateVersionNumberFromDependencyVersion('2.0.2')); } -} \ No newline at end of file +} diff --git a/webserver-configs/lighttpd.conf b/webserver-configs/lighttpd.conf index df77c6902..fd3ca9a54 100644 --- a/webserver-configs/lighttpd.conf +++ b/webserver-configs/lighttpd.conf @@ -23,7 +23,7 @@ $HTTP["querystring"] =~ "_REQUEST(=|\[|\%[0-9A-Z])" { #REROUTING TO THE INDEX PAGE url.rewrite-if-not-file = ( - "^/grav_path/(.*)$" => "/grav_path/index.php" + "^/grav_path/(.*)$" => "/grav_path/index.php$1" ) #IMPROVING SECURITY