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