diff --git a/composer.json b/composer.json index a467f0716..016c37c95 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "mrclay/minify": "~2.2", "donatj/phpuseragentparser": "~0.3", "pimple/pimple": "~3.0", - "rockettheme/toolbox": "~1.2", + "rockettheme/toolbox": "dev-develop", "maximebf/debugbar": "~1.10", "ext-mbstring": "*", "ext-openssl": "*", diff --git a/composer.lock b/composer.lock index db14032e4..ae991c0e2 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": "e7fd6dac2d1a99dcd78c5572dd90a333", - "content-hash": "812ba1911705385948bc6b15c197f9b4", + "hash": "dafb943040964731630ab4992b1ea540", + "content-hash": "93e9fc9ecc82e91296f8a21aa9756123", "packages": [ { "name": "doctrine/cache", @@ -364,48 +364,6 @@ ], "time": "2015-05-30 19:24:37" }, - { - "name": "ircmaxell/password-compat", - "version": "v1.0.4", - "source": { - "type": "git", - "url": "https://github.com/ircmaxell/password_compat.git", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c", - "shasum": "" - }, - "require-dev": { - "phpunit/phpunit": "4.*" - }, - "type": "library", - "autoload": { - "files": [ - "lib/password.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Anthony Ferrara", - "email": "ircmaxell@php.net", - "homepage": "http://blog.ircmaxell.com" - } - ], - "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash", - "homepage": "https://github.com/ircmaxell/password_compat", - "keywords": [ - "hashing", - "password" - ], - "time": "2014-11-20 16:49:30" - }, { "name": "maximebf/debugbar", "version": "v1.11.1", @@ -469,16 +427,16 @@ }, { "name": "monolog/monolog", - "version": "1.17.2", + "version": "1.18.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "bee7f0dc9c3e0b69a6039697533dca1e845c8c24" + "reference": "e19b764b5c855580e8ffa7e615f72c10fd2f99cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bee7f0dc9c3e0b69a6039697533dca1e845c8c24", - "reference": "bee7f0dc9c3e0b69a6039697533dca1e845c8c24", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/e19b764b5c855580e8ffa7e615f72c10fd2f99cc", + "reference": "e19b764b5c855580e8ffa7e615f72c10fd2f99cc", "shasum": "" }, "require": { @@ -507,6 +465,7 @@ "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", "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-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", @@ -516,7 +475,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.16.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -542,7 +501,7 @@ "logging", "psr-3" ], - "time": "2015-10-14 12:51:02" + "time": "2016-03-01 18:00:40" }, { "name": "mrclay/minify", @@ -675,27 +634,26 @@ }, { "name": "rockettheme/toolbox", - "version": "1.2.1", + "version": "dev-develop", "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "22273dff75748eb1f51fcfa41fa85d8eff1f9f6c" + "reference": "88c9e928a5e4fee08ceb606265f02b1e89d37e1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/22273dff75748eb1f51fcfa41fa85d8eff1f9f6c", - "reference": "22273dff75748eb1f51fcfa41fa85d8eff1f9f6c", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/88c9e928a5e4fee08ceb606265f02b1e89d37e1e", + "reference": "88c9e928a5e4fee08ceb606265f02b1e89d37e1e", "shasum": "" }, "require": { - "ircmaxell/password-compat": "1.0.*", "php": ">=5.4.0", "pimple/pimple": "~3.0", - "symfony/event-dispatcher": "~2.5", - "symfony/yaml": "~2.5" + "symfony/event-dispatcher": ">2.5", + "symfony/yaml": ">2.5" }, "require-dev": { - "phpunit/phpunit": "4.0.*" + "phpunit/phpunit": "~5.1.5" }, "type": "library", "autoload": { @@ -720,7 +678,7 @@ "php", "rockettheme" ], - "time": "2016-02-11 19:08:48" + "time": "2016-03-03 19:03:07" }, { "name": "symfony/console", @@ -1134,1522 +1092,7 @@ "time": "2016-01-25 21:22:18" } ], - "packages-dev": [ - { - "name": "codeception/codeception", - "version": "2.1.6", - "source": { - "type": "git", - "url": "https://github.com/Codeception/Codeception.git", - "reference": "b199941f5e59d1e7fd32d78296c8ab98db873d89" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeception/Codeception/zipball/b199941f5e59d1e7fd32d78296c8ab98db873d89", - "reference": "b199941f5e59d1e7fd32d78296c8ab98db873d89", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-mbstring": "*", - "facebook/webdriver": ">=1.0.1", - "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" - }, - "require-dev": { - "codeception/specify": "~0.3", - "facebook/php-sdk-v4": "~4.0", - "flow/jsonpath": "~0.2", - "monolog/monolog": "~1.8", - "pda/pheanstalk": "~2.0", - "videlalvaro/php-amqplib": "~2.4" - }, - "suggest": { - "codeception/phpbuiltinserver": "Extension to start and stop PHP built-in web server for your tests", - "codeception/specify": "BDD-style code blocks", - "codeception/verify": "BDD-style assertions", - "monolog/monolog": "Log test steps", - "phpseclib/phpseclib": "Extension required to use the SFTP option in the FTP Module." - }, - "bin": [ - "codecept" - ], - "type": "library", - "extra": { - "branch-alias": [] - }, - "autoload": { - "psr-4": { - "Codeception\\": "src\\Codeception", - "Codeception\\Extension\\": "ext" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Bodnarchuk", - "email": "davert@mail.ua", - "homepage": "http://codegyre.com" - } - ], - "description": "BDD-style testing framework", - "homepage": "http://codeception.com/", - "keywords": [ - "BDD", - "TDD", - "acceptance testing", - "functional testing", - "unit testing" - ], - "time": "2016-02-09 22:27:48" - }, - { - "name": "doctrine/instantiator", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", - "shasum": "" - }, - "require": { - "php": ">=5.3,<8.0-DEV" - }, - "require-dev": { - "athletic/athletic": "~0.1.8", - "ext-pdo": "*", - "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", - "keywords": [ - "constructor", - "instantiate" - ], - "time": "2015-06-14 21:17:01" - }, - { - "name": "facebook/webdriver", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/facebook/php-webdriver.git", - "reference": "1c98108ba3eb435b681655764de11502a0653705" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/1c98108ba3eb435b681655764de11502a0653705", - "reference": "1c98108ba3eb435b681655764de11502a0653705", - "shasum": "" - }, - "require": { - "php": ">=5.3.19" - }, - "require-dev": { - "phpunit/phpunit": "4.6.*" - }, - "suggest": { - "phpdocumentor/phpdocumentor": "2.*" - }, - "type": "library", - "autoload": { - "psr-4": { - "Facebook\\WebDriver\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "description": "A PHP client for WebDriver", - "homepage": "https://github.com/facebook/php-webdriver", - "keywords": [ - "facebook", - "php", - "selenium", - "webdriver" - ], - "time": "2015-12-31 15:58:49" - }, - { - "name": "fzaninotto/faker", - "version": "v1.5.0", - "source": { - "type": "git", - "url": "https://github.com/fzaninotto/Faker.git", - "reference": "d0190b156bcca848d401fb80f31f504f37141c8d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/d0190b156bcca848d401fb80f31f504f37141c8d", - "reference": "d0190b156bcca848d401fb80f31f504f37141c8d", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~1.5" - }, - "suggest": { - "ext-intl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.5.x-dev" - } - }, - "autoload": { - "psr-4": { - "Faker\\": "src/Faker/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "François Zaninotto" - } - ], - "description": "Faker is a PHP library that generates fake data for you.", - "keywords": [ - "data", - "faker", - "fixtures" - ], - "time": "2015-05-29 06:29:14" - }, - { - "name": "guzzlehttp/guzzle", - "version": "6.1.1", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/c6851d6e48f63b69357cbfa55bca116448140e0c", - "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c", - "shasum": "" - }, - "require": { - "guzzlehttp/promises": "~1.0", - "guzzlehttp/psr7": "~1.1", - "php": ">=5.5.0" - }, - "require-dev": { - "ext-curl": "*", - "phpunit/phpunit": "~4.0", - "psr/log": "~1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.1-dev" - } - }, - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "GuzzleHttp\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle is a PHP HTTP client library", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" - ], - "time": "2015-11-23 00:47:50" - }, - { - "name": "guzzlehttp/promises", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/b1e1c0d55f8083c71eda2c28c12a228d708294ea", - "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea", - "shasum": "" - }, - "require": { - "php": ">=5.5.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle promises library", - "keywords": [ - "promise" - ], - "time": "2015-10-15 22:28:00" - }, - { - "name": "guzzlehttp/psr7", - "version": "1.2.3", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "2e89629ff057ebb49492ba08e6995d3a6a80021b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/2e89629ff057ebb49492ba08e6995d3a6a80021b", - "reference": "2e89629ff057ebb49492ba08e6995d3a6a80021b", - "shasum": "" - }, - "require": { - "php": ">=5.4.0", - "psr/http-message": "~1.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "PSR-7 message implementation", - "keywords": [ - "http", - "message", - "stream", - "uri" - ], - "time": "2016-02-18 21:54:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "suggest": { - "dflydev/markdown": "~1.0", - "erusev/parsedown": "~1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "phpDocumentor": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "mike.vanriel@naenius.com" - } - ], - "time": "2015-02-03 12:10:50" - }, - { - "name": "phpspec/prophecy", - "version": "v1.6.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3c91bdf81797d725b14cb62906f9a4ce44235972", - "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "~2.0", - "sebastian/comparator": "~1.1", - "sebastian/recursion-context": "~1.0" - }, - "require-dev": { - "phpspec/phpspec": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.5.x-dev" - } - }, - "autoload": { - "psr-0": { - "Prophecy\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "time": "2016-02-15 07:46:21" - }, - { - "name": "phpunit/php-code-coverage", - "version": "2.2.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": "~1.3", - "phpunit/php-text-template": "~1.2", - "phpunit/php-token-stream": "~1.3", - "sebastian/environment": "^1.3.2", - "sebastian/version": "~1.0" - }, - "require-dev": { - "ext-xdebug": ">=2.1.4", - "phpunit/phpunit": "~4" - }, - "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.2.1", - "ext-xmlwriter": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "time": "2015-10-06 15:47:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2015-06-21 13:08:43" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2015-06-21 13:50:34" - }, - { - "name": "phpunit/php-timer", - "version": "1.0.7", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "time": "2015-06-21 08:01:12" - }, - { - "name": "phpunit/php-token-stream", - "version": "1.4.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "time": "2015-09-15 10:49:45" - }, - { - "name": "phpunit/phpunit", - "version": "4.8.23", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "6e351261f9cd33daf205a131a1ba61c6d33bd483" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6e351261f9cd33daf205a131a1ba61c6d33bd483", - "reference": "6e351261f9cd33daf205a131a1ba61c6d33bd483", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=5.3.3", - "phpspec/prophecy": "^1.3.1", - "phpunit/php-code-coverage": "~2.1", - "phpunit/php-file-iterator": "~1.4", - "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": ">=1.0.6", - "phpunit/phpunit-mock-objects": "~2.3", - "sebastian/comparator": "~1.1", - "sebastian/diff": "~1.2", - "sebastian/environment": "~1.3", - "sebastian/exporter": "~1.2", - "sebastian/global-state": "~1.0", - "sebastian/version": "~1.0", - "symfony/yaml": "~2.1|~3.0" - }, - "suggest": { - "phpunit/php-invoker": "~1.1" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.8.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "time": "2016-02-11 14:56:33" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "2.3.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": ">=5.3.3", - "phpunit/php-text-template": "~1.2", - "sebastian/exporter": "~1.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "time": "2015-10-02 06:51:40" - }, - { - "name": "psr/http-message", - "version": "1.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", - "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "time": "2015-05-04 20:22:00" - }, - { - "name": "sebastian/comparator", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "http://www.github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "time": "2015-07-26 15:48:44" - }, - { - "name": "sebastian/diff", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff" - ], - "time": "2015-12-08 07:14:41" - }, - { - "name": "sebastian/environment", - "version": "1.3.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf", - "reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "time": "2016-02-26 18:40:46" - }, - { - "name": "sebastian/exporter", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "7ae5513327cb536431847bcc0c10edba2701064e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e", - "reference": "7ae5513327cb536431847bcc0c10edba2701064e", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "sebastian/recursion-context": "~1.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "time": "2015-06-21 07:55:53" - }, - { - "name": "sebastian/global-state", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "time": "2015-10-12 03:26:01" - }, - { - "name": "sebastian/recursion-context", - "version": "1.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "913401df809e99e4f47b27cdd781f4a258d58791" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", - "reference": "913401df809e99e4f47b27cdd781f4a258d58791", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2015-11-11 19:50:13" - }, - { - "name": "sebastian/version", - "version": "1.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "shasum": "" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "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" - }, - { - "name": "symfony/browser-kit", - "version": "v3.0.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/browser-kit.git", - "reference": "dde849a0485b70a24b36f826ed3fb95b904d80c3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/dde849a0485b70a24b36f826ed3fb95b904d80c3", - "reference": "dde849a0485b70a24b36f826ed3fb95b904d80c3", - "shasum": "" - }, - "require": { - "php": ">=5.5.9", - "symfony/dom-crawler": "~2.8|~3.0" - }, - "require-dev": { - "symfony/css-selector": "~2.8|~3.0", - "symfony/process": "~2.8|~3.0" - }, - "suggest": { - "symfony/process": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\BrowserKit\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony BrowserKit Component", - "homepage": "https://symfony.com", - "time": "2016-01-27 11:34:55" - }, - { - "name": "symfony/css-selector", - "version": "v3.0.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/css-selector.git", - "reference": "6605602690578496091ac20ec7a5cbd160d4dff4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/6605602690578496091ac20ec7a5cbd160d4dff4", - "reference": "6605602690578496091ac20ec7a5cbd160d4dff4", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\CssSelector\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jean-François Simon", - "email": "jeanfrancois.simon@sensiolabs.com" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony CssSelector Component", - "homepage": "https://symfony.com", - "time": "2016-01-27 05:14:46" - }, - { - "name": "symfony/dom-crawler", - "version": "v3.0.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/dom-crawler.git", - "reference": "981c8edb4538f88ba976ed44bdcaa683fce3d6c6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/981c8edb4538f88ba976ed44bdcaa683fce3d6c6", - "reference": "981c8edb4538f88ba976ed44bdcaa683fce3d6c6", - "shasum": "" - }, - "require": { - "php": ">=5.5.9", - "symfony/polyfill-mbstring": "~1.0" - }, - "require-dev": { - "symfony/css-selector": "~2.8|~3.0" - }, - "suggest": { - "symfony/css-selector": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\DomCrawler\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony DomCrawler Component", - "homepage": "https://symfony.com", - "time": "2016-02-28 16:24:34" - }, - { - "name": "symfony/finder", - "version": "v3.0.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "623bda0abd9aa29e529c8e9c08b3b84171914723" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/623bda0abd9aa29e529c8e9c08b3b84171914723", - "reference": "623bda0abd9aa29e529c8e9c08b3b84171914723", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Finder Component", - "homepage": "https://symfony.com", - "time": "2016-01-27 05:14:46" - } - ], + "packages-dev": null, "aliases": [ { "alias": "1.6.0", @@ -2660,7 +1103,8 @@ ], "minimum-stability": "stable", "stability-flags": { - "erusev/parsedown": 20 + "erusev/parsedown": 20, + "rockettheme/toolbox": 20 }, "prefer-stable": false, "prefer-lowest": false, diff --git a/system/blueprints/pages/default.yaml b/system/blueprints/pages/default.yaml index 1b9b166ee..472fb3b62 100644 --- a/system/blueprints/pages/default.yaml +++ b/system/blueprints/pages/default.yaml @@ -29,7 +29,6 @@ form: content: type: markdown - showPreview: true validate: type: textarea diff --git a/system/blueprints/pages/modular_raw.yaml b/system/blueprints/pages/modular_raw.yaml index 393cde5fd..020ab4a1d 100644 --- a/system/blueprints/pages/modular_raw.yaml +++ b/system/blueprints/pages/modular_raw.yaml @@ -19,13 +19,22 @@ form: fields: frontmatter: - type: 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 - showPreview: true uploads: type: pagemedia diff --git a/system/blueprints/pages/raw.yaml b/system/blueprints/pages/raw.yaml index bed82d593..a195ab7ed 100644 --- a/system/blueprints/pages/raw.yaml +++ b/system/blueprints/pages/raw.yaml @@ -19,13 +19,22 @@ form: fields: frontmatter: - type: 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 - showPreview: true uploads: type: pagemedia diff --git a/system/src/Grav/Common/Assets.php b/system/src/Grav/Common/Assets.php index 102a49e6d..3a9a19d17 100644 --- a/system/src/Grav/Common/Assets.php +++ b/system/src/Grav/Common/Assets.php @@ -177,13 +177,14 @@ class Assets */ public function init() { + $grav = Grav::instance(); /** @var Config $config */ - $config = Grav::instance()['config']; - $base_url = Grav::instance()['base_url']; + $config = $grav['config']; + $base_url = $grav['base_url']; $asset_config = (array)$config->get('system.assets'); /** @var UniformResourceLocator $locator */ - $locator = Grav::instance()['locator']; + $locator = $grav['locator']; $this->assets_dir = $locator->findResource('asset://') . DS; $this->assets_url = $locator->findResource('asset://', false); diff --git a/system/src/Grav/Common/Backup/ZipBackup.php b/system/src/Grav/Common/Backup/ZipBackup.php index 94cfc4167..e69b4431f 100644 --- a/system/src/Grav/Common/Backup/ZipBackup.php +++ b/system/src/Grav/Common/Backup/ZipBackup.php @@ -40,10 +40,9 @@ class ZipBackup if (!$destination) { $destination = Grav::instance()['locator']->findResource('backup://', true); - if (!$destination) + if (!$destination) { throw new \RuntimeException('The backup folder is missing.'); - - Folder::mkdir($destination); + } } $name = Grav::instance()['config']->get('site.title', basename(GRAV_ROOT)); diff --git a/system/src/Grav/Common/Cache.php b/system/src/Grav/Common/Cache.php index 65dcfcf0e..81567d5cf 100644 --- a/system/src/Grav/Common/Cache.php +++ b/system/src/Grav/Common/Cache.php @@ -230,27 +230,29 @@ class Cache extends Getters /** * Deletes an item in the cache based on the id * - * @param $id the id of the cached data entry - * @return bool true if the item was deleted successfully + * @param string $id the id of the cached data entry + * @return bool true if the item was deleted successfully */ public function delete($id) { if ($this->enabled) { return $this->driver->delete($id); } + return false; } /** * Returns a boolean state of whether or not the item exists in the cache based on id key * - * @param $id the id of the cached data entry - * @return bool true if the cached items exists + * @param string $id the id of the cached data entry + * @return bool true if the cached items exists */ public function contains($id) { if ($this->enabled) { return $this->driver->contains(($id)); } + return false; } /** @@ -311,7 +313,7 @@ class Cache extends Getters $anything = true; } } elseif (is_dir($file)) { - if (@Folder::delete($file)) { + if (Folder::delete($file)) { $anything = true; } } diff --git a/system/src/Grav/Common/Config/CompiledBase.php b/system/src/Grav/Common/Config/CompiledBase.php index 9f51d7d26..833b4da7a 100644 --- a/system/src/Grav/Common/Config/CompiledBase.php +++ b/system/src/Grav/Common/Config/CompiledBase.php @@ -226,7 +226,7 @@ abstract class CompiledBase 'timestamp' => time(), 'checksum' => $this->checksum(), 'files' => $this->files, - 'data' => $this->object->toArray() + 'data' => $this->getState() ]; $file->save($cache); @@ -235,4 +235,9 @@ abstract class CompiledBase $this->modified(); } + + protected function getState() + { + return $this->object->toArray(); + } } diff --git a/system/src/Grav/Common/Config/CompiledBlueprints.php b/system/src/Grav/Common/Config/CompiledBlueprints.php index d78a0e04e..b7614b501 100644 --- a/system/src/Grav/Common/Config/CompiledBlueprints.php +++ b/system/src/Grav/Common/Config/CompiledBlueprints.php @@ -1,8 +1,9 @@ checksum = false to disable this check. + * + * @return bool|string + */ + public function checksum() + { + if (!isset($this->checksum)) { + $this->checksum = md5(json_encode($this->files) . json_encode($this->getTypes()) . $this->version); + } + + return $this->checksum; + } + /** * Create configuration object. * @@ -26,24 +43,70 @@ class CompiledBlueprints extends CompiledBase */ protected function createObject(array $data = []) { - $this->object = new Blueprints($data); + $this->object = (new BlueprintSchema($data))->setTypes($this->getTypes()); + } + + /** + * Get list of form field types. + * + * @return array + */ + protected function getTypes() + { + return Grav::instance()['plugins']->formFieldTypes ?: []; } /** * Finalize configuration object. */ - protected function finalizeObject() {} + protected function finalizeObject() + { + } /** * Load single configuration file and append it to the correct position. * * @param string $name Name of the position. - * @param string $filename File to be loaded. + * @param array $files Files to be loaded. */ - protected function loadFile($name, $filename) + protected function loadFile($name, $files) { - $file = CompiledYamlFile::instance($filename); - $this->object->embed($name, $file->content(), '/'); - $file->free(); + // Load blueprint file. + $blueprint = new Blueprint($files); + + $this->object->embed($name, $blueprint->load()->toArray(), '/', true); + } + + /** + * Load and join all configuration files. + * + * @return bool + * @internal + */ + protected function loadFiles() + { + $this->createObject(); + + // Convert file list into parent list. + $list = []; + foreach ($this->files as $files) { + foreach ($files as $name => $item) { + $list[$name][] = $this->path . $item['file']; + } + } + + // Load files. + foreach ($list as $name => $files) { + $this->loadFile($name, $files); + } + + $this->finalizeObject(); + + return true; + } + + protected function getState() + { + return $this->object->getState(); } } diff --git a/system/src/Grav/Common/Config/Setup.php b/system/src/Grav/Common/Config/Setup.php index 8b6b70750..61f4dc9f2 100644 --- a/system/src/Grav/Common/Config/Setup.php +++ b/system/src/Grav/Common/Config/Setup.php @@ -4,6 +4,7 @@ namespace Grav\Common\Config; use Grav\Common\File\CompiledYamlFile; use Grav\Common\Data\Data; use Grav\Common\Utils; +use Pimple\Container; use RocketTheme\Toolbox\File\YamlFile; use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; @@ -113,12 +114,12 @@ class Setup extends Data ], ]; + /** + * @param Container|array $container + */ public function __construct($container) { - $environment = $container['uri']->environment(); - if (!$environment) { - $environment = 'localhost'; - } + $environment = $container['uri']->environment() ?: 'localhost'; // Pre-load setup.php which contains our initial configuration. // Configuration may contain dynamic parts, which is why we need to always load it. diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index 099dde4d9..a48a92618 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -1,87 +1,40 @@ 1]; - /** - * @param string $name - * @param array $data - * @param Blueprints $context + * @var string */ - public function __construct($name, array $data = array(), Blueprints $context = null) - { - $this->name = $name; - $this->items = $data; - $this->context = $context; - } + protected $context = 'blueprints://'; /** - * Set filter for inherited properties. + * @var BlueprintSchema + */ + protected $blueprintSchema; + + /** + * Get nested structure containing default values defined in the blueprints. * - * @param array $filter List of field names to be inherited. - */ - public function setFilter(array $filter) - { - $this->filter = array_flip($filter); - } - - /** - * Return all form fields. + * Fields without default value are ignored in the list. * * @return array */ - public function fields() + public function getDefaults() { - if (!isset($this->fields)) { - $this->fields = []; - $this->embed('', $this->items); - } + $this->initInternals(); - return $this->fields; - } - - /** - * Validate data against blueprints. - * - * @param array $data - * @throws \RuntimeException - */ - public function validate(array $data) - { - // Initialize data - $this->fields(); - - try { - $this->validateArray($data, $this->nested); - } catch (\RuntimeException $e) { - $language = Grav::instance()['language']; - $message = sprintf($language->translate('FORM.VALIDATION_FAIL', null, true) . ' %s', $e->getMessage()); - throw new \RuntimeException($message); - } + return $this->blueprintSchema->getDefaults(); } /** @@ -89,26 +42,15 @@ class Blueprint implements \ArrayAccess, ExportInterface * * @param array $data1 * @param array $data2 + * @param string $name Optional + * @param string $separator Optional * @return array */ - public function mergeData(array $data1, array $data2) + public function mergeData(array $data1, array $data2, $name = null, $separator = '.') { - // Initialize data - $this->fields(); - return $this->mergeArrays($data1, $data2, $this->nested); - } + $this->initInternals(); - /** - * Filter data by using blueprints. - * - * @param array $data - * @return array - */ - public function filter(array $data) - { - // Initialize data - $this->fields(); - return $this->filterArray($data, $this->nested); + return $this->blueprintSchema->mergeData($data1, $data2, $name, $separator); } /** @@ -120,357 +62,158 @@ class Blueprint implements \ArrayAccess, ExportInterface */ public function extra(array $data, $prefix = '') { - // Initialize data - $this->fields(); - $rules = $this->nested; + $this->initInternals(); - // Drill down to prefix level - if (!empty($prefix)) { - $parts = explode('.', trim($prefix, '.')); - foreach ($parts as $part) { - $rules = isset($rules[$part]) ? $rules[$part] : []; - } - } - - return $this->extraArray($data, $rules, $prefix); + return $this->blueprintSchema->extra($data, $prefix); } /** - * Extend blueprint with another blueprint. + * Validate data against blueprints. * - * @param Blueprint $extends - * @param bool $append - */ - public function extend(Blueprint $extends, $append = false) - { - $blueprints = $append ? $this->items : $extends->toArray(); - $appended = $append ? $extends->toArray() : $this->items; - - $bref_stack = array(&$blueprints); - $head_stack = array($appended); - - do { - end($bref_stack); - - $bref = &$bref_stack[key($bref_stack)]; - $head = array_pop($head_stack); - - unset($bref_stack[key($bref_stack)]); - - foreach (array_keys($head) as $key) { - if (isset($key, $bref[$key]) && is_array($bref[$key]) && is_array($head[$key])) { - $bref_stack[] = &$bref[$key]; - $head_stack[] = $head[$key]; - } else { - $bref = array_merge($bref, array($key => $head[$key])); - } - } - } while (count($head_stack)); - - $this->items = $blueprints; - } - - /** - * Convert object into an array. - * - * @return array - */ - public function getState() - { - return ['name' => $this->name, 'items' => $this->items, 'rules' => $this->rules, 'nested' => $this->nested]; - } - - /** - * Embed an array to the blueprint. - * - * @param $name - * @param array $value - * @param string $separator - */ - public function embed($name, array $value, $separator = '.') - { - - if (!isset($value['form']['fields']) || !is_array($value['form']['fields'])) { - return; - } - // Initialize data - $this->fields(); - $prefix = $name ? strtr($name, $separator, '.') . '.' : ''; - $params = array_intersect_key($this->filter, $value); - $this->parseFormFields($value['form']['fields'], $params, $prefix, $this->fields); - } - - /** - * @param array $data - * @param array $rules + * @param array $data * @throws \RuntimeException - * @internal */ - protected function validateArray(array $data, array $rules) + public function validate(array $data) { - $this->checkRequired($data, $rules); + $this->initInternals(); - foreach ($data as $key => $field) { - $val = isset($rules[$key]) ? $rules[$key] : null; - $rule = is_string($val) ? $this->rules[$val] : null; - - if ($rule) { - // Item has been defined in blueprints. - Validation::validate($field, $rule); - } elseif (is_array($field) && is_array($val)) { - // Array has been defined in blueprints. - $this->validateArray($field, $val); - } elseif (isset($this->items['form']['validation']) && $this->items['form']['validation'] == 'strict') { - // Undefined/extra item. - throw new \RuntimeException(sprintf('%s is not defined in blueprints', $key)); - } - } + $this->blueprintSchema->validate($data); } /** - * @param array $data - * @param array $rules - * @return array - * @internal - */ - protected function filterArray(array $data, array $rules) - { - $results = array(); - foreach ($data as $key => $field) { - $val = isset($rules[$key]) ? $rules[$key] : null; - $rule = is_string($val) ? $this->rules[$val] : null; - - if ($rule) { - // Item has been defined in blueprints. - $field = Validation::filter($field, $rule); - } elseif (is_array($field) && is_array($val)) { - // Array has been defined in blueprints. - $field = $this->filterArray($field, $val); - } elseif (isset($this->items['form']['validation']) && $this->items['form']['validation'] == 'strict') { - $field = null; - } - - if (isset($field) && (!is_array($field) || !empty($field))) { - $results[$key] = $field; - } - } - - return $results; - } - - /** - * @param array $data1 - * @param array $data2 - * @param array $rules - * @return array - * @internal - */ - protected function mergeArrays(array $data1, array $data2, array $rules) - { - foreach ($data2 as $key => $field) { - $val = isset($rules[$key]) ? $rules[$key] : null; - $rule = is_string($val) ? $this->rules[$val] : null; - - if (!$rule && array_key_exists($key, $data1) && is_array($field) && is_array($val)) { - // Array has been defined in blueprints. - $data1[$key] = $this->mergeArrays($data1[$key], $field, $val); - } else { - // Otherwise just take value from the data2. - $data1[$key] = $field; - } - } - - return $data1; - } - - /** - * @param array $data - * @param array $rules - * @param string $prefix - * @return array - * @internal - */ - protected function extraArray(array $data, array $rules, $prefix) - { - $array = array(); - foreach ($data as $key => $field) { - $val = isset($rules[$key]) ? $rules[$key] : null; - $rule = is_string($val) ? $this->rules[$val] : null; - - if ($rule) { - // Item has been defined in blueprints. - } elseif (is_array($field) && is_array($val)) { - // Array has been defined in blueprints. - $array += $this->ExtraArray($field, $val, $prefix . $key . '.'); - } else { - // Undefined/extra item. - $array[$prefix.$key] = $field; - } - } - return $array; - } - - /** - * Gets all field definitions from the blueprints. - * - * @param array $fields - * @param array $params - * @param string $prefix - * @param array $current - * @internal - */ - protected function parseFormFields(array &$fields, $params, $prefix, array &$current) - { - // Go though all the fields in current level. - foreach ($fields as $key => &$field) { - $current[$key] = &$field; - // Set name from the array key. - $field['name'] = $prefix . $key; - $field += $params; - - if (isset($field['fields']) && (!isset($field['type']) || $field['type'] !== 'list')) { - // Recursively get all the nested fields. - $newParams = array_intersect_key($this->filter, $field); - $this->parseFormFields($field['fields'], $newParams, $prefix, $current[$key]['fields']); - } else if ($field['type'] !== 'ignore') { - $this->rules[$prefix . $key] = &$field; - $this->addProperty($prefix . $key); - - if ($field['type'] === 'list') { - // we loop through list to get the actual field - if (isset($field['fields']) && $field['fields']) { - foreach($field['fields'] as $subName => &$subField) { - $this->parseFormField($subField); - } - } - } else { - $this->parseFormField($field); - } - - if (isset($field['validate']['rule']) && $field['type'] !== 'ignore') { - $field['validate'] += $this->getRule($field['validate']['rule']); - } - } - } - } - /** - * Parses individual field definition - * - * @param array $field - * @internal - */ - protected function parseFormField(&$field) { - foreach ($field as $name => $value) { - // Support nested blueprints. - if ($this->context && $name == '@import') { - $values = (array) $value; - if (!isset($field['fields'])) { - $field['fields'] = array(); - } - foreach ($values as $bname) { - $b = $this->context->get($bname); - $field['fields'] = array_merge($field['fields'], $b->fields()); - } - } - - // Support for callable data values. - elseif (substr($name, 0, 6) == '@data-') { - $property = substr($name, 6); - if (is_array($value)) { - $func = array_shift($value); - } else { - $func = $value; - $value = array(); - } - list($o, $f) = preg_split('/::/', $func); - if (!$f && function_exists($o)) { - $data = call_user_func_array($o, $value); - } elseif ($f && method_exists($o, $f)) { - $data = call_user_func_array(array($o, $f), $value); - } - - // If function returns a value, - if (isset($data)) { - if (isset($field[$property]) && is_array($field[$property]) && is_array($data)) { - // Combine field and @data-field together. - $field[$property] += $data; - } else { - // Or create/replace field with @data-field. - $field[$property] = $data; - } - } - } - - elseif (substr($name, 0, 8) == '@config-') { - $property = substr($name, 8); - $default = isset($field[$property]) ? $field[$property] : null; - $config = Grav::instance()['config']->get($value, $default); - - if (!is_null($config)) { - $field[$property] = $config; - } - } - } - } - - /** - * Add property to the definition. + * Filter data by using blueprints. * - * @param string $path Comma separated path to the property. - * @internal - */ - protected function addProperty($path) - { - $parts = explode('.', $path); - $item = array_pop($parts); - - $nested = &$this->nested; - foreach ($parts as $part) { - if (!isset($nested[$part])) { - $nested[$part] = array(); - } - $nested = &$nested[$part]; - } - - if (!isset($nested[$item])) { - $nested[$item] = $path; - } - } - - /** - * @param $rule + * @param array $data * @return array - * @internal */ - protected function getRule($rule) + public function filter(array $data) { - if (isset($this->items['rules'][$rule]) && is_array($this->items['rules'][$rule])) { - return $this->items['rules'][$rule]; - } - return array(); + $this->initInternals(); + + return $this->blueprintSchema->filter($data); } /** - * @param array $data - * @param array $fields - * @throws \RuntimeException - * @internal + * Initialize validator. */ - protected function checkRequired(array $data, array $fields) + protected function initInternals() { - foreach ($fields as $name => $field) { - if (!is_string($field)) { - continue; + if (!isset($this->blueprintSchema)) { + $types = Grav::instance()['plugins']->formFieldTypes; + + $this->blueprintSchema = new BlueprintSchema; + if ($types) { + $this->blueprintSchema->setTypes($types); } - $field = $this->rules[$field]; - if (isset($field['validate']['required']) - && $field['validate']['required'] === true - && empty($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); - throw new \RuntimeException($message); + $this->blueprintSchema->embed('', $this->items); + $this->blueprintSchema->init(); + } + } + + /** + * @param string $filename + * @return string + */ + protected function loadFile($filename) + { + $file = CompiledYamlFile::instance($filename); + $content = $file->content(); + $file->free(); + + return $content; + } + + /** + * @param string|array $path + * @param string $context + * @return array + */ + protected function getFiles($path, $context = null) + { + if (is_string($path) && !strpos($path, '://')) { + // Resolve filename. + if (isset($this->overrides[$path])) { + $path = $this->overrides[$path]; + } else { + if ($context === null) { + $context = $this->context; + } + if ($context && $context[strlen($context)-1] !== '/') { + $context .= '/'; + } + $path = $context . $path; + + if (!preg_match('/\.yaml$/', $path)) { + $path .= '.yaml'; + } } } + + if (is_string($path) && strpos($path, '://')) { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + + $files = $locator->findResources($path); + } else { + $files = (array) $path; + } + + return $files; + } + + /** + * @param array $field + * @param string $property + * @param array $call + */ + protected function dynamicData(array &$field, $property, array &$call) + { + $params = $call['params']; + + if (is_array($params)) { + $function = array_shift($params); + } else { + $function = $params; + $params = []; + } + + list($o, $f) = preg_split('/::/', $function, 2); + if (!$f) { + if (function_exists($o)) { + $data = call_user_func_array($o, $params); + } + } else { + if (method_exists($o, $f)) { + $data = call_user_func_array(array($o, $f), $params); + } + } + + // If function returns a value, + if (isset($data)) { + if (isset($field[$property]) && is_array($field[$property]) && is_array($data)) { + // Combine field and @data-field together. + $field[$property] += $data; + } else { + // Or create/replace field with @data-field. + $field[$property] = $data; + } + } + } + + /** + * @param array $field + * @param string $property + * @param array $call + */ + protected function dynamicConfig(array &$field, $property, array &$call) + { + $value = $call['params']; + + $default = isset($field[$property]) ? $field[$property] : null; + $config = Grav::instance()['config']->get($value, $default); + + if (!is_null($config)) { + $field[$property] = $config; + } } } diff --git a/system/src/Grav/Common/Data/BlueprintSchema.php b/system/src/Grav/Common/Data/BlueprintSchema.php new file mode 100644 index 000000000..5e8efeb1c --- /dev/null +++ b/system/src/Grav/Common/Data/BlueprintSchema.php @@ -0,0 +1,164 @@ + true, + 'title' => true, + 'help' => true, + 'placeholder' => true, + 'placeholder_key' => true, + 'placeholder_value' => true, + 'fields' => true + ]; + + /** + * Validate data against blueprints. + * + * @param array $data + * @throws \RuntimeException + */ + public function validate(array $data) + { + try { + $messages = $this->validateArray($data, $this->nested); + + } catch (\RuntimeException $e) { + throw (new ValidationException($e->getMessage(), $e->getCode(), $e))->setMessages(); + } + + if (!empty($messages)) { + throw (new ValidationException())->setMessages($messages); + } + } + + /** + * Filter data by using blueprints. + * + * @param array $data + * @return array + */ + public function filter(array $data) + { + return $this->filterArray($data, $this->nested); + } + + /** + * @param array $data + * @param array $rules + * @returns array + * @throws \RuntimeException + * @internal + */ + protected function validateArray(array $data, array $rules) + { + $messages = $this->checkRequired($data, $rules); + + foreach ($data as $key => $field) { + $val = isset($rules[$key]) ? $rules[$key] : null; + $rule = is_string($val) ? $this->items[$val] : null; + + if ($rule) { + // Item has been defined in blueprints. + $messages += Validation::validate($field, $rule); + } elseif (is_array($field) && is_array($val)) { + // Array has been defined in blueprints. + $messages += $this->validateArray($field, $val); + } elseif (isset($rules['validation']) && $rules['validation'] == 'strict') { + // Undefined/extra item. + throw new \RuntimeException(sprintf('%s is not defined in blueprints', $key)); + } + } + + return $messages; + } + + /** + * @param array $data + * @param array $rules + * @return array + * @internal + */ + protected function filterArray(array $data, array $rules) + { + $results = array(); + foreach ($data as $key => $field) { + $val = isset($rules[$key]) ? $rules[$key] : null; + $rule = is_string($val) ? $this->items[$val] : null; + + if ($rule) { + // Item has been defined in blueprints. + $field = Validation::filter($field, $rule); + } elseif (is_array($field) && is_array($val)) { + // Array has been defined in blueprints. + $field = $this->filterArray($field, $val); + } elseif (isset($rules['validation']) && $rules['validation'] == 'strict') { + $field = null; + } + + if (isset($field) && (!is_array($field) || !empty($field))) { + $results[$key] = $field; + } + } + + return $results; + } + + /** + * @param array $data + * @param array $fields + * @return array + */ + protected function checkRequired(array $data, array $fields) + { + $messages = []; + + foreach ($fields as $name => $field) { + if (!is_string($field)) { + continue; + } + $field = $this->items[$field]; + if (isset($field['validate']['required']) + && $field['validate']['required'] === true + && !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); + $messages[$field['name']][] = $message; + } + } + + return $messages; + } + + /** + * @param array $field + * @param string $property + * @param array $call + */ + protected function dynamicConfig(array &$field, $property, array &$call) + { + $value = $call['params']; + + $default = isset($field[$property]) ? $field[$property] : null; + $config = Grav::instance()['config']->get($value, $default); + + if (!is_null($config)) { + $field[$property] = $config; + } + } +} diff --git a/system/src/Grav/Common/Data/Blueprints.php b/system/src/Grav/Common/Data/Blueprints.php index e9f692814..f2f6a0224 100644 --- a/system/src/Grav/Common/Data/Blueprints.php +++ b/system/src/Grav/Common/Data/Blueprints.php @@ -1,7 +1,6 @@ search = $search; } @@ -35,73 +34,7 @@ class Blueprints public function get($type) { if (!isset($this->instances[$type])) { - $parents = []; - if (is_string($this->search)) { - $filename = $this->search . $type . YAML_EXT; - - // Check if search is a stream and resolve the path. - if (strpos($filename, '://')) { - $grav = Grav::instance(); - /** @var UniformResourceLocator $locator */ - $locator = $grav['locator']; - $parents = $locator->findResources($filename); - $filename = array_shift($parents); - } - } else { - $filename = isset($this->search[$type]) ? $this->search[$type] : ''; - } - - if ($filename && is_file($filename)) { - $file = CompiledYamlFile::instance($filename); - $blueprints = $file->content(); - } else { - $blueprints = []; - } - - $blueprint = new Blueprint($type, $blueprints, $this); - - if (isset($blueprints['@extends'])) { - // Extend blueprint by other blueprints. - $extends = (array) $blueprints['@extends']; - - if (is_string(key($extends))) { - $extends = [ $extends ]; - } - - foreach ($extends as $extendConfig) { - $extendType = !is_string($extendConfig) ? empty($extendConfig['type']) ? false : $extendConfig['type'] : $extendConfig; - - if (!$extendType) { - continue; - } elseif ($extendType === '@parent') { - $parentFile = array_shift($parents); - if (!$parentFile || !is_file($parentFile)) { - continue; - } - $blueprints = CompiledYamlFile::instance($parentFile)->content(); - $parent = new Blueprint($type.'-parent', $blueprints, $this); - $blueprint->extend($parent); - continue; - } - - if (is_string($extendConfig) || empty($extendConfig['context'])) { - $context = $this; - } else { - // Load blueprints from external context. - $array = explode('://', $extendConfig['context'], 2); - $scheme = array_shift($array); - $path = array_shift($array); - if ($path) { - $scheme .= '://'; - $extendType = $path ? "{$path}/{$extendType}" : $extendType; - } - $context = new self($scheme); - } - $blueprint->extend($context->get($extendType)); - } - } - - $this->instances[$type] = $blueprint; + $this->instances[$type] = $this->loadFile($type); } return $this->instances[$type]; @@ -117,15 +50,15 @@ class Blueprints if ($this->types === null) { $this->types = array(); - // Check if search is a stream. - if (strpos($this->search, '://')) { - // Stream: use UniformResourceIterator. - $grav = Grav::instance(); - /** @var UniformResourceLocator $locator */ - $locator = $grav['locator']; - $iterator = $locator->getIterator($this->search, null); + $grav = Grav::instance(); + + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + + // Get stream / directory iterator. + if ($locator->isStream($this->search)) { + $iterator = $locator->getIterator($this->search); } else { - // Not a stream: use DirectoryIterator. $iterator = new \DirectoryIterator($this->search); } @@ -138,6 +71,27 @@ class Blueprints $this->types[$name] = ucfirst(strtr($name, '_', ' ')); } } + return $this->types; } + + + /** + * Load blueprint file. + * + * @param string $name Name of the blueprint. + * @return Blueprint + */ + protected function loadFile($name) + { + $blueprint = new Blueprint($name); + + if (is_array($this->search) || is_object($this->search)) { + $blueprint->setOverrides($this->search); + } else { + $blueprint->setContext($this->search); + } + + return $blueprint->load()->init(); + } } diff --git a/system/src/Grav/Common/Data/Data.php b/system/src/Grav/Common/Data/Data.php index 0a0850765..37590aa2f 100644 --- a/system/src/Grav/Common/Data/Data.php +++ b/system/src/Grav/Common/Data/Data.php @@ -5,7 +5,6 @@ use RocketTheme\Toolbox\ArrayTraits\Countable; use RocketTheme\Toolbox\ArrayTraits\Export; use RocketTheme\Toolbox\ArrayTraits\ExportInterface; use RocketTheme\Toolbox\ArrayTraits\NestedArrayAccessWithGetters; -use RocketTheme\Toolbox\Blueprints\Blueprints; use RocketTheme\Toolbox\File\File; use RocketTheme\Toolbox\File\FileInterface; @@ -211,18 +210,18 @@ class Data implements DataInterface, \ArrayAccess, \Countable, ExportInterface */ public function extra() { - return $this->blueprints ? $this->blueprints->extra($this->items) : array(); + return $this->blueprints()->extra($this->items); } /** * Return blueprints. * - * @return Blueprints + * @return Blueprint */ public function blueprints() { if (!$this->blueprints){ - $this->blueprints = new Blueprints; + $this->blueprints = new Blueprint; } elseif (is_callable($this->blueprints)) { // Lazy load blueprints. $blueprints = $this->blueprints; diff --git a/system/src/Grav/Common/Data/Validation.php b/system/src/Grav/Common/Data/Validation.php index b06524a82..9eb9a2bca 100644 --- a/system/src/Grav/Common/Data/Validation.php +++ b/system/src/Grav/Common/Data/Validation.php @@ -2,6 +2,7 @@ namespace Grav\Common\Data; use Grav\Common\Grav; +use Grav\Common\GravTrait; use Symfony\Component\Yaml\Exception\ParseException; use Symfony\Component\Yaml\Parser; @@ -16,53 +17,63 @@ class Validation /** * Validate value against a blueprint field definition. * - * @param mixed $value + * @param $value * @param array $field - * @throws \RuntimeException + * @return array */ public static function validate($value, array $field) { - $validate = isset($field['validate']) ? (array) $field['validate'] : array(); + $messages = []; + + $validate = isset($field['validate']) ? (array) $field['validate'] : []; // If value isn't required, we will stop validation if empty value is given. if (empty($validate['required']) && ($value === null || $value === '')) { - return; + return $messages; } - // special case for files, value is never empty and errors with code 4 instead - if (empty($validate['required']) && $field['type'] == 'file' && (isset($value['error']) && ($value['error'] == UPLOAD_ERR_NO_FILE || in_array(UPLOAD_ERR_NO_FILE, $value['error'])))) { - return; + // Special case for files, value is never empty and errors with code 4 instead. + if (empty($validate['required']) && $field['type'] == 'file' && isset($value['error']) + && ($value['error'] == UPLOAD_ERR_NO_FILE || in_array(UPLOAD_ERR_NO_FILE, $value['error']))) { + return $messages; } - // Get language class + // Get language class. $language = Grav::instance()['language']; // Validate type with fallback type text. $type = (string) isset($field['validate']['type']) ? $field['validate']['type'] : $field['type']; $method = 'type'.strtr($type, '-', '_'); + + if (!method_exists(__CLASS__, $method)) { + $method = 'typeText'; + } + $name = ucfirst(isset($field['label']) ? $field['label'] : $field['name']); - $message = (string) isset($field['validate']['message']) ? $language->translate($field['validate']['message']) : $language->translate('FORM.INVALID_INPUT', null, true) . ' "' . $language->translate($name) . '"'; + $message = (string) isset($field['validate']['message']) + ? $language->translate($field['validate']['message']) + : $language->translate('FORM.INVALID_INPUT', null, true) . ' "' . $language->translate($name) . '"'; + + $success = self::$method($value, $validate, $field); - if (method_exists(__CLASS__, $method)) { - $success = self::$method($value, $validate, $field); - } else { - $success = self::typeText($value, $validate, $field); - } if (!$success) { - throw new \RuntimeException($message); + $messages[$field['name']][] = $message; } - // Check individual rules + // Check individual rules. foreach ($validate as $rule => $params) { - $method = 'validate'.strtr($rule, '-', '_'); + $method = 'validate' . ucfirst(strtr($rule, '-', '_')); + if (method_exists(__CLASS__, $method)) { $success = self::$method($value, $params); if (!$success) { - throw new \RuntimeException($message); + $messages[$field['name']][] = $message; } } } + + return $messages; } /** @@ -74,22 +85,24 @@ class Validation */ public static function filter($value, array $field) { - $validate = isset($field['validate']) ? (array) $field['validate'] : array(); + $validate = isset($field['validate']) ? (array) $field['validate'] : []; // If value isn't required, we will return null if empty value is given. if (empty($validate['required']) && ($value === null || $value === '')) { return null; } - // special case for files, value is never empty and errors with code 4 instead - if (empty($validate['required']) && $field['type'] == 'file' && (isset($value['error']) && ($value['error'] == UPLOAD_ERR_NO_FILE || in_array(UPLOAD_ERR_NO_FILE, $value['error'])))) { + // Special case for files, value is never empty and errors with code 4 instead. + if (empty($validate['required']) && $field['type'] == 'file' && isset($value['error']) + && ($value['error'] == UPLOAD_ERR_NO_FILE || in_array(UPLOAD_ERR_NO_FILE, $value['error']))) { return null; } - // if this is a YAML field, simply parse it and return the value + // If this is a YAML field, simply parse it and return the value. if (isset($field['yaml']) && $field['yaml'] === true) { try { $yaml = new Parser(); + return $yaml->parse($value); } catch (ParseException $e) { throw new \RuntimeException($e->getMessage()); @@ -98,14 +111,13 @@ class Validation // Validate type with fallback type text. $type = (string) isset($field['validate']['type']) ? $field['validate']['type'] : $field['type']; - $method = 'filter'.strtr($type, '-', '_'); - if (method_exists(__CLASS__, $method)) { - $value = self::$method($value, $validate, $field); - } else { - $value = self::filterText($value, $validate, $field); + $method = 'filter' . ucfirst(strtr($type, '-', '_')); + + if (!method_exists(__CLASS__, $method)) { + $method = 'filterText'; } - return $value; + return self::$method($value, $validate, $field); } /** @@ -627,11 +639,11 @@ class Validation public static function validateRequired($value, $params) { - if (is_string($value)) { - $value = trim($value); + if (is_scalar($value)) { + return (bool) $params !== true || $value !== ''; + } else { + return (bool) $params !== true || !empty($value); } - - return (bool) $params !== true || !empty($value); } public static function validatePattern($value, $params) @@ -699,13 +711,14 @@ class Validation public static function validateArray($value, $params) { - return is_array($value) || ($value instanceof \ArrayAccess + return is_array($value) + || ($value instanceof \ArrayAccess && $value instanceof \Traversable && $value instanceof \Countable); } public static function validateJson($value, $params) { - return (bool) (json_decode($value)); + return (bool) (@json_decode($value)); } } diff --git a/system/src/Grav/Common/Data/ValidationException.php b/system/src/Grav/Common/Data/ValidationException.php new file mode 100644 index 000000000..20011cb8e --- /dev/null +++ b/system/src/Grav/Common/Data/ValidationException.php @@ -0,0 +1,30 @@ +messages = $messages; + + $language = Grav::instance()['language']; + $this->message = $language->translate('FORM.VALIDATION_FAIL', null, true) . ' ' . $this->message; + + foreach ($messages as $variable => &$list) { + $list = array_unique($list); + foreach ($list as $message) { + $this->message .= "
$message"; + } + } + + return $this; + } + + public function getMessages() + { + return $this->messages; + } +} \ No newline at end of file diff --git a/system/src/Grav/Common/Filesystem/Folder.php b/system/src/Grav/Common/Filesystem/Folder.php index 26e90fe31..a60d1ad14 100644 --- a/system/src/Grav/Common/Filesystem/Folder.php +++ b/system/src/Grav/Common/Filesystem/Folder.php @@ -1,6 +1,9 @@ isStream($path)) { + $directory = $locator->getRecursiveIterator($path, $flags); + } else { + $directory = new \RecursiveDirectoryIterator($path, $flags); + } $filter = new RecursiveFolderFilterIterator($directory); $iterator = new \RecursiveIteratorIterator($filter, \RecursiveIteratorIterator::SELF_FIRST); @@ -46,7 +56,14 @@ abstract class Folder { $last_modified = 0; - $directory = new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS); + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + $flags = \RecursiveDirectoryIterator::SKIP_DOTS; + if ($locator->isStream($path)) { + $directory = $locator->getRecursiveIterator($path, $flags); + } else { + $directory = new \RecursiveDirectoryIterator($path, $flags); + } $recursive = new \RecursiveIteratorIterator($directory, \RecursiveIteratorIterator::SELF_FIRST); $iterator = new \RegexIterator($recursive, '/^.+\.'.$extensions.'$/i'); @@ -145,7 +162,7 @@ abstract class Folder public static function all($path, array $params = []) { if ($path === false) { - throw new \RuntimeException("Path to {$path} doesn't exist."); + throw new \RuntimeException("Path doesn't exist."); } $compare = isset($params['compare']) ? 'get' . $params['compare'] : null; @@ -158,13 +175,23 @@ abstract class Folder $folders = isset($params['folders']) ? $params['folders'] : true; $files = isset($params['files']) ? $params['files'] : true; + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; if ($recursive) { - $directory = new \RecursiveDirectoryIterator($path, - \RecursiveDirectoryIterator::SKIP_DOTS + \FilesystemIterator::UNIX_PATHS + \FilesystemIterator::CURRENT_AS_SELF); + $flags = \RecursiveDirectoryIterator::SKIP_DOTS + \FilesystemIterator::UNIX_PATHS + \FilesystemIterator::CURRENT_AS_SELF; + if ($locator->isStream($path)) { + $directory = $locator->getRecursiveIterator($path, $flags); + } else { + $directory = new \RecursiveDirectoryIterator($path, $flags); + } $iterator = new \RecursiveIteratorIterator($directory, \RecursiveIteratorIterator::SELF_FIRST); $iterator->setMaxDepth(max($levels, -1)); } else { - $iterator = new \FilesystemIterator($path); + if ($locator->isStream($path)) { + $iterator = $locator->getIterator($path); + } else { + $iterator = new \FilesystemIterator($path); + } } $results = []; diff --git a/system/src/Grav/Common/GPM/GPM.php b/system/src/Grav/Common/GPM/GPM.php index ea525f387..bd4fb90a9 100644 --- a/system/src/Grav/Common/GPM/GPM.php +++ b/system/src/Grav/Common/GPM/GPM.php @@ -201,7 +201,7 @@ class GPM extends Iterator * * @param $package_name * - * @return string + * @return string|null */ public function getLatestVersionOfPackage($package_name) { @@ -216,6 +216,8 @@ class GPM extends Iterator if (isset($repository[$package_name])) { return $repository[$package_name]->version; } + + return null; } /** diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index cfd405654..829e7ab81 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -223,6 +223,8 @@ class Grav extends Container // Initialize configuration. $debugger->startTimer('_config', 'Configuration'); + /** @var Plugins $plugins */ + $plugins = $this['plugins']->setup(); $this['config']->init(); $debugger->stopTimer('_config'); @@ -262,7 +264,7 @@ class Grav extends Container $debugger->stopTimer('init'); $debugger->startTimer('plugins', 'Plugins'); - $this['plugins']->init(); + $plugins->init(); $this->fireEvent('onPluginsInitialized'); $debugger->stopTimer('plugins'); diff --git a/system/src/Grav/Common/GravTrait.php b/system/src/Grav/Common/GravTrait.php index 89883c595..8810291f6 100644 --- a/system/src/Grav/Common/GravTrait.php +++ b/system/src/Grav/Common/GravTrait.php @@ -5,6 +5,7 @@ namespace Grav\Common; * Class GravTrait * * @package Grav\Common + * @deprecated */ trait GravTrait { diff --git a/system/src/Grav/Common/Page/Media.php b/system/src/Grav/Common/Page/Media.php index 9013d8b62..3a7373444 100644 --- a/system/src/Grav/Common/Page/Media.php +++ b/system/src/Grav/Common/Page/Media.php @@ -87,7 +87,7 @@ class Media extends Getters $medium = MediumFactory::scaledFromMedium($altMedium, $ratio, 1)['file']; } - if (!$medium) { + if (empty($medium)) { continue; } diff --git a/system/src/Grav/Common/Page/Medium/MediumFactory.php b/system/src/Grav/Common/Page/Medium/MediumFactory.php index 0f4063cc0..60658135f 100644 --- a/system/src/Grav/Common/Page/Medium/MediumFactory.php +++ b/system/src/Grav/Common/Page/Medium/MediumFactory.php @@ -59,12 +59,9 @@ class MediumFactory $locator = Grav::instance()['locator']; - $lookup = $locator->findResources('image://'); - foreach ($lookup as $lookupPath) { - if (is_file($lookupPath . '/' . $params['thumb'])) { - $params['thumbnails']['default'] = $lookupPath . '/' . $params['thumb']; - break; - } + $file = $locator->findResource("image://{$params['thumb']}"); + if ($file) { + $params['thumbnails']['default'] = $file; } return static::fromArray($params); diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 149e1b302..7ec8c293e 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -100,8 +100,6 @@ class Page /** * Page Object Constructor - * - * @return $this */ public function __construct() { @@ -111,8 +109,6 @@ class Page $this->taxonomy = []; $this->process = $config->get('system.pages.process'); $this->published = true; - - return $this; } /** @@ -883,12 +879,14 @@ class Page */ public function blueprints() { + $grav = Grav::instance(); + /** @var Pages $pages */ - $pages = Grav::instance()['pages']; + $pages = $grav['pages']; $blueprint = $pages->blueprints($this->blueprintName()); $fields = $blueprint->fields(); - $edit_mode = isset(Grav::instance()['admin']) ? Grav::instance()['config']->get('plugins.admin.edit_mode') : null; + $edit_mode = isset($grav['admin']) ? $grav['config']->get('plugins.admin.edit_mode') : null; // override if you only want 'normal' mode if (empty($fields) && ($edit_mode == 'auto' || $edit_mode == 'normal')) { @@ -1419,17 +1417,19 @@ class Page */ public function url($include_host = false, $canonical = false, $include_lang = true) { + $grav = Grav::instance(); + /** @var Pages $pages */ - $pages = Grav::instance()['pages']; + $pages = $grav['pages']; /** @var Config $config */ - $config = Grav::instance()['config']; + $config = $grav['config']; /** @var Language $language */ - $language = Grav::instance()['language']; + $language = $grav['language']; /** @var Uri $uri */ - $uri = Grav::instance()['uri']; + $uri = $grav['uri']; // get pre-route if ($include_lang && $language->enabled()) { diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 407b964af..fb98932db 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -391,7 +391,7 @@ class Pages $blueprint = $this->blueprints->get('default'); } - if (!$blueprint->initialized) { + if (empty($blueprint->initialized)) { $this->grav->fireEvent('onBlueprintCreated', new Event(['blueprint' => $blueprint])); $blueprint->initialized = true; } @@ -470,11 +470,10 @@ class Pages */ public static function getTypes() { - $locator = Grav::instance()['locator']; if (!self::$types) { self::$types = new Types(); - file_exists('theme://blueprints/') && self::$types->scanBlueprints($locator->findResources('theme://blueprints/')); - file_exists('theme://templates/') && self::$types->scanTemplates($locator->findResources('theme://templates/')); + self::$types->scanBlueprints('theme://blueprints/'); + self::$types->scanTemplates('theme://templates/'); $event = new Event(); $event->types = self::$types; @@ -683,6 +682,7 @@ class Pages /** @var UniformResourceLocator $locator */ $locator = $this->grav['locator']; + $pages_dir = $locator->findResource('page://'); if ($config->get('system.cache.enabled')) { @@ -826,8 +826,10 @@ class Pages // set current modified of page $last_modified = $page->modified(); + $iterator = new \FilesystemIterator($directory); + /** @var \DirectoryIterator $file */ - foreach (new \FilesystemIterator($directory) as $file) { + foreach ($iterator as $file) { $name = $file->getFilename(); // Ignore all hidden files if set. diff --git a/system/src/Grav/Common/Page/Types.php b/system/src/Grav/Common/Page/Types.php index 5fbeaea5e..46d64a542 100644 --- a/system/src/Grav/Common/Page/Types.php +++ b/system/src/Grav/Common/Page/Types.php @@ -28,13 +28,21 @@ class Types implements \ArrayAccess, \Iterator, \Countable } } - public function scanBlueprints($paths) + public function scanBlueprints($uri) { - $this->items = $this->findBlueprints($paths) + $this->items; + if (!is_string($uri)) { + throw new \InvalidArgumentException('First parameter must be URI'); + } + + $this->items = $this->findBlueprints($uri) + $this->items; } - public function scanTemplates($paths) + public function scanTemplates($uri) { + if (!is_string($uri)) { + throw new \InvalidArgumentException('First parameter must be URI'); + } + $options = [ 'compare' => 'Filename', 'pattern' => '|\.html\.twig$|', @@ -52,16 +60,13 @@ class Types implements \ArrayAccess, \Iterator, \Countable // register default by default $this->register('default'); - foreach ((array) $paths as $path) { - foreach (Folder::all($path, $options) as $type) { - $this->register($type); - } - $modular_path = rtrim($path, '/') . '/modular'; - if (file_exists($modular_path)) { - foreach (Folder::all($modular_path, $options) as $type) { - $this->register('modular/' . $type); - } - } + foreach (Folder::all($uri, $options) as $type) { + $this->register($type); + } + + $modular_uri = rtrim($uri, '/') . '/modular'; + foreach (Folder::all($modular_uri, $options) as $type) { + $this->register('modular/' . $type); } } @@ -91,7 +96,7 @@ class Types implements \ArrayAccess, \Iterator, \Countable return $list; } - private function findBlueprints($paths) + private function findBlueprints($uri) { $options = [ 'compare' => 'Filename', @@ -103,10 +108,7 @@ class Types implements \ArrayAccess, \Iterator, \Countable 'value' => 'PathName', ]; - $list = []; - foreach ((array) $paths as $path) { - $list += Folder::all($path, $options); - } + $list = Folder::all($uri, $options); return $list; } diff --git a/system/src/Grav/Common/Plugin.php b/system/src/Grav/Common/Plugin.php index e6fd41664..74e9571f7 100644 --- a/system/src/Grav/Common/Plugin.php +++ b/system/src/Grav/Common/Plugin.php @@ -16,6 +16,16 @@ use RocketTheme\Toolbox\File\YamlFile; */ class Plugin implements EventSubscriberInterface { + /** + * @var string + */ + public $name; + + /** + * @var array + */ + public $features = []; + /** * @var Grav */ @@ -27,10 +37,6 @@ class Plugin implements EventSubscriberInterface protected $config; protected $active = true; - /** - * @var \Grav\Common\string - */ - protected $name; /** * By default assign all methods as listeners using the default priority. @@ -58,13 +64,29 @@ class Plugin implements EventSubscriberInterface * @param Grav $grav * @param Config $config */ - public function __construct($name, Grav $grav, Config $config) + public function __construct($name, Grav $grav, Config $config = null) { - $this->grav = $grav; - $this->config = $config; $this->name = $name; + $this->grav = $grav; + if ($config) { + $this->setConfig($config); + } } + /** + * @param Config $config + * @return $this + */ + public function setConfig(Config $config) + { + $this->config = $config; + + return $this; + } + + /** + * @return bool + */ public function isAdmin() { if (isset($this->grav['admin'])) { @@ -200,10 +222,11 @@ class Plugin implements EventSubscriberInterface return false; } - $locator = Grav::instance()['locator']; + $grav = Grav::instance(); + $locator = $grav['locator']; $filename = 'config://plugins/' . $plugin_name . '.yaml'; $file = YamlFile::instance($locator->findResource($filename, true, true)); - $content = Grav::instance()['config']->get('plugins.' . $plugin_name); + $content = $grav['config']->get('plugins.' . $plugin_name); $file->save($content); $file->free(); diff --git a/system/src/Grav/Common/Plugins.php b/system/src/Grav/Common/Plugins.php index af637d01f..ff52e3eed 100644 --- a/system/src/Grav/Common/Plugins.php +++ b/system/src/Grav/Common/Plugins.php @@ -1,13 +1,12 @@ getIterator('plugins://'); + foreach ($iterator as $directory) { + if (!$directory->isDir()) { + continue; + } + + $plugin = $directory->getBasename(); + + $this->add($this->loadPlugin($plugin)); + } + } + /** - * Recurses through the plugins directory creating Plugin objects for each plugin it finds. + * @return $this + */ + public function setup() + { + $blueprints = []; + $formFields = []; + + /** @var Plugin $plugin */ + foreach ($this->items as $plugin) { + if (isset($plugin->features['blueprints'])) { + $blueprints["plugin://{$plugin->name}/blueprints"] = $plugin->features['blueprints']; + } + if (method_exists($plugin, 'getFormFieldTypes')) { + $formFields[get_class($plugin)] = isset($plugin->features['formfields']) ? $plugin->features['formfields'] : 0; + } + } + + if ($blueprints) { + // Order by priority. + arsort($blueprints); + + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + $locator->addPath('blueprints', '', array_keys($blueprints), 'system/blueprints'); + } + + if ($formFields) { + // Order by priority. + arsort($formFields); + + $list = []; + foreach ($formFields as $className => $priority) { + $plugin = $this->items[$className]; + $list += $plugin->getFormFieldTypes(); + } + + $this->formFieldTypes = $list; + } + + return $this; + } + + /** + * Registers all plugins. * * @return array|Plugin[] array of Plugin objects * @throws \RuntimeException */ public function init() { - /** @var Config $config */ - $config = Grav::instance()['config']; - $plugins = (array)$config->get('plugins'); + $grav = Grav::instance(); - $inflector = Grav::instance()['inflector']; + /** @var Config $config */ + $config = $grav['config']; /** @var EventDispatcher $events */ - $events = Grav::instance()['events']; + $events = $grav['events']; - foreach ($plugins as $plugin => $data) { - if (empty($data['enabled'])) { - // Only load enabled plugins. - continue; - } - - $locator = Grav::instance()['locator']; - $filePath = $locator->findResource('plugins://' . $plugin . DS . $plugin . PLUGIN_EXT); - if (!is_file($filePath)) { - Grav::instance()['log']->addWarning(sprintf("Plugin '%s' enabled but not found! Try clearing cache with `bin/grav clear-cache`", $plugin)); - continue; - } - - require_once $filePath; - - $pluginClassFormat = [ - 'Grav\\Plugin\\' . ucfirst($plugin) . 'Plugin', - 'Grav\\Plugin\\' . $inflector->camelize($plugin) . 'Plugin' - ]; - $pluginClassName = false; - - foreach ($pluginClassFormat as $pluginClass) { - if (class_exists($pluginClass)) { - $pluginClassName = $pluginClass; - break; - } - } - - if (false === $pluginClassName) { - throw new \RuntimeException(sprintf("Plugin '%s' class not found! Try reinstalling this plugin.", - $plugin)); - } - - $instance = new $pluginClassName($plugin, Grav::instance(), $config); - if ($instance instanceof EventSubscriberInterface) { + foreach ($this->items as $instance) { + // Register only enabled plugins. + if ($config["plugins.{$instance->name}.enabled"] && $instance instanceof Plugin) { + $instance->setConfig($config); $events->addSubscriber($instance); } } @@ -96,28 +127,17 @@ class Plugins extends Iterator */ public static function all() { + $plugins = Grav::instance()['plugins']; $list = []; - $locator = Grav::instance()['locator']; - $plugins = (array)$locator->findResources('plugins://', false); - foreach ($plugins as $path) { - $iterator = new \DirectoryIterator($path); + foreach ($plugins as $instance) { + $name = $instance->name; + $result = self::get($name); - /** @var \DirectoryIterator $directory */ - foreach ($iterator as $directory) { - if (!$directory->isDir() || $directory->isDot()) { - continue; - } - - $plugin = $directory->getBasename(); - $result = self::get($plugin); - - if ($result) { - $list[$plugin] = $result; - } + if ($result) { + $list[$name] = $result; } } - ksort($list); return $list; } @@ -133,7 +153,6 @@ class Plugins extends Iterator { $blueprints = new Blueprints('plugins://'); $blueprint = $blueprints->get("{$name}/blueprints"); - $blueprint->name = $name; // Load default configuration. $file = CompiledYamlFile::instance("plugins://{$name}/{$name}" . YAML_EXT); @@ -155,4 +174,29 @@ class Plugins extends Iterator return $obj; } + protected function loadPlugin($name) + { + $grav = Grav::instance(); + $locator = $grav['locator']; + + $filePath = $locator->findResource('plugins://' . $name . DS . $name . PLUGIN_EXT); + if (!is_file($filePath)) { + $grav['log']->addWarning( + sprintf("Plugin '%s' enabled but not found! Try clearing cache with `bin/grav clear-cache`", $name) + ); + return null; + } + + require_once $filePath; + + $pluginClassName = 'Grav\\Plugin\\' . ucfirst($name) . 'Plugin'; + if (!class_exists($pluginClassName)) { + $pluginClassName = 'Grav\\Plugin\\' . $grav['inflector']->camelize($name) . 'Plugin'; + if (!class_exists($pluginClassName)) { + throw new \RuntimeException(sprintf("Plugin '%s' class not found! Try reinstalling this plugin.", $name)); + } + } + return new $pluginClassName($name, $grav); + } + } diff --git a/system/src/Grav/Common/Service/StreamsServiceProvider.php b/system/src/Grav/Common/Service/StreamsServiceProvider.php index ec7f9cd85..98f396814 100644 --- a/system/src/Grav/Common/Service/StreamsServiceProvider.php +++ b/system/src/Grav/Common/Service/StreamsServiceProvider.php @@ -34,7 +34,7 @@ class StreamsServiceProvider implements ServiceProviderInterface Stream::setLocator($locator); ReadOnlyStream::setLocator($locator); - return new StreamBuilder($setup->getStreams($c)); + return new StreamBuilder($setup->getStreams()); }; } } diff --git a/system/src/Grav/Common/Session.php b/system/src/Grav/Common/Session.php index c73ddcfca..e99151f3f 100644 --- a/system/src/Grav/Common/Session.php +++ b/system/src/Grav/Common/Session.php @@ -1,10 +1,12 @@ name = $name; - parent::__construct($name, $grav, $config); } @@ -39,10 +35,11 @@ class Theme extends Plugin return false; } - $locator = Grav::instance()['locator']; + $grav = Grav::instance(); + $locator = $grav['locator']; $filename = 'config://themes/' . $theme_name . '.yaml'; $file = YamlFile::instance($locator->findResource($filename, true, true)); - $content = Grav::instance()['config']->get('themes.' . $theme_name); + $content = $grav['config']->get('themes.' . $theme_name); $file->save($content); $file->free(); diff --git a/system/src/Grav/Common/Themes.php b/system/src/Grav/Common/Themes.php index 9f360cc35..e3497f542 100644 --- a/system/src/Grav/Common/Themes.php +++ b/system/src/Grav/Common/Themes.php @@ -79,24 +79,23 @@ class Themes extends Iterator public function all() { $list = []; - $locator = Grav::instance()['locator']; - $themes = (array)$locator->findResources('themes://', false); - foreach ($themes as $path) { - $iterator = new \DirectoryIterator($path); + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; - /** @var \DirectoryIterator $directory */ - foreach ($iterator as $directory) { - if (!$directory->isDir() || $directory->isDot()) { - continue; - } + $iterator = $locator->getIterator('themes://'); - $theme = $directory->getBasename(); - $result = self::get($theme); + /** @var \DirectoryIterator $directory */ + foreach ($iterator as $directory) { + if (!$directory->isDir() || $directory->isDot()) { + continue; + } - if ($result) { - $list[$theme] = $result; - } + $theme = $directory->getBasename(); + $result = self::get($theme); + + if ($result) { + $list[$theme] = $result; } } ksort($list); @@ -120,7 +119,6 @@ class Themes extends Iterator $blueprints = new Blueprints('themes://'); $blueprint = $blueprints->get("{$name}/blueprints"); - $blueprint->name = $name; // Load default configuration. $file = CompiledYamlFile::instance("themes://{$name}/{$name}" . YAML_EXT); @@ -141,7 +139,7 @@ class Themes extends Iterator $obj = new Data($file->content(), $blueprint); // Override with user configuration. - $obj->merge($this->grav['config']->get('themes.' . $name) ?: []); + $obj->merge($this->config->get('themes.' . $name) ?: []); // Save configuration always to user/config. $file = CompiledYamlFile::instance("config://themes/{$name}" . YAML_EXT); diff --git a/system/src/Grav/Common/Uri.php b/system/src/Grav/Common/Uri.php index 001a448b4..0c708ca85 100644 --- a/system/src/Grav/Common/Uri.php +++ b/system/src/Grav/Common/Uri.php @@ -325,7 +325,7 @@ class Uri $valid_page_types = implode('|', $config->get('system.pages.types')); // Strip the file extension for valid page types - if (preg_match("/\.(" . $valid_page_types . ")$/", $parts['basename'])) { + if (preg_match('/\.(' . $valid_page_types . ')$/', $parts['basename'])) { $uri = rtrim(str_replace(DIRECTORY_SEPARATOR, DS, $parts['dirname']), DS) . '/' . $parts['filename']; } @@ -748,7 +748,7 @@ class Uri * @param Page $page the current page to use as reference * @param string $url the URL as it was written in the markdown * @param string $type the type of URL, image | link - * @param null $absolute if null, will use system default, if true will use absolute links internally + * @param bool $absolute if null, will use system default, if true will use absolute links internally * * @return string the more friendly formatted url */ @@ -965,7 +965,6 @@ class Uri if ($type == 'link' && $language->enabled()) { $language_append = $language->getLanguageURLPrefix(); } - $pages_dir = $grav['locator']->findResource('page://'); if (is_null($relative)) { $base = $grav['base_url']; diff --git a/system/src/Grav/Common/User/Group.php b/system/src/Grav/Common/User/Group.php index 068adadcc..476d4e060 100644 --- a/system/src/Grav/Common/User/Group.php +++ b/system/src/Grav/Common/User/Group.php @@ -54,7 +54,7 @@ class Group extends Data $content = []; } - $blueprints = new Blueprints('blueprints://'); + $blueprints = new Blueprints; $blueprint = $blueprints->get('user/group'); if (!isset($content['groupname'])) { $content['groupname'] = $groupname; @@ -69,18 +69,21 @@ class Group extends Data */ public function save() { - $blueprints = new Blueprints('blueprints://'); + $grav = Grav::instance(); + $config = $grav['config']; + + $blueprints = new Blueprints; $blueprint = $blueprints->get('user/group'); $fields = $blueprint->fields(); - Grav::instance()['config']->set("groups.$this->groupname", []); + $config->set("groups.$this->groupname", []); foreach ($fields as $field) { if ($field['type'] == 'text') { $value = $field['name']; if (isset($this->items[$value])) { - Grav::instance()['config']->set("groups.$this->groupname.$value", $this->items[$value]); + $config->set("groups.$this->groupname.$value", $this->items[$value]); } } if ($field['type'] == 'array') { @@ -89,7 +92,7 @@ class Group extends Data if ($arrayValues) { foreach ($arrayValues as $arrayIndex => $arrayValue) { - Grav::instance()['config']->set("groups.$this->groupname.$value.$arrayIndex", $arrayValue); + $config->set("groups.$this->groupname.$value.$arrayIndex", $arrayValue); } } } @@ -97,8 +100,8 @@ class Group extends Data $type = 'groups'; $blueprints = $this->blueprints("config/{$type}"); - $obj = new Data(Grav::instance()['config']->get($type), $blueprints); - $file = CompiledYamlFile::instance(Grav::instance()['locator']->findResource("config://{$type}.yaml")); + $obj = new Data($config->get($type), $blueprints); + $file = CompiledYamlFile::instance($grav['locator']->findResource("config://{$type}.yaml")); $obj->file($file); $obj->save(); } @@ -112,16 +115,18 @@ class Group extends Data */ public static function remove($groupname) { - $blueprints = new Blueprints('blueprints://'); + $grav = Grav::instance(); + $config = $grav['config']; + $blueprints = new Blueprints; $blueprint = $blueprints->get('user/group'); - $groups = Grav::instance()['config']->get("groups"); + $groups = $config->get("groups"); unset($groups[$groupname]); - Grav::instance()['config']->set("groups", $groups); + $config->set("groups", $groups); $type = 'groups'; - $obj = new Data(Grav::instance()['config']->get($type), $blueprint); - $file = CompiledYamlFile::instance(Grav::instance()['locator']->findResource("config://{$type}.yaml")); + $obj = new Data($config->get($type), $blueprint); + $file = CompiledYamlFile::instance($grav['locator']->findResource("config://{$type}.yaml")); $obj->file($file); $obj->save(); diff --git a/system/src/Grav/Common/User/User.php b/system/src/Grav/Common/User/User.php index 73e2082f3..4e5cc2348 100644 --- a/system/src/Grav/Common/User/User.php +++ b/system/src/Grav/Common/User/User.php @@ -34,7 +34,7 @@ class User extends Data // force lowercase of username $username = strtolower($username); - $blueprints = new Blueprints('blueprints://'); + $blueprints = new Blueprints; $blueprint = $blueprints->get('user/account'); $file_path = $locator->findResource('account://' . $username . YAML_EXT); $file = CompiledYamlFile::instance($file_path);