diff --git a/CHANGELOG.md b/CHANGELOG.md
index e19f64f01..24489165c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,19 @@
+# v1.1.0
+## XX/XX/2016
+
+1. [](#new)
+ *
+1. [](#improved)
+ * Now supporting hostnames with localhost environments for better vhost support/development
+1. [](#bugfix)
+ *
+
# v1.0.10
## 02/11/2016
1. [](#new)
* Added new `Page::contentMeta()` mechanism to store content-level meta data alongside content
- * Added Japanese language translation
+ * Added Japanese language translation
1. [](#improved)
* Updated some vendor libraries
1. [](#bugfix)
@@ -18,7 +28,7 @@
* New **page-level SSL** functionality when using `absolute_urls`
* Added `reverse_proxy` config option for issues with non-standard ports
* Added `proxy_url` config option to support GPM behind proxy servers #639
- * New `Pages::parentsRawRoutes()` method
+ * New `Pages::parentsRawRoutes()` method
* Enhanced `bin/gpm info` CLI command with Changelog support #559
* Ability to add empty *Folder* via admin plugin
* Added latest `jQuery 2.2.0` library to core
diff --git a/bin/grav b/bin/grav
index 7c44efd2e..550767f9d 100755
--- a/bin/grav
+++ b/bin/grav
@@ -32,15 +32,17 @@ if (!file_exists(ROOT_DIR . 'index.php')) {
exit('FATAL: Must be run from ROOT directory of Grav!');
}
-$app = new Application('Grav CLI Application', '0.1.0');
+$app = new Application('Grav CLI Application', GRAV_VERSION);
$app->addCommands(array(
- new Grav\Console\Cli\InstallCommand(),
- new Grav\Console\Cli\ComposerCommand(),
- new Grav\Console\Cli\SandboxCommand(),
- new Grav\Console\Cli\CleanCommand(),
- new Grav\Console\Cli\ClearCacheCommand(),
- new Grav\Console\Cli\BackupCommand(),
- new Grav\Console\Cli\NewProjectCommand(),
- new Grav\Console\Cli\NewUserCommand(),
+ new \Grav\Console\Cli\InstallCommand(),
+ new \Grav\Console\Cli\ComposerCommand(),
+ new \Grav\Console\Cli\SandboxCommand(),
+ new \Grav\Console\Cli\CleanCommand(),
+ new \Grav\Console\Cli\ClearCacheCommand(),
+ new \Grav\Console\Cli\BackupCommand(),
+ new \Grav\Console\Cli\NewProjectCommand(),
+ new \Grav\Console\Cli\NewUserCommand(),
+ new \Grav\Console\Cli\DevTools\NewPluginCommand(),
+ new \Grav\Console\Cli\DevTools\NewThemeCommand(),
));
$app->run();
diff --git a/composer.json b/composer.json
index 016c37c95..5730daa5a 100644
--- a/composer.json
+++ b/composer.json
@@ -26,10 +26,12 @@
"maximebf/debugbar": "~1.10",
"ext-mbstring": "*",
"ext-openssl": "*",
- "ext-curl": "*"
+ "ext-curl": "*",
+ "twig/extensions": "^1.3"
},
"require-dev": {
"codeception/codeception": "^2.1",
+ "phpunit/php-code-coverage": "~2.0",
"fzaninotto/faker": "^1.5"
},
"autoload": {
diff --git a/composer.lock b/composer.lock
index bcf3ef2c9..221d490f4 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "dafb943040964731630ab4992b1ea540",
- "content-hash": "93e9fc9ecc82e91296f8a21aa9756123",
+ "hash": "ff44cbc35ded0b6491ab74b32f62cd9f",
+ "content-hash": "5d8b4ff937850c8b1cd333f5855369a6",
"packages": [
{
"name": "doctrine/cache",
@@ -216,16 +216,16 @@
},
{
"name": "filp/whoops",
- "version": "2.0.0",
+ "version": "2.1.2",
"source": {
"type": "git",
"url": "https://github.com/filp/whoops.git",
- "reference": "a327942c50cbd62b25c6fbe08f173031ce25fbff"
+ "reference": "d13505b240a6f580bc75ba591da30299d6cb0eec"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/filp/whoops/zipball/a327942c50cbd62b25c6fbe08f173031ce25fbff",
- "reference": "a327942c50cbd62b25c6fbe08f173031ce25fbff",
+ "url": "https://api.github.com/repos/filp/whoops/zipball/d13505b240a6f580bc75ba591da30299d6cb0eec",
+ "reference": "d13505b240a6f580bc75ba591da30299d6cb0eec",
"shasum": ""
},
"require": {
@@ -233,7 +233,8 @@
},
"require-dev": {
"mockery/mockery": "0.9.*",
- "phpunit/phpunit": "^4.8 || ^5.0"
+ "phpunit/phpunit": "^4.8 || ^5.0",
+ "symfony/var-dumper": "~3.0"
},
"suggest": {
"symfony/var-dumper": "Pretty print complex values better with var-dumper available",
@@ -271,7 +272,7 @@
"whoops",
"zf2"
],
- "time": "2016-01-06 17:51:21"
+ "time": "2016-04-07 06:16:25"
},
{
"name": "gregwar/cache",
@@ -427,16 +428,16 @@
},
{
"name": "monolog/monolog",
- "version": "1.18.0",
+ "version": "1.18.2",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
- "reference": "e19b764b5c855580e8ffa7e615f72c10fd2f99cc"
+ "reference": "064b38c16790249488e7a8b987acf1c9d7383c09"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Seldaek/monolog/zipball/e19b764b5c855580e8ffa7e615f72c10fd2f99cc",
- "reference": "e19b764b5c855580e8ffa7e615f72c10fd2f99cc",
+ "url": "https://api.github.com/repos/Seldaek/monolog/zipball/064b38c16790249488e7a8b987acf1c9d7383c09",
+ "reference": "064b38c16790249488e7a8b987acf1c9d7383c09",
"shasum": ""
},
"require": {
@@ -451,13 +452,13 @@
"doctrine/couchdb": "~1.0@dev",
"graylog2/gelf-php": "~1.0",
"jakub-onderka/php-parallel-lint": "0.9",
+ "php-amqplib/php-amqplib": "~2.4",
"php-console/php-console": "^3.1.3",
"phpunit/phpunit": "~4.5",
"phpunit/phpunit-mock-objects": "2.3.0",
"raven/raven": "^0.13",
"ruflin/elastica": ">=0.90 <3.0",
- "swiftmailer/swiftmailer": "~5.3",
- "videlalvaro/php-amqplib": "~2.4"
+ "swiftmailer/swiftmailer": "~5.3"
},
"suggest": {
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
@@ -466,11 +467,11 @@
"ext-mongo": "Allow sending log messages to a MongoDB server",
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
"mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver",
+ "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
"php-console/php-console": "Allow sending log messages to Google Chrome",
"raven/raven": "Allow sending log messages to a Sentry server",
"rollbar/rollbar": "Allow sending log messages to Rollbar",
- "ruflin/elastica": "Allow sending log messages to an Elastic Search server",
- "videlalvaro/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib"
+ "ruflin/elastica": "Allow sending log messages to an Elastic Search server"
},
"type": "library",
"extra": {
@@ -501,20 +502,20 @@
"logging",
"psr-3"
],
- "time": "2016-03-01 18:00:40"
+ "time": "2016-04-02 13:12:58"
},
{
"name": "mrclay/minify",
- "version": "2.2.1",
+ "version": "2.3.0",
"source": {
"type": "git",
"url": "https://github.com/mrclay/minify.git",
- "reference": "3c11ba8232a2155a1a29552aafc528be5fb0a662"
+ "reference": "f4cb31135d288f951bb0af1f23a03d4c00ba9446"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/mrclay/minify/zipball/3c11ba8232a2155a1a29552aafc528be5fb0a662",
- "reference": "3c11ba8232a2155a1a29552aafc528be5fb0a662",
+ "url": "https://api.github.com/repos/mrclay/minify/zipball/f4cb31135d288f951bb0af1f23a03d4c00ba9446",
+ "reference": "f4cb31135d288f951bb0af1f23a03d4c00ba9446",
"shasum": ""
},
"require": {
@@ -546,7 +547,7 @@
],
"description": "Minify is a PHP5 app that helps you follow several rules for client-side performance. It combines multiple CSS or Javascript files, removes unnecessary whitespace and comments, and serves them with gzip encoding and optimal client-side cache headers",
"homepage": "http://code.google.com/p/minify/",
- "time": "2014-10-30 22:58:02"
+ "time": "2016-03-08 11:49:57"
},
{
"name": "pimple/pimple",
@@ -638,12 +639,12 @@
"source": {
"type": "git",
"url": "https://github.com/rockettheme/toolbox.git",
- "reference": "bb8902cf4ec25ece14d89efc743f3732244e18a8"
+ "reference": "c1da8d97b11e5a341d085bdbc83ca1b6721477a5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/bb8902cf4ec25ece14d89efc743f3732244e18a8",
- "reference": "bb8902cf4ec25ece14d89efc743f3732244e18a8",
+ "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/c1da8d97b11e5a341d085bdbc83ca1b6721477a5",
+ "reference": "c1da8d97b11e5a341d085bdbc83ca1b6721477a5",
"shasum": ""
},
"require": {
@@ -678,20 +679,20 @@
"php",
"rockettheme"
],
- "time": "2016-03-15 12:06:40"
+ "time": "2016-03-21 06:47:31"
},
{
"name": "symfony/console",
- "version": "v2.8.3",
+ "version": "v2.8.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "56cc5caf051189720b8de974e4746090aaa10d44"
+ "reference": "9a5aef5fc0d4eff86853d44202b02be8d5a20154"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/56cc5caf051189720b8de974e4746090aaa10d44",
- "reference": "56cc5caf051189720b8de974e4746090aaa10d44",
+ "url": "https://api.github.com/repos/symfony/console/zipball/9a5aef5fc0d4eff86853d44202b02be8d5a20154",
+ "reference": "9a5aef5fc0d4eff86853d44202b02be8d5a20154",
"shasum": ""
},
"require": {
@@ -738,20 +739,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
- "time": "2016-02-28 16:20:50"
+ "time": "2016-03-17 09:19:04"
},
{
"name": "symfony/event-dispatcher",
- "version": "v2.8.3",
+ "version": "v2.8.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "78c468665c9568c3faaa9c416a7134308f2d85c3"
+ "reference": "47d2d8cade9b1c3987573d2943bb9352536cdb87"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/78c468665c9568c3faaa9c416a7134308f2d85c3",
- "reference": "78c468665c9568c3faaa9c416a7134308f2d85c3",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/47d2d8cade9b1c3987573d2943bb9352536cdb87",
+ "reference": "47d2d8cade9b1c3987573d2943bb9352536cdb87",
"shasum": ""
},
"require": {
@@ -798,7 +799,7 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
- "time": "2016-01-27 05:14:19"
+ "time": "2016-03-07 14:04:32"
},
{
"name": "symfony/polyfill-iconv",
@@ -920,16 +921,16 @@
},
{
"name": "symfony/var-dumper",
- "version": "v2.8.3",
+ "version": "v2.8.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
- "reference": "19b697abe08833ddf38c3ab0cb1bfad236b13bde"
+ "reference": "1f840df081f59cbe25140742bbe94a0dfac0222a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-dumper/zipball/19b697abe08833ddf38c3ab0cb1bfad236b13bde",
- "reference": "19b697abe08833ddf38c3ab0cb1bfad236b13bde",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/1f840df081f59cbe25140742bbe94a0dfac0222a",
+ "reference": "1f840df081f59cbe25140742bbe94a0dfac0222a",
"shasum": ""
},
"require": {
@@ -979,20 +980,20 @@
"debug",
"dump"
],
- "time": "2016-02-13 09:21:29"
+ "time": "2016-03-07 14:04:32"
},
{
"name": "symfony/yaml",
- "version": "v2.8.3",
+ "version": "v2.8.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "2a4ee40acb880c56f29fb1b8886e7ffe94f3b995"
+ "reference": "584e52cb8f788a887553ba82db6caacb1d6260bb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/2a4ee40acb880c56f29fb1b8886e7ffe94f3b995",
- "reference": "2a4ee40acb880c56f29fb1b8886e7ffe94f3b995",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/584e52cb8f788a887553ba82db6caacb1d6260bb",
+ "reference": "584e52cb8f788a887553ba82db6caacb1d6260bb",
"shasum": ""
},
"require": {
@@ -1028,7 +1029,59 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "time": "2016-02-23 07:41:20"
+ "time": "2016-03-04 07:54:35"
+ },
+ {
+ "name": "twig/extensions",
+ "version": "v1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/twigphp/Twig-extensions.git",
+ "reference": "449e3c8a9ffad7c2479c7864557275a32b037499"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/twigphp/Twig-extensions/zipball/449e3c8a9ffad7c2479c7864557275a32b037499",
+ "reference": "449e3c8a9ffad7c2479c7864557275a32b037499",
+ "shasum": ""
+ },
+ "require": {
+ "twig/twig": "~1.20|~2.0"
+ },
+ "require-dev": {
+ "symfony/translation": "~2.3"
+ },
+ "suggest": {
+ "symfony/translation": "Allow the time_diff output to be translated"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Twig_Extensions_": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "description": "Common additional features for Twig that do not directly belong in core",
+ "homepage": "http://twig.sensiolabs.org/doc/extensions/index.html",
+ "keywords": [
+ "i18n",
+ "text"
+ ],
+ "time": "2015-08-22 16:38:35"
},
{
"name": "twig/twig",
@@ -1095,41 +1148,42 @@
"packages-dev": [
{
"name": "codeception/codeception",
- "version": "2.1.6",
+ "version": "2.1.7",
"source": {
"type": "git",
"url": "https://github.com/Codeception/Codeception.git",
- "reference": "b199941f5e59d1e7fd32d78296c8ab98db873d89"
+ "reference": "65971b0dee4972710365b6102154cd412a9bf7b1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Codeception/Codeception/zipball/b199941f5e59d1e7fd32d78296c8ab98db873d89",
- "reference": "b199941f5e59d1e7fd32d78296c8ab98db873d89",
+ "url": "https://api.github.com/repos/Codeception/Codeception/zipball/65971b0dee4972710365b6102154cd412a9bf7b1",
+ "reference": "65971b0dee4972710365b6102154cd412a9bf7b1",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-mbstring": "*",
- "facebook/webdriver": ">=1.0.1",
+ "facebook/webdriver": ">=1.0.1 <2.0",
"guzzlehttp/guzzle": ">=4.1.4 <7.0",
"guzzlehttp/psr7": "~1.0",
- "php": ">=5.4.0",
- "phpunit/phpunit": "~4.8.0",
- "symfony/browser-kit": ">=2.4|<3.1",
- "symfony/console": ">=2.4|<3.1",
- "symfony/css-selector": ">=2.4|<3.1",
- "symfony/dom-crawler": ">=2.4|<3.1",
- "symfony/event-dispatcher": ">=2.4|<3.1",
- "symfony/finder": ">=2.4|<3.1",
- "symfony/yaml": ">=2.4|<3.1"
+ "php": ">=5.4.0 <8.0",
+ "phpunit/php-code-coverage": ">=2.1.3",
+ "phpunit/phpunit": ">4.8.20 <6.0",
+ "symfony/browser-kit": ">=2.5 <3.1",
+ "symfony/console": ">=2.5 <3.1",
+ "symfony/css-selector": ">=2.5 <3.1",
+ "symfony/dom-crawler": ">=2.5 <3.1",
+ "symfony/event-dispatcher": ">=2.5 <3.1",
+ "symfony/finder": ">=2.5 <3.1",
+ "symfony/yaml": ">=2.5 <3.1"
},
"require-dev": {
"codeception/specify": "~0.3",
- "facebook/php-sdk-v4": "~4.0",
+ "facebook/php-sdk-v4": "~5.0",
"flow/jsonpath": "~0.2",
"monolog/monolog": "~1.8",
"pda/pheanstalk": "~2.0",
- "videlalvaro/php-amqplib": "~2.4"
+ "php-amqplib/php-amqplib": "~2.4"
},
"suggest": {
"codeception/phpbuiltinserver": "Extension to start and stop PHP built-in web server for your tests",
@@ -1171,7 +1225,7 @@
"functional testing",
"unit testing"
],
- "time": "2016-02-09 22:27:48"
+ "time": "2016-03-12 01:15:25"
},
{
"name": "doctrine/instantiator",
@@ -1324,16 +1378,16 @@
},
{
"name": "guzzlehttp/guzzle",
- "version": "6.1.1",
+ "version": "6.2.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
- "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c"
+ "reference": "d094e337976dff9d8e2424e8485872194e768662"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/guzzle/zipball/c6851d6e48f63b69357cbfa55bca116448140e0c",
- "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d094e337976dff9d8e2424e8485872194e768662",
+ "reference": "d094e337976dff9d8e2424e8485872194e768662",
"shasum": ""
},
"require": {
@@ -1349,7 +1403,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "6.1-dev"
+ "dev-master": "6.2-dev"
}
},
"autoload": {
@@ -1382,7 +1436,7 @@
"rest",
"web service"
],
- "time": "2015-11-23 00:47:50"
+ "time": "2016-03-21 20:02:09"
},
{
"name": "guzzlehttp/promises",
@@ -1846,16 +1900,16 @@
},
{
"name": "phpunit/phpunit",
- "version": "4.8.23",
+ "version": "4.8.24",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "6e351261f9cd33daf205a131a1ba61c6d33bd483"
+ "reference": "a1066c562c52900a142a0e2bbf0582994671385e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6e351261f9cd33daf205a131a1ba61c6d33bd483",
- "reference": "6e351261f9cd33daf205a131a1ba61c6d33bd483",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a1066c562c52900a142a0e2bbf0582994671385e",
+ "reference": "a1066c562c52900a142a0e2bbf0582994671385e",
"shasum": ""
},
"require": {
@@ -1914,7 +1968,7 @@
"testing",
"xunit"
],
- "time": "2016-02-11 14:56:33"
+ "time": "2016-03-14 06:16:08"
},
{
"name": "phpunit/phpunit-mock-objects",
@@ -2394,16 +2448,16 @@
},
{
"name": "symfony/browser-kit",
- "version": "v3.0.3",
+ "version": "v3.0.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/browser-kit.git",
- "reference": "dde849a0485b70a24b36f826ed3fb95b904d80c3"
+ "reference": "e07127ac31230b30887c2dddf3708d883d239b14"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/browser-kit/zipball/dde849a0485b70a24b36f826ed3fb95b904d80c3",
- "reference": "dde849a0485b70a24b36f826ed3fb95b904d80c3",
+ "url": "https://api.github.com/repos/symfony/browser-kit/zipball/e07127ac31230b30887c2dddf3708d883d239b14",
+ "reference": "e07127ac31230b30887c2dddf3708d883d239b14",
"shasum": ""
},
"require": {
@@ -2447,20 +2501,20 @@
],
"description": "Symfony BrowserKit Component",
"homepage": "https://symfony.com",
- "time": "2016-01-27 11:34:55"
+ "time": "2016-03-04 07:55:57"
},
{
"name": "symfony/css-selector",
- "version": "v3.0.3",
+ "version": "v3.0.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
- "reference": "6605602690578496091ac20ec7a5cbd160d4dff4"
+ "reference": "65e764f404685f2dc20c057e889b3ad04b2e2db0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/css-selector/zipball/6605602690578496091ac20ec7a5cbd160d4dff4",
- "reference": "6605602690578496091ac20ec7a5cbd160d4dff4",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/65e764f404685f2dc20c057e889b3ad04b2e2db0",
+ "reference": "65e764f404685f2dc20c057e889b3ad04b2e2db0",
"shasum": ""
},
"require": {
@@ -2500,20 +2554,20 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
- "time": "2016-01-27 05:14:46"
+ "time": "2016-03-04 07:55:57"
},
{
"name": "symfony/dom-crawler",
- "version": "v3.0.3",
+ "version": "v3.0.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
- "reference": "981c8edb4538f88ba976ed44bdcaa683fce3d6c6"
+ "reference": "18a06d7a9af41718c20764a674a0ebba3bc40d1f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/981c8edb4538f88ba976ed44bdcaa683fce3d6c6",
- "reference": "981c8edb4538f88ba976ed44bdcaa683fce3d6c6",
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/18a06d7a9af41718c20764a674a0ebba3bc40d1f",
+ "reference": "18a06d7a9af41718c20764a674a0ebba3bc40d1f",
"shasum": ""
},
"require": {
@@ -2556,20 +2610,20 @@
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
- "time": "2016-02-28 16:24:34"
+ "time": "2016-03-23 13:23:25"
},
{
"name": "symfony/finder",
- "version": "v3.0.3",
+ "version": "v3.0.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "623bda0abd9aa29e529c8e9c08b3b84171914723"
+ "reference": "c54e407b35bc098916704e9fd090da21da4c4f52"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/623bda0abd9aa29e529c8e9c08b3b84171914723",
- "reference": "623bda0abd9aa29e529c8e9c08b3b84171914723",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/c54e407b35bc098916704e9fd090da21da4c4f52",
+ "reference": "c54e407b35bc098916704e9fd090da21da4c4f52",
"shasum": ""
},
"require": {
@@ -2605,7 +2659,7 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
- "time": "2016-01-27 05:14:46"
+ "time": "2016-03-10 11:13:05"
}
],
"aliases": [
diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml
index 6059d7fde..73d4af5af 100644
--- a/system/blueprints/config/system.yaml
+++ b/system/blueprints/config/system.yaml
@@ -567,6 +567,28 @@ form:
validate:
type: bool
+ assets.css_pipeline_include_externals:
+ type: toggle
+ label: PLUGIN_ADMIN.CSS_PIPELINE_INCLUDE_EXTERNALS
+ help: PLUGIN_ADMIN.CSS_PIPELINE_INCLUDE_EXTERNALS_HELP
+ highlight: 1
+ options:
+ 1: PLUGIN_ADMIN.YES
+ 0: PLUGIN_ADMIN.NO
+ validate:
+ type: bool
+
+ assets.css_pipeline_before_excludes:
+ type: toggle
+ label: PLUGIN_ADMIN.CSS_PIPELINE_BEFORE_EXCLUDES
+ help: PLUGIN_ADMIN.CSS_PIPELINE_BEFORE_EXCLUDES_HELP
+ highlight: 1
+ options:
+ 1: PLUGIN_ADMIN.YES
+ 0: PLUGIN_ADMIN.NO
+ validate:
+ type: bool
+
assets.css_minify:
type: toggle
label: PLUGIN_ADMIN.CSS_MINIFY
@@ -611,6 +633,28 @@ form:
validate:
type: bool
+ assets.js_pipeline_include_externals:
+ type: toggle
+ label: PLUGIN_ADMIN.JAVASCRIPT_PIPELINE_INCLUDE_EXTERNALS
+ help: PLUGIN_ADMIN.JAVASCRIPT_PIPELINE_INCLUDE_EXTERNALS_HELP
+ highlight: 1
+ options:
+ 1: PLUGIN_ADMIN.YES
+ 0: PLUGIN_ADMIN.NO
+ validate:
+ type: bool
+
+ assets.js_pipeline_before_excludes:
+ type: toggle
+ label: PLUGIN_ADMIN.JAVASCRIPT_PIPELINE_BEFORE_EXCLUDES
+ help: PLUGIN_ADMIN.JAVASCRIPT_PIPELINE_BEFORE_EXCLUDES_HELP
+ highlight: 1
+ options:
+ 1: PLUGIN_ADMIN.YES
+ 0: PLUGIN_ADMIN.NO
+ validate:
+ type: bool
+
assets.js_minify:
type: toggle
label: PLUGIN_ADMIN.JAVASCRIPT_MINIFY
diff --git a/system/config/system.yaml b/system/config/system.yaml
index 1d21cea23..534c9b09c 100644
--- a/system/config/system.yaml
+++ b/system/config/system.yaml
@@ -80,10 +80,14 @@ twig:
assets: # Configuration for Assets Manager (JS, CSS)
css_pipeline: false # The CSS pipeline is the unification of multiple CSS resources into one file
+ css_pipeline_include_externals: true # Include external URLs in the pipeline by default
+ css_pipeline_before_excludes: true # Render the pipeline before any excluded files
css_minify: true # Minify the CSS during pipelining
css_minify_windows: false # Minify Override for Windows platforms. False by default due to ThreadStackSize
css_rewrite: true # Rewrite any CSS relative URLs during pipelining
js_pipeline: false # The JS pipeline is the unification of multiple JS resources into one file
+ js_pipeline_include_externals: true # Include external URLs in the pipeline by default
+ js_pipeline_before_excludes: true # Render the pipeline before any excluded files
js_minify: true # Minify the JS during pipelining
enable_asset_timestamp: false # Enable asset timestamps
collections:
diff --git a/system/defines.php b/system/defines.php
index 7d1ce424a..e81c95143 100644
--- a/system/defines.php
+++ b/system/defines.php
@@ -13,9 +13,7 @@ if (!defined('GRAV_ROOT')) {
define('ROOT_DIR', GRAV_ROOT . '/');
define('USER_PATH', 'user/');
define('USER_DIR', ROOT_DIR . USER_PATH);
-define('SYSTEM_DIR', ROOT_DIR .'system/');
define('CACHE_DIR', ROOT_DIR . 'cache/');
-define('LOG_DIR', ROOT_DIR .'logs/');
// DEPRECATED: Do not use!
define('ASSETS_DIR', ROOT_DIR . 'assets/');
@@ -23,10 +21,12 @@ define('IMAGES_DIR', ROOT_DIR . 'images/');
define('ACCOUNTS_DIR', USER_DIR .'accounts/');
define('PAGES_DIR', USER_DIR .'pages/');
define('DATA_DIR', USER_DIR .'data/');
+define('SYSTEM_DIR', ROOT_DIR .'system/');
define('LIB_DIR', SYSTEM_DIR .'src/');
define('PLUGINS_DIR', USER_DIR .'plugins/');
define('THEMES_DIR', USER_DIR .'themes/');
define('VENDOR_DIR', ROOT_DIR .'vendor/');
+define('LOG_DIR', ROOT_DIR .'logs/');
// END DEPRECATED
// Some extensions
diff --git a/system/src/Grav/Common/Assets.php b/system/src/Grav/Common/Assets.php
index 3a9a19d17..ebdce1b7b 100644
--- a/system/src/Grav/Common/Assets.php
+++ b/system/src/Grav/Common/Assets.php
@@ -61,7 +61,11 @@ class Assets
// Configuration toggles to enable/disable the pipelining feature
protected $css_pipeline = false;
+ protected $css_pipeline_include_externals = true;
+ protected $css_pipeline_before_excludes = true;
protected $js_pipeline = false;
+ protected $js_pipeline_include_externals = true;
+ protected $js_pipeline_before_excludes = true;
// The asset holding arrays
protected $collections = [];
@@ -120,10 +124,26 @@ class Assets
$this->css_pipeline = $config['css_pipeline'];
}
+ if (isset($config['css_pipeline_include_externals'])) {
+ $this->css_pipeline_include_externals = $config['css_pipeline_include_externals'];
+ }
+
+ if (isset($config['css_pipeline_before_excludes'])) {
+ $this->css_pipeline_before_excludes = $config['css_pipeline_before_excludes'];
+ }
+
if (isset($config['js_pipeline'])) {
$this->js_pipeline = $config['js_pipeline'];
}
+ if (isset($config['js_pipeline_include_externals'])) {
+ $this->js_pipeline_include_externals = $config['js_pipeline_include_externals'];
+ }
+
+ if (isset($config['js_pipeline_before_excludes'])) {
+ $this->js_pipeline_before_excludes = $config['js_pipeline_before_excludes'];
+ }
+
// Pipeline requires public dir
if (($this->js_pipeline || $this->css_pipeline) && !is_dir($this->assets_dir)) {
throw new \Exception('Assets: Public dir not found');
@@ -526,8 +546,10 @@ class Assets
if ($this->css_pipeline) {
$pipeline_result = $this->pipelineCss($group);
- if ($pipeline_result) {
- $output .= '' . "\n";
+ $pipeline_html = '' . "\n";
+
+ if ($this->css_pipeline_before_excludes && $pipeline_result) {
+ $output .= $pipeline_html;
}
foreach ($this->css_no_pipeline as $file) {
if ($group && $file['group'] == $group) {
@@ -535,6 +557,9 @@ class Assets
$output .= '' . "\n";
}
}
+ if (!$this->css_pipeline_before_excludes && $pipeline_result) {
+ $output .= $pipeline_html;
+ }
} else {
foreach ($this->css as $file) {
if ($group && $file['group'] == $group) {
@@ -600,14 +625,19 @@ class Assets
if ($this->js_pipeline) {
$pipeline_result = $this->pipelineJs($group);
- if ($pipeline_result) {
- $output .= '' . "\n";
+ $pipeline_html = '' . "\n";
+
+ if ($this->js_pipeline_before_excludes && $pipeline_result) {
+ $output .= $pipeline_html;
}
foreach ($this->js_no_pipeline as $file) {
if ($group && $file['group'] == $group) {
$output .= '' . "\n";
}
}
+ if (!$this->js_pipeline_before_excludes && $pipeline_result) {
+ $output .= $pipeline_html;
+ }
} else {
foreach ($this->js as $file) {
if ($group && $file['group'] == $group) {
@@ -649,20 +679,27 @@ class Assets
// clear no-pipeline assets lists
$this->css_no_pipeline = [];
- $file = md5(json_encode($this->css) . $this->css_minify . $this->css_rewrite . $group) . '.css';
+ $uid = md5(json_encode($this->css) . $this->css_minify . $this->css_rewrite . $group);
+ $file = $uid . '.css';
+ $inline_file = $uid . '-inline.css';
$relative_path = "{$this->base_url}{$this->assets_url}/{$file}";
- $absolute_path = $this->assets_dir . $file;
+
+ // If inline files exist set them on object
+ if (file_exists($this->assets_dir . $inline_file)) {
+ $this->css_no_pipeline = json_decode(file_get_contents($this->assets_dir . $inline_file), true);
+ }
// If pipeline exist return it
- if (file_exists($absolute_path)) {
+ if (file_exists($this->assets_dir . $file)) {
return $relative_path . $key;
}
// Remove any non-pipeline files
foreach ($this->css as $id => $asset) {
if ($asset['group'] == $group) {
- if (!$asset['pipeline']) {
+ if (!$asset['pipeline'] ||
+ ($this->isRemoteLink($asset['asset']) && $this->css_pipeline_include_externals === false)) {
$this->css_no_pipeline[$id] = $asset;
} else {
$temp_css[$id] = $asset;
@@ -675,6 +712,12 @@ class Assets
return false;
}
+ // Write non-pipeline files out
+ if (!empty($this->css_no_pipeline)) {
+ file_put_contents($this->assets_dir . $inline_file, json_encode($this->css_no_pipeline));
+ }
+
+
$css_minify = $this->css_minify;
// If this is a Windows server, and minify_windows is false (default value) skip the
@@ -693,7 +736,7 @@ class Assets
// Write file
if (strlen(trim($buffer)) > 0) {
- file_put_contents($absolute_path, $buffer);
+ file_put_contents($this->assets_dir . $file, $buffer);
return $relative_path . $key;
} else {
@@ -720,20 +763,27 @@ class Assets
// clear no-pipeline assets lists
$this->js_no_pipeline = [];
- $file = md5(json_encode($this->js) . $this->js_minify . $group) . '.js';
+ $uid = md5(json_encode($this->js) . $this->js_minify . $group);
+ $file = $uid . '.js';
+ $inline_file = $uid . '-inline.js';
$relative_path = "{$this->base_url}{$this->assets_url}/{$file}";
- $absolute_path = $this->assets_dir . $file;
+
+ // If inline files exist set them on object
+ if (file_exists($this->assets_dir . $inline_file)) {
+ $this->js_no_pipeline = json_decode(file_get_contents($this->assets_dir . $inline_file), true);
+ }
// If pipeline exist return it
- if (file_exists($absolute_path)) {
+ if (file_exists($this->assets_dir . $file)) {
return $relative_path . $key;
}
// Remove any non-pipeline files
foreach ($this->js as $id => $asset) {
if ($asset['group'] == $group) {
- if (!$asset['pipeline']) {
+ if (!$asset['pipeline'] ||
+ ($this->isRemoteLink($asset['asset']) && $this->js_pipeline_include_externals === false)) {
$this->js_no_pipeline[] = $asset;
} else {
$temp_js[$id] = $asset;
@@ -746,6 +796,11 @@ class Assets
return false;
}
+ // Write non-pipeline files out
+ if (!empty($this->js_no_pipeline)) {
+ file_put_contents($this->assets_dir . $inline_file, json_encode($this->js_no_pipeline));
+ }
+
// Concatenate files
$buffer = $this->gatherLinks($temp_js, JS_ASSET);
if ($this->js_minify) {
@@ -754,7 +809,7 @@ class Assets
// Write file
if (strlen(trim($buffer)) > 0) {
- file_put_contents($absolute_path, $buffer);
+ file_put_contents($this->assets_dir . $file, $buffer);
return $relative_path . $key;
} else {
@@ -1010,10 +1065,11 @@ class Assets
protected function gatherLinks(array $links, $css = true)
{
$buffer = '';
- $local = true;
+
foreach ($links as $asset) {
$relative_dir = '';
+ $local = true;
$link = $asset['asset'];
$relative_path = $link;
diff --git a/system/src/Grav/Common/Data/BlueprintSchema.php b/system/src/Grav/Common/Data/BlueprintSchema.php
index 659c18ba3..b2f41adaf 100644
--- a/system/src/Grav/Common/Data/BlueprintSchema.php
+++ b/system/src/Grav/Common/Data/BlueprintSchema.php
@@ -136,7 +136,7 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
&& !isset($data[$name])) {
$value = isset($field['label']) ? $field['label'] : $field['name'];
$language = Grav::instance()['language'];
- $message = sprintf($language->translate('FORM.MISSING_REQUIRED_FIELD', null, true) . ' %s', $value);
+ $message = sprintf($language->translate('FORM.MISSING_REQUIRED_FIELD', null, true) . ' %s', $language->translate($value));
$messages[$field['name']][] = $message;
}
}
diff --git a/system/src/Grav/Common/GPM/GPM.php b/system/src/Grav/Common/GPM/GPM.php
index a71f82884..c4577547f 100644
--- a/system/src/Grav/Common/GPM/GPM.php
+++ b/system/src/Grav/Common/GPM/GPM.php
@@ -194,7 +194,7 @@ class GPM extends Iterator
}
foreach ($this->installed['plugins'] as $slug => $plugin) {
- if (!isset($repository[$slug]) || $plugin->symlink) {
+ if (!isset($repository[$slug]) || $plugin->symlink || !$plugin->version || $plugin->gpm === false) {
continue;
}
@@ -272,7 +272,7 @@ class GPM extends Iterator
}
foreach ($this->installed['themes'] as $slug => $plugin) {
- if (!isset($repository[$slug]) || $plugin->symlink) {
+ if (!isset($repository[$slug]) || $plugin->symlink || !$plugin->version || $plugin->gpm === false) {
continue;
}
diff --git a/system/src/Grav/Common/GPM/Response.php b/system/src/Grav/Common/GPM/Response.php
index 50e89677e..f8c8ed307 100644
--- a/system/src/Grav/Common/GPM/Response.php
+++ b/system/src/Grav/Common/GPM/Response.php
@@ -199,7 +199,15 @@ class Response
// if proxy set add that
$proxy_url = Grav::instance()['config']->get('system.proxy_url');
if ($proxy_url) {
- $options['fopen']['proxy'] = $proxy_url;
+ $parsed_url = parse_url($proxy_url);
+
+ $options['fopen']['proxy'] = ($parsed_url['scheme'] ?: 'http') . '://' . $parsed_url['host'] . (isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '');
+ $options['fopen']['request_fulluri'] = true;
+
+ if (isset($parsed_url['user']) && isset($parsed_url['pass'])) {
+ $auth = base64_encode($parsed_url['user'] . ':' . $parsed_url['pass']);
+ $options['fopen']['header'] = "Proxy-Authorization: Basic $auth";
+ }
}
if ($callback) {
@@ -267,7 +275,18 @@ class Response
// if proxy set add that
$proxy_url = Grav::instance()['config']->get('system.proxy_url');
if ($proxy_url) {
- $options['curl'][CURLOPT_PROXY] = $proxy_url;
+ $parsed_url = parse_url($proxy_url);
+
+ $options['curl'][CURLOPT_PROXY] = $parsed_url['host'];
+ $options['curl'][CURLOPT_PROXYTYPE] = 'HTTP';
+
+ if (isset($parsed_url['port'])) {
+ $options['curl'][CURLOPT_PROXYPORT] = $parsed_url['port'];
+ }
+
+ if (isset($parsed_url['user']) && isset($parsed_url['pass'])) {
+ $options['curl'][CURLOPT_PROXYUSERPWD] = $parsed_url['user'] . ':' . $parsed_url['pass'];
+ }
}
// no open_basedir set, we can proceed normally
@@ -276,7 +295,7 @@ class Response
return curl_exec($ch);
}
- $max_redirects = isset($options['curl'][CURLOPT_MAXREDIRS]) ? $options['curl'][CURLOPT_MAXREDIRS] : 3;
+ $max_redirects = isset($options['curl'][CURLOPT_MAXREDIRS]) ? $options['curl'][CURLOPT_MAXREDIRS] : 3;
$options['curl'][CURLOPT_FOLLOWLOCATION] = false;
// open_basedir set but no redirects to follow, we can disable followlocation and proceed normally
diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php
index 4917da357..b761cda2a 100644
--- a/system/src/Grav/Common/Grav.php
+++ b/system/src/Grav/Common/Grav.php
@@ -84,8 +84,6 @@ class Grav extends Container
$container['debugger'] = new Debugger();
$container['debugger']->startTimer('_services', 'Services');
- $container->register(new LoggerServiceProvider);
-
$container->register(new ErrorServiceProvider);
$container['uri'] = function ($c) {
@@ -154,18 +152,35 @@ class Grav extends Container
// Redirection tests
if ($page) {
+ $url = $page->route();
+
+ if ($uri->params()) {
+ if ($url == '/') { //Avoid double slash
+ $url = $uri->params();
+ } else {
+ $url .= $uri->params();
+ }
+ }
+ if ($uri->query()) {
+ $url .= '?' . $uri->query();
+ }
+ if ($uri->fragment()) {
+ $url .= '#' . $uri->fragment();
+ }
+
// Language-specific redirection scenarios
if ($language->enabled()) {
if ($language->isLanguageInUrl() && !$language->isIncludeDefaultLanguage()) {
- $c->redirect($page->route());
+ $c->redirect($url);
}
if (!$language->isLanguageInUrl() && $language->isIncludeDefaultLanguage()) {
- $c->redirectLangSafe($page->route());
+ $c->redirectLangSafe($url);
}
}
+
// Default route test and redirect
if ($c['config']->get('system.pages.redirect_default_route') && $page->route() != $path) {
- $c->redirectLangSafe($page->route());
+ $c->redirectLangSafe($url);
}
}
@@ -199,6 +214,7 @@ class Grav extends Container
$container->register(new StreamsServiceProvider);
$container->register(new ConfigServiceProvider);
+ $container->register(new LoggerServiceProvider);
$container['inflector'] = new Inflector();
diff --git a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php
index 6610e056b..9b99c0587 100644
--- a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php
+++ b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php
@@ -63,9 +63,13 @@ trait ParsedownGravTrait
* @param $type
* @param $tag
*/
- public function addBlockType($type, $tag, $continuable = false, $completable = false)
+ public function addBlockType($type, $tag, $continuable = false, $completable = false, $index = null)
{
- $this->BlockTypes[$type] [] = $tag;
+ if (!isset($index)) {
+ $this->BlockTypes[$type] [] = $tag;
+ } else {
+ array_splice($this->BlockTypes[$type], $index, 0, $tag);
+ }
if ($continuable) {
$this->continuable_blocks[] = $tag;
@@ -82,10 +86,17 @@ trait ParsedownGravTrait
* @param $type
* @param $tag
*/
- public function addInlineType($type, $tag)
+ public function addInlineType($type, $tag, $index = null)
{
- $this->InlineTypes[$type] [] = $tag;
- $this->inlineMarkerList .= $type;
+ if (!isset($index)) {
+ $this->InlineTypes[$type] [] = $tag;
+ } else {
+ array_splice($this->InlineTypes[$type], $index, 0, $tag);
+ }
+
+ if (strpos($this->inlineMarkerList, $type) === false) {
+ $this->inlineMarkerList .= $type;
+ }
}
/**
@@ -229,6 +240,7 @@ trait ParsedownGravTrait
// if there is a query, then parse it and build action calls
if (isset($url['query'])) {
+ $url['query'] = htmlspecialchars_decode(urldecode($url['query']));
$actions = array_reduce(explode('&', $url['query']), function ($carry, $item) {
$parts = explode('=', $item, 2);
$value = isset($parts[1]) ? $parts[1] : null;
diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php
index c8ecf7d22..64acb7671 100644
--- a/system/src/Grav/Common/Page/Page.php
+++ b/system/src/Grav/Common/Page/Page.php
@@ -2134,7 +2134,7 @@ class Page
/** @var Pages $pages */
$pages = Grav::instance()['pages'];
- return $pages->dispatch($url, $all);
+ return $pages->find($url, $all);
}
/**
diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php
index fb98932db..1cb97592d 100644
--- a/system/src/Grav/Common/Page/Pages.php
+++ b/system/src/Grav/Common/Page/Pages.php
@@ -287,6 +287,19 @@ class Pages
return new Collection($children, [], $this);
}
+ /**
+ * alias method to return find a page.
+ *
+ * @param string $url The relative URL of the page
+ * @param bool $all
+ *
+ * @return Page|null
+ */
+ public function find($url, $all = false)
+ {
+ return $this->dispatch($url, $all);
+ }
+
/**
* Dispatch URI to a page.
*
@@ -704,7 +717,7 @@ class Pages
$last_modified = Folder::lastModifiedFile($pages_dir);
}
- $page_cache_id = md5(USER_DIR . $last_modified . $language->getActive() . $config->checksum());
+ $page_cache_id = md5($pages_dir . $last_modified . $language->getActive() . $config->checksum());
list($this->instances, $this->routes, $this->children, $taxonomy_map, $this->sort) = $cache->fetch($page_cache_id);
if (!$this->instances) {
diff --git a/system/src/Grav/Common/Service/LoggerServiceProvider.php b/system/src/Grav/Common/Service/LoggerServiceProvider.php
index edaf92178..75affc985 100644
--- a/system/src/Grav/Common/Service/LoggerServiceProvider.php
+++ b/system/src/Grav/Common/Service/LoggerServiceProvider.php
@@ -5,16 +5,23 @@ use Pimple\Container;
use Pimple\ServiceProviderInterface;
use \Monolog\Logger;
use \Monolog\Handler\StreamHandler;
+use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
class LoggerServiceProvider implements ServiceProviderInterface
{
public function register(Container $container)
{
- $log = new Logger('grav');
- $log_file = LOG_DIR.'grav.log';
+ $container['log'] = function ($c) {
+ $log = new Logger('grav');
- $log->pushHandler(new StreamHandler($log_file, Logger::DEBUG));
+ /** @var UniformResourceLocator $locator */
+ $locator = $c['locator'];
- $container['log'] = $log;
+ $log_file = $locator->findResource('log://grav.log', true, true);
+
+ $log->pushHandler(new StreamHandler($log_file, Logger::DEBUG));
+
+ return $log;
+ };
}
}
diff --git a/system/src/Grav/Common/Themes.php b/system/src/Grav/Common/Themes.php
index e3497f542..1ed46d44a 100644
--- a/system/src/Grav/Common/Themes.php
+++ b/system/src/Grav/Common/Themes.php
@@ -278,15 +278,23 @@ class Themes extends Iterator
$locator = $this->grav['locator'];
if ($config->get('system.languages.translations', true)) {
- $languageFiles = array_reverse($locator->findResources("theme://languages" . YAML_EXT));
-
- $languages = [];
- foreach ($languageFiles as $language) {
- $languages[] = CompiledYamlFile::instance($language)->content();
+ $language_file = $locator->findResource("theme://languages" . YAML_EXT);
+ if ($language_file) {
+ $language = CompiledYamlFile::instance($language_file)->content();
+ $this->grav['languages']->mergeRecursive($language);
}
+ $languages_folder = $locator->findResource("theme://languages/");
+ if (file_exists($languages_folder)) {
+ $languages = [];
+ $iterator = new \DirectoryIterator($languages_folder);
- if ($languages) {
- $languages = call_user_func_array('array_replace_recursive', $languages);
+ /** @var \DirectoryIterator $directory */
+ foreach ($iterator as $file) {
+ if ($file->getExtension() != 'yaml') {
+ continue;
+ }
+ $languages[$file->getBasename('.yaml')] = CompiledYamlFile::instance($file->getPathname())->content();
+ }
$this->grav['languages']->mergeRecursive($languages);
}
}
diff --git a/system/src/Grav/Common/Twig/Twig.php b/system/src/Grav/Common/Twig/Twig.php
index e36b5372f..502c2c542 100644
--- a/system/src/Grav/Common/Twig/Twig.php
+++ b/system/src/Grav/Common/Twig/Twig.php
@@ -150,6 +150,13 @@ class Twig
}
$this->twig->addExtension(new TwigExtension());
+ // enable the Intl Twig extension if translations are enabled
+ if (count($config->get('system.languages.supported', [])) > 0) {
+ if (class_exists('\Twig_Extensions_Extension_Intl')) {
+ $this->twig->addExtension(new \Twig_Extensions_Extension_Intl());
+ }
+ }
+
$this->grav->fireEvent('onTwigExtensions');
// Set some standard variables for twig
diff --git a/system/src/Grav/Common/Twig/TwigExtension.php b/system/src/Grav/Common/Twig/TwigExtension.php
index 2fc18b9d9..fb37f934c 100644
--- a/system/src/Grav/Common/Twig/TwigExtension.php
+++ b/system/src/Grav/Common/Twig/TwigExtension.php
@@ -63,7 +63,6 @@ class TwigExtension extends \Twig_Extension
new \Twig_SimpleFilter('*ize', [$this, 'inflectorFilter']),
new \Twig_SimpleFilter('absolute_url', [$this, 'absoluteUrlFilter']),
new \Twig_SimpleFilter('contains', [$this, 'containsFilter']),
- new \Twig_SimpleFilter('date', [$this, 'dateFilter'], array('needs_environment' => true)),
new \Twig_SimpleFilter('defined', [$this, 'definedDefaultFilter']),
new \Twig_SimpleFilter('ends_with', [$this, 'endsWithFilter']),
new \Twig_SimpleFilter('fieldName', [$this, 'fieldNameFilter']),
@@ -318,67 +317,6 @@ class TwigExtension extends \Twig_Extension
return (strpos($haystack, $needle) !== false);
}
- /**
- * Overrides the built-in date filter to output dates in the set locale
- *
- * @param TwigEnvironment $env A Twig_Environment instance
- * @param DateTime|DateTimeInterface|DateInterval|string $date A date
- * @param string|null $format The target format, null to use the default
- * @param DateTimeZone|string|null|false $timezone The target timezone, null to use the default, false to leave unchanged
- *
- * @return string The formatted date
- */
- function dateFilter(TwigEnvironment $env, $date, $format = null, $timezone = null)
- {
- $this->grav->setLocale();
-
- if (null === $format) {
- $formats = $env->getExtension('core')->getDateFormat();
- $format = $date instanceof DateInterval ? $formats[1] : $formats[0];
- }
-
- if ($date instanceof DateInterval) {
- return strftime($this->dateFormatToStrftime($format), $date->getTimestamp());
- }
-
- return strftime($this->dateFormatToStrftime($format), \twig_date_converter($env, $date, $timezone)->getTimestamp());
- }
-
- /**
- * Convert a date format to a strftime format
- *
- * Timezone conversion is done for unix. Windows users must exchange %z and %Z.
- *
- * Unsupported date formats : S, n, t, L, B, G, u, e, I, P, Z, c, r
- * Unsupported strftime formats : %U, %W, %C, %g, %r, %R, %T, %X, %c, %D, %F, %x
- *
- * @param string $dateFormat a date format
- * @return string
- *
- * @author https://secure.php.net/manual/it/function.strftime.php#96424
- */
- public function dateFormatToStrftime($dateFormat)
- {
- $caracs = array(
- // Day - no strf eq : S
- 'd' => '%d', 'D' => '%a', 'j' => '%e', 'l' => '%A', 'N' => '%u', 'w' => '%w', 'z' => '%j',
- // Week - no date eq : %U, %W
- 'W' => '%V',
- // Month - no strf eq : n, t
- 'F' => '%B', 'm' => '%m', 'M' => '%b',
- // Year - no strf eq : L; no date eq : %C, %g
- 'o' => '%G', 'Y' => '%Y', 'y' => '%y',
- // Time - no strf eq : B, G, u; no date eq : %r, %R, %T, %X
- 'a' => '%P', 'A' => '%p', 'g' => '%l', 'h' => '%I', 'H' => '%H', 'i' => '%M', 's' => '%S',
- // Timezone - no strf eq : e, I, P, Z
- 'O' => '%z', 'T' => '%Z',
- // Full Date / Time - no strf eq : c, r; no date eq : %c, %D, %F, %x
- 'U' => '%s'
- );
-
- return strtr((string)$dateFormat, $caracs);
- }
-
/**
* displays a facebook style 'time ago' formatted date/time
*
diff --git a/system/src/Grav/Common/Uri.php b/system/src/Grav/Common/Uri.php
index 0c708ca85..7a9e536e7 100644
--- a/system/src/Grav/Common/Uri.php
+++ b/system/src/Grav/Common/Uri.php
@@ -159,17 +159,12 @@ class Uri
private function buildEnvironment()
{
- // set hostname
- $address = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '::1';
-
// check for localhost variations
- if ($this->name == 'localhost' || $address == '::1' || $address == '127.0.0.1') {
- $env = 'localhost';
+ if ($this->name == '127.0.0.1' || $this->name== '::1') {
+ return 'localhost';
} else {
- $env = $this->name;
+ return $this->name;
}
-
- return $env;
}
/**
@@ -479,7 +474,7 @@ class Uri
* Gets the Fragment portion of a URI (eg #target)
*
* @param null $fragment
- *
+ *
* @return null
*/
public function fragment($fragment = null)
@@ -601,6 +596,27 @@ class Uri
return $this->base;
}
+ /**
+ * Return the base relative URL including the language prefix
+ * or the base relative url if multilanguage is not enabled
+ *
+ * @return String The base of the URI
+ */
+ public function baseIncludingLanguage()
+ {
+ $grav = Grav::instance();
+
+ // Link processing should prepend language
+ $language = $grav['language'];
+ $language_append = '';
+ if ($language->enabled()) {
+ $language_append = $language->getLanguageURLPrefix();
+ }
+
+ $base = $grav['base_url_relative'];
+ return rtrim($base . $grav['pages']->base(), '/') . $language_append;
+ }
+
/**
* Return root URL to the site.
*
diff --git a/system/src/Grav/Console/Cli/DevTools/DevToolsCommand.php b/system/src/Grav/Console/Cli/DevTools/DevToolsCommand.php
new file mode 100644
index 000000000..dbdf1c8ff
--- /dev/null
+++ b/system/src/Grav/Console/Cli/DevTools/DevToolsCommand.php
@@ -0,0 +1,192 @@
+grav = Grav::instance(array('loader' => $autoload));
+ $this->grav['config']->init();
+ $this->grav['uri']->init();
+ $this->grav['streams'];
+ $this->inflector = $this->grav['inflector'];
+ $this->locator = $this->grav['locator'];
+ $this->twig = new Twig($this->grav);
+ $this->gpm = new GPM(true);
+
+ //Add `theme://` to prevent fail
+ $this->locator->addPath('theme', '', []);
+ }
+
+ /**
+ * Copies the component type and renames accordingly
+ */
+ protected function createComponent()
+ {
+ $name = $this->component['name'];
+ $folderName = strtolower($this->inflector->hyphenize($name));
+ $type = $this->component['type'];
+
+ $template = $this->component['template'];
+ $templateFolder = __DIR__ . '/components/' . $type . DS . $template;
+ $componentFolder = $this->locator->findResource($type . 's://') . DS . $folderName;
+
+ //Copy All files to component folder
+ try {
+ Folder::copy($templateFolder, $componentFolder);
+ } catch (\Exception $e) {
+ $this->output->writeln("