mirror of
https://github.com/getgrav/grav.git
synced 2025-12-05 15:29:57 +01:00
Compare commits
79 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
95a4ecb0f1 | ||
|
|
fbd3bbdbf9 | ||
|
|
f0e58adfbc | ||
|
|
f1363877d8 | ||
|
|
e8825beae5 | ||
|
|
394dfad566 | ||
|
|
680bfef2c3 | ||
|
|
28bd4027cd | ||
|
|
108541e0d0 | ||
|
|
54a177279f | ||
|
|
b3e9974e95 | ||
|
|
708c79cef8 | ||
|
|
b6c582ad3a | ||
|
|
5e1980d770 | ||
|
|
5e7eb6b2f4 | ||
|
|
4daa07fd14 | ||
|
|
9a8b47872e | ||
|
|
9405418572 | ||
|
|
59ccd662c7 | ||
|
|
377751416b | ||
|
|
116c279f01 | ||
|
|
bf86b5a924 | ||
|
|
d0b34d114d | ||
|
|
b9dc2baef1 | ||
|
|
72cc5b9d07 | ||
|
|
b9c28c5a7c | ||
|
|
c56d7ac793 | ||
|
|
000bac8cfc | ||
|
|
e7d660149e | ||
|
|
829638c143 | ||
|
|
d8a627898e | ||
|
|
a3caa13c23 | ||
|
|
9944486c17 | ||
|
|
da5c9e415f | ||
|
|
7b5a1b2c14 | ||
|
|
235a5cc765 | ||
|
|
073d601b67 | ||
|
|
ad1bbba0b3 | ||
|
|
b6b5e329aa | ||
|
|
0e973dab07 | ||
|
|
15e371564a | ||
|
|
f0e33dc242 | ||
|
|
e67c3c1091 | ||
|
|
d5ce0bd93c | ||
|
|
44dbcdf2b1 | ||
|
|
3216442946 | ||
|
|
9d4471b196 | ||
|
|
c48107acd9 | ||
|
|
4671518409 | ||
|
|
41bf943f49 | ||
|
|
f40c6a8617 | ||
|
|
fb98ca7b19 | ||
|
|
451ec49d9c | ||
|
|
1709eb038c | ||
|
|
e69d6cefee | ||
|
|
7abe01ed8c | ||
|
|
17a371d86a | ||
|
|
5b787d56e6 | ||
|
|
33d98114ba | ||
|
|
51f29e112a | ||
|
|
ca8805683d | ||
|
|
8295bd8243 | ||
|
|
da95d1bb1e | ||
|
|
bbc4fd6c79 | ||
|
|
732ff8ecab | ||
|
|
41b7aadbda | ||
|
|
834d6938db | ||
|
|
dfabceb3d2 | ||
|
|
1808fd3d6e | ||
|
|
0b5c1dcfa7 | ||
|
|
1369f941f2 | ||
|
|
2101c6d0dc | ||
|
|
1993fc6a2c | ||
|
|
b9b43d1f05 | ||
|
|
8d53cf3c77 | ||
|
|
756ddaa97d | ||
|
|
89f64e423d | ||
|
|
ec5596b1a3 | ||
|
|
9ca5598b6f |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -42,3 +42,4 @@ tests/_output/*
|
||||
tests/_support/_generated/*
|
||||
tests/cache/*
|
||||
tests/error.log
|
||||
/system/templates/testing
|
||||
|
||||
91
CHANGELOG.md
91
CHANGELOG.md
@@ -1,3 +1,70 @@
|
||||
# v1.5.7
|
||||
## 01/25/2018
|
||||
|
||||
1. [](#new)
|
||||
* Support for AWS Cloudfront forwarded scheme header [#2297](https://github.com/getgrav/grav/pull/2297)
|
||||
1. [](#improved)
|
||||
* Set homepage with `https://` protocol [#2299](https://github.com/getgrav/grav/pull/2299)
|
||||
* Preserve accents in fields containing Twig expr. using unicode [#2279](https://github.com/getgrav/grav/pull/2279)
|
||||
* Updated vendor libraries
|
||||
1. [](#bugfix)
|
||||
* Support spaces with filenames in responsive images [#2300](https://github.com/getgrav/grav/pull/2300)
|
||||
|
||||
# v1.5.6
|
||||
## 12/14/2018
|
||||
|
||||
1. [](#improved)
|
||||
* Updated InitializeProcessor.php to use lang-safe redirect [#2268](https://github.com/getgrav/grav/pull/2268)
|
||||
* Improved user serialization to use less memory in the session
|
||||
|
||||
# v1.5.5
|
||||
## 11/12/2018
|
||||
|
||||
1. [](#new)
|
||||
* Register theme prefixes as namespaces in Twig [#2210](https://github.com/getgrav/grav/pull/2210)
|
||||
1. [](#improved)
|
||||
* Propogate error code between 400 and 600 for production sites [#2181](https://github.com/getgrav/grav/pull/2181)
|
||||
1. [](#bugfix)
|
||||
* Remove hardcoded `302` when redirecting trailing slash [#2155](https://github.com/getgrav/grav/pull/2155)
|
||||
|
||||
# v1.5.4
|
||||
## 11/05/2018
|
||||
|
||||
1. [](#improved)
|
||||
* Updated default page `index.md` with some consistency fixes [#2245](https://github.com/getgrav/grav/pull/2245)
|
||||
1. [](#bugfix)
|
||||
* Fixed fatal error if calling `$session->invalidate()` when there's no active session
|
||||
* Fixed typo in media.yaml for `webm` extension [#2220](https://github.com/getgrav/grav/pull/2220)
|
||||
* Fixed markdown processing for telephone links [#2235](https://github.com/getgrav/grav/pull/2235)
|
||||
|
||||
# v1.5.3
|
||||
## 10/08/2018
|
||||
|
||||
1. [](#new)
|
||||
* Added `Utils::getMimeByFilename()`, `Utils::getMimeByLocalFile()` and `Utils::checkFilename()` methods
|
||||
* Added configurable dangerous upload extensions in `security.yaml`
|
||||
1. [](#improved)
|
||||
* Updated vendor libraries to latest
|
||||
|
||||
# v1.5.2
|
||||
## 10/01/2018
|
||||
|
||||
1. [](#new)
|
||||
* Added new `Security` class for Grav security functionality including XSS checks
|
||||
* Added new `bin/grav security` command to scan for security issues
|
||||
* Added new `xss()` Twig function to allow for XSS checks on strings and arrays
|
||||
* Added `onHttpPostFilter` event to allow plugins to globally clean up XSS in the forms and tasks
|
||||
* Added `Deprecated` tab to DebugBar to catch future incompatibilities with later Grav versions
|
||||
* Added deprecation notices for features which will be removed in Grav 2.0
|
||||
1. [](#improved)
|
||||
* Updated vendor libraries to latest
|
||||
1. [](#bugfix)
|
||||
* Allow `$page->slug()` to be called before `$page->init()` without breaking the page
|
||||
* Fix for `Page::translatedLanguages()` to use routes always [#2163](https://github.com/getgrav/grav/issues/2163)
|
||||
* Fixed `nicetime()` twig function
|
||||
* Allow twig tags `{% script %}`, `{% style %}` and `{% switch %}` to be placed outside of blocks
|
||||
* Session expires in 30 mins independent from config settings [login#178](https://github.com/getgrav/grav-plugin-login/issues/178)
|
||||
|
||||
# v1.5.1
|
||||
## 08/23/2018
|
||||
|
||||
@@ -13,19 +80,19 @@
|
||||
## 08/17/2018
|
||||
|
||||
1. [](#new)
|
||||
* Set minimum requirements to [PHP 5.6.4](https://getgrav.org/blog/raising-php-requirements-2018)
|
||||
* Set minimum requirements to [PHP 5.6.4](https://getgrav.org/blog/raising-php-requirements-2018)
|
||||
* Updated Doctrine Collections to 1.4
|
||||
* Updated Symfony Components to 3.4 (with compatibility mode to fall back to Symfony YAML 2.8)
|
||||
* Added `Uri::method()` to get current HTTP method (GET/POST etc)
|
||||
* `FormatterInterface`: Added `getSupportedFileExtensions()` and `getDefaultFileExtension()` methods
|
||||
* Added option to disable `SimpleCache` key validation
|
||||
* Added support for multiple repo locations for `bin/grav install` command
|
||||
* Added option to disable `SimpleCache` key validation
|
||||
* Added support for multiple repo locations for `bin/grav install` command
|
||||
* Added twig filters for casting values: `|string`, `|int`, `|bool`, `|float`, `|array`
|
||||
* Made `ObjectCollection::matching()` criteria expressions to behave more like in Twig
|
||||
* Criteria: Added support for `LENGTH()`, `LOWER()`, `UPPER()`, `LTRIM()`, `RTRIM()` and `TRIM()`
|
||||
* Added `Grav\Framework\File\Formatter` classes for encoding/decoding YAML, Markdown, JSON, INI and PHP serialized strings
|
||||
* Added `Grav\Framework\Session` class to replace `RocketTheme\Toolbox\Session\Session`
|
||||
* Added `Grav\Common\Media` interfaces and trait; use those in `Page` and `Media` classes
|
||||
* Added `Grav\Common\Media` interfaces and trait; use those in `Page` and `Media` classes
|
||||
* Added `Grav\Common\Page` interface to allow custom page types in the future
|
||||
* Added setting to disable sessions from the site [#2013](https://github.com/getgrav/grav/issues/2013)
|
||||
* Added new `strict_mode` settings in `system.yaml` for compatibility
|
||||
@@ -38,7 +105,7 @@
|
||||
* Improved session handling, allow all session configuration options in `system.session.options`
|
||||
1. [](#bugfix)
|
||||
* Fix broken form nonce logic [#2121](https://github.com/getgrav/grav/pull/2121)
|
||||
* Fixed issue with uppercase extensions and fallback media URLs [#2133](https://github.com/getgrav/grav/issues/2133)
|
||||
* Fixed issue with uppercase extensions and fallback media URLs [#2133](https://github.com/getgrav/grav/issues/2133)
|
||||
* Fixed theme inheritance issue with `camel-case` that includes numbers [#2134](https://github.com/getgrav/grav/issues/2134)
|
||||
* Typo in demo typography page [#2136](https://github.com/getgrav/grav/pull/2136)
|
||||
* Fix for incorrect plugin order in debugger panel
|
||||
@@ -66,7 +133,7 @@
|
||||
1. [](#bugfix)
|
||||
* Fix for modular page preview [#2066](https://github.com/getgrav/grav/issues/2066)
|
||||
* `Page::routeCanonical()` should be string not array [#2069](https://github.com/getgrav/grav/issues/2069)
|
||||
|
||||
|
||||
# v1.4.6
|
||||
## 06/20/2018
|
||||
|
||||
@@ -92,7 +159,7 @@
|
||||
* Fixed an issue with some users getting **2FA** prompt after upgrade [admin#1442](https://github.com/getgrav/grav-plugin-admin/issues/1442)
|
||||
* Do not crash when generating URLs with arrays as parameters [#2018](https://github.com/getgrav/grav/pull/2018)
|
||||
* Utils::truncateHTML removes whitespace when generating summaries [#2004](https://github.com/getgrav/grav/pull/2004)
|
||||
|
||||
|
||||
# v1.4.4
|
||||
## 05/11/2018
|
||||
|
||||
@@ -101,8 +168,8 @@
|
||||
* Added a new `Medium:thumbnailExists()` function [#1966](https://github.com/getgrav/grav/issues/1966)
|
||||
* Added `authorized` support for 2FA
|
||||
1. [](#improved)
|
||||
* Added default configuration for images [#1979](https://github.com/getgrav/grav/pull/1979)
|
||||
* Added dedicated PHPUnit assertions [#1990](https://github.com/getgrav/grav/pull/1990)
|
||||
* Added default configuration for images [#1979](https://github.com/getgrav/grav/pull/1979)
|
||||
* Added dedicated PHPUnit assertions [#1990](https://github.com/getgrav/grav/pull/1990)
|
||||
1. [](#bugfix)
|
||||
* Use `array_key_exists` instead of `in_array + array_keys` [#1991](https://github.com/getgrav/grav/pull/1991)
|
||||
* Fixed an issue with `custom_base_url` always causing 404 errors
|
||||
@@ -128,13 +195,13 @@
|
||||
* Added new `|nicefilesize` Twig filter for pretty file (auto converts to bytes, kB, MB, GB, etc)
|
||||
* Added new `regex_filter()` Twig function to values in arrays
|
||||
1. [](#improved)
|
||||
* Added bosnian to lang codes [#1917](https://github.com/getgrav/grav/issues/1917)
|
||||
* Improved Zip extraction error codes [#1922](https://github.com/getgrav/grav/issues/1922)
|
||||
* Added bosnian to lang codes [#1917](https://github.com/getgrav/grav/issues/1917)
|
||||
* Improved Zip extraction error codes [#1922](https://github.com/getgrav/grav/issues/1922)
|
||||
1. [](#bugfix)
|
||||
* Fixed an issue with Markdown Video and Audio that broke after Parsedown 1.7.0 Security updates [#1924](https://github.com/getgrav/grav/issues/1924)
|
||||
* Fix for case-sensitive page metadata [admin#1370](https://github.com/getgrav/grav-plugin-admin/issues/1370)
|
||||
* Fixed missing composer requirements for the new `Grav\Framework\Uri` classes
|
||||
* Added missing PSR-7 vendor library required for URI additions in Grav 1.4.0
|
||||
* Added missing PSR-7 vendor library required for URI additions in Grav 1.4.0
|
||||
|
||||
# v1.4.1
|
||||
## 03/11/2018
|
||||
|
||||
73
README.md
73
README.md
@@ -1,6 +1,6 @@
|
||||
#  Grav
|
||||
|
||||
[](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad) [](https://chat.getgrav.org) [](https://travis-ci.org/getgrav/grav) [](#backers) [](#sponsors)
|
||||
[](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad) [](https://chat.getgrav.org) [](https://travis-ci.org/getgrav/grav) [](#backers) [](#sponsors)
|
||||
|
||||
Grav is a **Fast**, **Simple**, and **Flexible**, file-based Web-platform. There is **Zero** installation required. Just extract the ZIP archive, and you are already up and running. It follows similar principles to other flat-file CMS platforms, but has a different design philosophy than most. Grav comes with a powerful **Package Management System** to allow for simple installation and upgrading of plugins and themes, as well as simple updating of Grav itself.
|
||||
|
||||
@@ -94,7 +94,7 @@ If you discover a possible security issue related to Grav or one of its plugins,
|
||||
* [Install](https://learn.getgrav.org/basics/installation) Grav in few seconds
|
||||
* Understand the [Configuration](https://learn.getgrav.org/basics/grav-configuration)
|
||||
* Take a peek at our available free [Skeletons](https://getgrav.org/downloads/skeletons)
|
||||
* If you have questions, jump on our [Slack Room](https://getgrav.org/slack)!
|
||||
* If you have questions, jump on our [Discord Chat Server](https://chat.getgrav.org)!
|
||||
* Have fun!
|
||||
|
||||
# Exploring More
|
||||
@@ -107,71 +107,12 @@ If you discover a possible security issue related to Grav or one of its plugins,
|
||||
# Backers
|
||||
Support Grav with a monthly donation to help us continue development. [[Become a backer](https://opencollective.com/grav#backer)]
|
||||
|
||||
<a href="https://opencollective.com/grav/backer/0/website" target="_blank"><img src="https://opencollective.com/grav/backer/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/1/website" target="_blank"><img src="https://opencollective.com/grav/backer/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/2/website" target="_blank"><img src="https://opencollective.com/grav/backer/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/3/website" target="_blank"><img src="https://opencollective.com/grav/backer/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/4/website" target="_blank"><img src="https://opencollective.com/grav/backer/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/5/website" target="_blank"><img src="https://opencollective.com/grav/backer/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/6/website" target="_blank"><img src="https://opencollective.com/grav/backer/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/7/website" target="_blank"><img src="https://opencollective.com/grav/backer/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/8/website" target="_blank"><img src="https://opencollective.com/grav/backer/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/9/website" target="_blank"><img src="https://opencollective.com/grav/backer/9/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/10/website" target="_blank"><img src="https://opencollective.com/grav/backer/10/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/11/website" target="_blank"><img src="https://opencollective.com/grav/backer/11/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/12/website" target="_blank"><img src="https://opencollective.com/grav/backer/12/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/13/website" target="_blank"><img src="https://opencollective.com/grav/backer/13/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/14/website" target="_blank"><img src="https://opencollective.com/grav/backer/14/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/15/website" target="_blank"><img src="https://opencollective.com/grav/backer/15/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/16/website" target="_blank"><img src="https://opencollective.com/grav/backer/16/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/17/website" target="_blank"><img src="https://opencollective.com/grav/backer/17/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/18/website" target="_blank"><img src="https://opencollective.com/grav/backer/18/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/19/website" target="_blank"><img src="https://opencollective.com/grav/backer/19/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/20/website" target="_blank"><img src="https://opencollective.com/grav/backer/20/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/21/website" target="_blank"><img src="https://opencollective.com/grav/backer/21/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/22/website" target="_blank"><img src="https://opencollective.com/grav/backer/22/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/23/website" target="_blank"><img src="https://opencollective.com/grav/backer/23/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/24/website" target="_blank"><img src="https://opencollective.com/grav/backer/24/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/25/website" target="_blank"><img src="https://opencollective.com/grav/backer/25/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/26/website" target="_blank"><img src="https://opencollective.com/grav/backer/26/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/27/website" target="_blank"><img src="https://opencollective.com/grav/backer/27/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/28/website" target="_blank"><img src="https://opencollective.com/grav/backer/28/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/29/website" target="_blank"><img src="https://opencollective.com/grav/backer/29/avatar.svg"></a>
|
||||
|
||||
<img src="https://opencollective.com/grav/tiers/backers.svg?avatarHeight=36&width=600" />
|
||||
|
||||
# Sponsors
|
||||
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/grav#sponsor)]
|
||||
|
||||
<a href="https://opencollective.com/grav/sponsor/0/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/1/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/2/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/3/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/4/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/5/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/6/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/7/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/8/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/9/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/9/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/10/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/10/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/11/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/11/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/12/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/12/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/13/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/13/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/14/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/14/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/15/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/15/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/16/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/16/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/17/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/17/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/18/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/18/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/19/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/19/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/20/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/20/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/21/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/21/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/22/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/22/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/23/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/23/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/24/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/24/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/25/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/25/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/26/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/26/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/27/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/27/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/28/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/28/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/29/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/29/avatar.svg"></a>
|
||||
<img src="https://opencollective.com/grav/tiers/sponsors.svg?avatarHeight=36&width=600" />
|
||||
|
||||
# License
|
||||
|
||||
@@ -183,7 +124,7 @@ See [LICENSE](LICENSE.txt)
|
||||
|
||||
# Running Tests
|
||||
|
||||
First install the dev dependencies by running `composer update` from the Grav root.
|
||||
Then `composer test` will run the Unit Tests, which should be always executed successfully on any site.
|
||||
Windows users should use the `composer test-windows` command.
|
||||
First install the dev dependencies by running `composer update` from the Grav root.
|
||||
Then `composer test` will run the Unit Tests, which should be always executed successfully on any site.
|
||||
Windows users should use the `composer test-windows` command.
|
||||
You can also run a single unit test file, e.g. `composer test tests/unit/Grav/Common/AssetsTest.php`
|
||||
|
||||
1
bin/grav
1
bin/grav
@@ -41,5 +41,6 @@ $app->addCommands(array(
|
||||
new \Grav\Console\Cli\ClearCacheCommand(),
|
||||
new \Grav\Console\Cli\BackupCommand(),
|
||||
new \Grav\Console\Cli\NewProjectCommand(),
|
||||
new \Grav\Console\Cli\SecurityCommand(),
|
||||
));
|
||||
$app->run();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"type": "project",
|
||||
"description": "Modern, Crazy Fast, Ridiculously Easy and Amazingly Powerful Flat-File CMS",
|
||||
"keywords": ["cms","flat-file cms","flat cms","flatfile cms","php"],
|
||||
"homepage": "http://getgrav.org",
|
||||
"homepage": "https://getgrav.org",
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": ">=5.6.4",
|
||||
@@ -32,6 +32,7 @@
|
||||
"ext-openssl": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-zip": "*",
|
||||
"ext-json": "*",
|
||||
"league/climate": "^3.2",
|
||||
"antoligy/dom-string-iterators": "^1.0",
|
||||
"miljar/php-exif": "^0.6.3",
|
||||
|
||||
325
composer.lock
generated
325
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "ec4860b0ab68318d0e4550d58b5c12b3",
|
||||
"content-hash": "544658e69ae737e742e014c6c674cc70",
|
||||
"packages": [
|
||||
{
|
||||
"name": "antoligy/dom-string-iterators",
|
||||
@@ -52,16 +52,16 @@
|
||||
},
|
||||
{
|
||||
"name": "composer/ca-bundle",
|
||||
"version": "1.1.2",
|
||||
"version": "1.1.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/ca-bundle.git",
|
||||
"reference": "46afded9720f40b9dc63542af4e3e43a1177acb0"
|
||||
"reference": "8afa52cd417f4ec417b4bfe86b68106538a87660"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/46afded9720f40b9dc63542af4e3e43a1177acb0",
|
||||
"reference": "46afded9720f40b9dc63542af4e3e43a1177acb0",
|
||||
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/8afa52cd417f4ec417b4bfe86b68106538a87660",
|
||||
"reference": "8afa52cd417f4ec417b4bfe86b68106538a87660",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -104,7 +104,7 @@
|
||||
"ssl",
|
||||
"tls"
|
||||
],
|
||||
"time": "2018-08-08T08:57:40+00:00"
|
||||
"time": "2018-10-18T06:09:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/cache",
|
||||
@@ -245,16 +245,16 @@
|
||||
},
|
||||
{
|
||||
"name": "donatj/phpuseragentparser",
|
||||
"version": "v0.10.0",
|
||||
"version": "v0.11.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/donatj/PhpUserAgent.git",
|
||||
"reference": "9de58cc2a3e986bfee7f4cea3365c830b765cf65"
|
||||
"reference": "0eab93a89a1a73a087e795abc96d5777c3d48b64"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/donatj/PhpUserAgent/zipball/9de58cc2a3e986bfee7f4cea3365c830b765cf65",
|
||||
"reference": "9de58cc2a3e986bfee7f4cea3365c830b765cf65",
|
||||
"url": "https://api.github.com/repos/donatj/PhpUserAgent/zipball/0eab93a89a1a73a087e795abc96d5777c3d48b64",
|
||||
"reference": "0eab93a89a1a73a087e795abc96d5777c3d48b64",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -283,7 +283,7 @@
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Simple, streamlined PHP user-agent parser",
|
||||
"description": "Lightning fast, minimalist PHP UserAgent string parser.",
|
||||
"homepage": "http://donatstudios.com/PHP-Parser-HTTP_USER_AGENT",
|
||||
"keywords": [
|
||||
"browser",
|
||||
@@ -292,7 +292,7 @@
|
||||
"user agent",
|
||||
"useragent"
|
||||
],
|
||||
"time": "2018-06-21T15:54:46+00:00"
|
||||
"time": "2018-10-25T20:22:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "erusev/parsedown",
|
||||
@@ -385,16 +385,16 @@
|
||||
},
|
||||
{
|
||||
"name": "filp/whoops",
|
||||
"version": "2.2.0",
|
||||
"version": "2.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/filp/whoops.git",
|
||||
"reference": "181c4502d8f34db7aed7bfe88d4f87875b8e947a"
|
||||
"reference": "bc0fd11bc455cc20ee4b5edabc63ebbf859324c7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/filp/whoops/zipball/181c4502d8f34db7aed7bfe88d4f87875b8e947a",
|
||||
"reference": "181c4502d8f34db7aed7bfe88d4f87875b8e947a",
|
||||
"url": "https://api.github.com/repos/filp/whoops/zipball/bc0fd11bc455cc20ee4b5edabc63ebbf859324c7",
|
||||
"reference": "bc0fd11bc455cc20ee4b5edabc63ebbf859324c7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -413,7 +413,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.1-dev"
|
||||
"dev-master": "2.2-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -442,7 +442,7 @@
|
||||
"throwable",
|
||||
"whoops"
|
||||
],
|
||||
"time": "2018-03-03T17:56:25+00:00"
|
||||
"time": "2018-10-23T09:00:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "gregwar/cache",
|
||||
@@ -489,17 +489,17 @@
|
||||
},
|
||||
{
|
||||
"name": "gregwar/image",
|
||||
"version": "v2.0.22",
|
||||
"version": "v2.0.23",
|
||||
"target-dir": "Gregwar/Image",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Gregwar/Image.git",
|
||||
"reference": "c506d57d7fb5e67961d4eea6540ae8e23dffd406"
|
||||
"reference": "25fbb91a95d41d44587ee7ca8923745b66221a7d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Gregwar/Image/zipball/c506d57d7fb5e67961d4eea6540ae8e23dffd406",
|
||||
"reference": "c506d57d7fb5e67961d4eea6540ae8e23dffd406",
|
||||
"url": "https://api.github.com/repos/Gregwar/Image/zipball/25fbb91a95d41d44587ee7ca8923745b66221a7d",
|
||||
"reference": "25fbb91a95d41d44587ee7ca8923745b66221a7d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -537,36 +537,37 @@
|
||||
"gd",
|
||||
"image"
|
||||
],
|
||||
"time": "2018-01-31T17:40:17+00:00"
|
||||
"time": "2018-10-25T17:12:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/psr7",
|
||||
"version": "1.4.2",
|
||||
"version": "1.5.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/psr7.git",
|
||||
"reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c"
|
||||
"reference": "9f83dded91781a01c63574e387eaa769be769115"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
|
||||
"reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/9f83dded91781a01c63574e387eaa769be769115",
|
||||
"reference": "9f83dded91781a01c63574e387eaa769be769115",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4.0",
|
||||
"psr/http-message": "~1.0"
|
||||
"psr/http-message": "~1.0",
|
||||
"ralouphie/getallheaders": "^2.0.5"
|
||||
},
|
||||
"provide": {
|
||||
"psr/http-message-implementation": "1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.0"
|
||||
"phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.4-dev"
|
||||
"dev-master": "1.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -596,13 +597,14 @@
|
||||
"keywords": [
|
||||
"http",
|
||||
"message",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response",
|
||||
"stream",
|
||||
"uri",
|
||||
"url"
|
||||
],
|
||||
"time": "2017-03-20T17:10:46+00:00"
|
||||
"time": "2018-12-04T20:46:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/climate",
|
||||
@@ -667,16 +669,16 @@
|
||||
},
|
||||
{
|
||||
"name": "matthiasmullie/minify",
|
||||
"version": "1.3.60",
|
||||
"version": "1.3.61",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/matthiasmullie/minify.git",
|
||||
"reference": "ab7fea80ce5ce6549baaf272bc8bd926a7e08f90"
|
||||
"reference": "d5acb8ce5b6acb7d11bafe97cecc533f6e4fd751"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/matthiasmullie/minify/zipball/ab7fea80ce5ce6549baaf272bc8bd926a7e08f90",
|
||||
"reference": "ab7fea80ce5ce6549baaf272bc8bd926a7e08f90",
|
||||
"url": "https://api.github.com/repos/matthiasmullie/minify/zipball/d5acb8ce5b6acb7d11bafe97cecc533f6e4fd751",
|
||||
"reference": "d5acb8ce5b6acb7d11bafe97cecc533f6e4fd751",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -723,20 +725,20 @@
|
||||
"minifier",
|
||||
"minify"
|
||||
],
|
||||
"time": "2018-04-18T08:50:35+00:00"
|
||||
"time": "2018-11-26T23:10:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "matthiasmullie/path-converter",
|
||||
"version": "1.1.1",
|
||||
"version": "1.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/matthiasmullie/path-converter.git",
|
||||
"reference": "3082a6838be02b930239a97d38b5c9da4d693aca"
|
||||
"reference": "5e4b121c8b9f97c80835c1d878b0812ba1d607c9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/3082a6838be02b930239a97d38b5c9da4d693aca",
|
||||
"reference": "3082a6838be02b930239a97d38b5c9da4d693aca",
|
||||
"url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/5e4b121c8b9f97c80835c1d878b0812ba1d607c9",
|
||||
"reference": "5e4b121c8b9f97c80835c1d878b0812ba1d607c9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -772,7 +774,7 @@
|
||||
"paths",
|
||||
"relative"
|
||||
],
|
||||
"time": "2018-02-02T11:30:10+00:00"
|
||||
"time": "2018-10-25T15:19:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "maximebf/debugbar",
|
||||
@@ -892,16 +894,16 @@
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "1.23.0",
|
||||
"version": "1.24.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Seldaek/monolog.git",
|
||||
"reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4"
|
||||
"reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4",
|
||||
"reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266",
|
||||
"reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -966,7 +968,7 @@
|
||||
"logging",
|
||||
"psr-3"
|
||||
],
|
||||
"time": "2017-06-19T01:22:40+00:00"
|
||||
"time": "2018-11-05T09:00:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pimple/pimple",
|
||||
@@ -1119,16 +1121,16 @@
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "1.0.2",
|
||||
"version": "1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/log.git",
|
||||
"reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
|
||||
"reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
|
||||
"reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
|
||||
"reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1162,7 +1164,7 @@
|
||||
"psr",
|
||||
"psr-3"
|
||||
],
|
||||
"time": "2016-10-10T12:19:37+00:00"
|
||||
"time": "2018-11-20T15:27:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/simple-cache",
|
||||
@@ -1212,6 +1214,46 @@
|
||||
],
|
||||
"time": "2017-10-23T01:57:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ralouphie/getallheaders",
|
||||
"version": "2.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ralouphie/getallheaders.git",
|
||||
"reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa",
|
||||
"reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~3.7.0",
|
||||
"satooshi/php-coveralls": ">=1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/getallheaders.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ralph Khattar",
|
||||
"email": "ralph.khattar@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A polyfill for getallheaders.",
|
||||
"time": "2016-02-11T07:05:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "rockettheme/toolbox",
|
||||
"version": "1.4.2",
|
||||
@@ -1311,16 +1353,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v3.4.14",
|
||||
"version": "v3.4.21",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "6b217594552b9323bcdcfc14f8a0ce126e84cd73"
|
||||
"reference": "a700b874d3692bc8342199adfb6d3b99f62cc61a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/6b217594552b9323bcdcfc14f8a0ce126e84cd73",
|
||||
"reference": "6b217594552b9323bcdcfc14f8a0ce126e84cd73",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/a700b874d3692bc8342199adfb6d3b99f62cc61a",
|
||||
"reference": "a700b874d3692bc8342199adfb6d3b99f62cc61a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1376,20 +1418,20 @@
|
||||
],
|
||||
"description": "Symfony Console Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T11:19:56+00:00"
|
||||
"time": "2019-01-04T04:42:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/debug",
|
||||
"version": "v3.4.14",
|
||||
"version": "v3.4.21",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/debug.git",
|
||||
"reference": "d5a058ff6ecad26b30c1ba452241306ea34c65cc"
|
||||
"reference": "26d7f23b9bd0b93bee5583e4d6ca5cb1ab31b186"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/debug/zipball/d5a058ff6ecad26b30c1ba452241306ea34c65cc",
|
||||
"reference": "d5a058ff6ecad26b30c1ba452241306ea34c65cc",
|
||||
"url": "https://api.github.com/repos/symfony/debug/zipball/26d7f23b9bd0b93bee5583e4d6ca5cb1ab31b186",
|
||||
"reference": "26d7f23b9bd0b93bee5583e4d6ca5cb1ab31b186",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1432,20 +1474,20 @@
|
||||
],
|
||||
"description": "Symfony Debug Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T11:19:56+00:00"
|
||||
"time": "2019-01-01T13:45:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v3.4.14",
|
||||
"version": "v3.4.21",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
"reference": "b2e1f19280c09a42dc64c0b72b80fe44dd6e88fb"
|
||||
"reference": "d1cdd46c53c264a2bd42505bd0e8ce21423bd0e2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b2e1f19280c09a42dc64c0b72b80fe44dd6e88fb",
|
||||
"reference": "b2e1f19280c09a42dc64c0b72b80fe44dd6e88fb",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d1cdd46c53c264a2bd42505bd0e8ce21423bd0e2",
|
||||
"reference": "d1cdd46c53c264a2bd42505bd0e8ce21423bd0e2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1495,11 +1537,11 @@
|
||||
],
|
||||
"description": "Symfony EventDispatcher Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T09:06:28+00:00"
|
||||
"time": "2019-01-01T18:08:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.9.0",
|
||||
"version": "v1.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
@@ -1557,16 +1599,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-iconv",
|
||||
"version": "v1.9.0",
|
||||
"version": "v1.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-iconv.git",
|
||||
"reference": "bcc0cd69185b8a5d8b4a5400c489ed3333bf9bb2"
|
||||
"reference": "97001cfc283484c9691769f51cdf25259037eba2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/bcc0cd69185b8a5d8b4a5400c489ed3333bf9bb2",
|
||||
"reference": "bcc0cd69185b8a5d8b4a5400c489ed3333bf9bb2",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/97001cfc283484c9691769f51cdf25259037eba2",
|
||||
"reference": "97001cfc283484c9691769f51cdf25259037eba2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1612,20 +1654,20 @@
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2018-08-06T14:22:27+00:00"
|
||||
"time": "2018-09-21T06:26:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.9.0",
|
||||
"version": "v1.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8"
|
||||
"reference": "c79c051f5b3a46be09205c73b80b346e4153e494"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8",
|
||||
"reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494",
|
||||
"reference": "c79c051f5b3a46be09205c73b80b346e4153e494",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1671,20 +1713,20 @@
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2018-08-06T14:22:27+00:00"
|
||||
"time": "2018-09-21T13:07:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-dumper",
|
||||
"version": "v3.4.14",
|
||||
"version": "v3.4.21",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-dumper.git",
|
||||
"reference": "f62a394bd3de96f2f5e8f4c7d685035897fb3cb3"
|
||||
"reference": "a5f39641bb62e8b74e343467b145331273f615a2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/f62a394bd3de96f2f5e8f4c7d685035897fb3cb3",
|
||||
"reference": "f62a394bd3de96f2f5e8f4c7d685035897fb3cb3",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/a5f39641bb62e8b74e343467b145331273f615a2",
|
||||
"reference": "a5f39641bb62e8b74e343467b145331273f615a2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1740,20 +1782,20 @@
|
||||
"debug",
|
||||
"dump"
|
||||
],
|
||||
"time": "2018-07-26T11:19:56+00:00"
|
||||
"time": "2019-01-01T13:45:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v3.4.14",
|
||||
"version": "v3.4.21",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "810af2d35fc72b6cf5c01116806d2b65ccaaf2e2"
|
||||
"reference": "554a59a1ccbaac238a89b19c8e551a556fd0e2ea"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/810af2d35fc72b6cf5c01116806d2b65ccaaf2e2",
|
||||
"reference": "810af2d35fc72b6cf5c01116806d2b65ccaaf2e2",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/554a59a1ccbaac238a89b19c8e551a556fd0e2ea",
|
||||
"reference": "554a59a1ccbaac238a89b19c8e551a556fd0e2ea",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1799,35 +1841,35 @@
|
||||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T11:19:56+00:00"
|
||||
"time": "2019-01-01T13:45:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v1.35.4",
|
||||
"version": "v1.37.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "7e081e98378a1e78c29cc9eba4aefa5d78a05d2a"
|
||||
"reference": "66be9366c76cbf23e82e7171d47cbfa54a057a62"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/7e081e98378a1e78c29cc9eba4aefa5d78a05d2a",
|
||||
"reference": "7e081e98378a1e78c29cc9eba4aefa5d78a05d2a",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/66be9366c76cbf23e82e7171d47cbfa54a057a62",
|
||||
"reference": "66be9366c76cbf23e82e7171d47cbfa54a057a62",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"php": ">=5.4.0",
|
||||
"symfony/polyfill-ctype": "^1.8"
|
||||
},
|
||||
"require-dev": {
|
||||
"psr/container": "^1.0",
|
||||
"symfony/debug": "^2.7",
|
||||
"symfony/phpunit-bridge": "^3.3"
|
||||
"symfony/phpunit-bridge": "^3.4.19|^4.1.8"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.35-dev"
|
||||
"dev-master": "1.37-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -1865,22 +1907,22 @@
|
||||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"time": "2018-07-13T07:12:17+00:00"
|
||||
"time": "2019-01-14T14:59:29+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "behat/gherkin",
|
||||
"version": "v4.5.1",
|
||||
"version": "v4.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Behat/Gherkin.git",
|
||||
"reference": "74ac03d52c5e23ad8abd5c5cce4ab0e8dc1b530a"
|
||||
"reference": "ab0a02ea14893860bca00f225f5621d351a3ad07"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Behat/Gherkin/zipball/74ac03d52c5e23ad8abd5c5cce4ab0e8dc1b530a",
|
||||
"reference": "74ac03d52c5e23ad8abd5c5cce4ab0e8dc1b530a",
|
||||
"url": "https://api.github.com/repos/Behat/Gherkin/zipball/ab0a02ea14893860bca00f225f5621d351a3ad07",
|
||||
"reference": "ab0a02ea14893860bca00f225f5621d351a3ad07",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1888,8 +1930,8 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.5|~5",
|
||||
"symfony/phpunit-bridge": "~2.7|~3",
|
||||
"symfony/yaml": "~2.3|~3"
|
||||
"symfony/phpunit-bridge": "~2.7|~3|~4",
|
||||
"symfony/yaml": "~2.3|~3|~4"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/yaml": "If you want to parse features, represented in YAML files"
|
||||
@@ -1926,26 +1968,27 @@
|
||||
"gherkin",
|
||||
"parser"
|
||||
],
|
||||
"time": "2017-08-30T11:04:43+00:00"
|
||||
"time": "2019-01-16T14:22:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "codeception/codeception",
|
||||
"version": "2.4.5",
|
||||
"version": "2.5.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Codeception/Codeception.git",
|
||||
"reference": "5fee32d5c82791548931cbc34806b4de6aa1abfc"
|
||||
"reference": "4f89de32929fef53ca6d83b159fe329b6d484c1c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/5fee32d5c82791548931cbc34806b4de6aa1abfc",
|
||||
"reference": "5fee32d5c82791548931cbc34806b4de6aa1abfc",
|
||||
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/4f89de32929fef53ca6d83b159fe329b6d484c1c",
|
||||
"reference": "4f89de32929fef53ca6d83b159fe329b6d484c1c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"behat/gherkin": "^4.4.0",
|
||||
"codeception/phpunit-wrapper": "^6.0.9|^7.0.6",
|
||||
"codeception/stub": "^2.0",
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"facebook/webdriver": ">=1.1.3 <2.0",
|
||||
@@ -1993,7 +2036,7 @@
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Codeception\\": "src\\Codeception",
|
||||
"Codeception\\": "src/Codeception",
|
||||
"Codeception\\Extension\\": "ext"
|
||||
}
|
||||
},
|
||||
@@ -2017,7 +2060,7 @@
|
||||
"functional testing",
|
||||
"unit testing"
|
||||
],
|
||||
"time": "2018-08-01T07:21:49+00:00"
|
||||
"time": "2019-01-02T10:28:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "codeception/phpunit-wrapper",
|
||||
@@ -3334,16 +3377,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/browser-kit",
|
||||
"version": "v3.4.14",
|
||||
"version": "v3.4.21",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/browser-kit.git",
|
||||
"reference": "f6668d1a6182d5a8dec65a1c863a4c1d963816c0"
|
||||
"reference": "6d98fb221a263c66b1311203fe4eed154035f508"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/f6668d1a6182d5a8dec65a1c863a4c1d963816c0",
|
||||
"reference": "f6668d1a6182d5a8dec65a1c863a4c1d963816c0",
|
||||
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/6d98fb221a263c66b1311203fe4eed154035f508",
|
||||
"reference": "6d98fb221a263c66b1311203fe4eed154035f508",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3387,20 +3430,20 @@
|
||||
],
|
||||
"description": "Symfony BrowserKit Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T09:06:28+00:00"
|
||||
"time": "2019-01-01T13:45:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/css-selector",
|
||||
"version": "v3.4.14",
|
||||
"version": "v3.4.21",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/css-selector.git",
|
||||
"reference": "edda5a6155000ff8c3a3f85ee5c421af93cca416"
|
||||
"reference": "12f86295c46c36af9896cf21db6b6b8a1465315d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/css-selector/zipball/edda5a6155000ff8c3a3f85ee5c421af93cca416",
|
||||
"reference": "edda5a6155000ff8c3a3f85ee5c421af93cca416",
|
||||
"url": "https://api.github.com/repos/symfony/css-selector/zipball/12f86295c46c36af9896cf21db6b6b8a1465315d",
|
||||
"reference": "12f86295c46c36af9896cf21db6b6b8a1465315d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3440,20 +3483,20 @@
|
||||
],
|
||||
"description": "Symfony CssSelector Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T09:06:28+00:00"
|
||||
"time": "2019-01-02T09:30:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/dom-crawler",
|
||||
"version": "v3.4.14",
|
||||
"version": "v3.4.21",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/dom-crawler.git",
|
||||
"reference": "452bfc854b60134438e3824b159b0d24a5892331"
|
||||
"reference": "311f666d85d1075b0a294ba1f3de4ae9307d8180"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/452bfc854b60134438e3824b159b0d24a5892331",
|
||||
"reference": "452bfc854b60134438e3824b159b0d24a5892331",
|
||||
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/311f666d85d1075b0a294ba1f3de4ae9307d8180",
|
||||
"reference": "311f666d85d1075b0a294ba1f3de4ae9307d8180",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3497,20 +3540,20 @@
|
||||
],
|
||||
"description": "Symfony DomCrawler Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T10:03:52+00:00"
|
||||
"time": "2019-01-01T13:45:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v3.4.14",
|
||||
"version": "v3.4.21",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "8a84fcb207451df0013b2c74cbbf1b62d47b999a"
|
||||
"reference": "3f2a2ab6315dd7682d4c16dcae1e7b95c8b8555e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/8a84fcb207451df0013b2c74cbbf1b62d47b999a",
|
||||
"reference": "8a84fcb207451df0013b2c74cbbf1b62d47b999a",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/3f2a2ab6315dd7682d4c16dcae1e7b95c8b8555e",
|
||||
"reference": "3f2a2ab6315dd7682d4c16dcae1e7b95c8b8555e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3546,20 +3589,20 @@
|
||||
],
|
||||
"description": "Symfony Finder Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T11:19:56+00:00"
|
||||
"time": "2019-01-01T13:45:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v3.4.14",
|
||||
"version": "v3.4.21",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "0414db29bd770ec5a4152683e655f55efd4fa60f"
|
||||
"reference": "0d41dd7d95ed179aed6a13393b0f4f97bfa2d25c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/0414db29bd770ec5a4152683e655f55efd4fa60f",
|
||||
"reference": "0414db29bd770ec5a4152683e655f55efd4fa60f",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/0d41dd7d95ed179aed6a13393b0f4f97bfa2d25c",
|
||||
"reference": "0d41dd7d95ed179aed6a13393b0f4f97bfa2d25c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3595,7 +3638,7 @@
|
||||
],
|
||||
"description": "Symfony Process Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T11:19:56+00:00"
|
||||
"time": "2019-01-02T21:24:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "victorjonsson/markdowndocs",
|
||||
@@ -3645,20 +3688,21 @@
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
"version": "1.3.0",
|
||||
"version": "1.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webmozart/assert.git",
|
||||
"reference": "0df1908962e7a3071564e857d86874dad1ef204a"
|
||||
"reference": "83e253c8e0be5b0257b881e1827274667c5c17a9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a",
|
||||
"reference": "0df1908962e7a3071564e857d86874dad1ef204a",
|
||||
"url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9",
|
||||
"reference": "83e253c8e0be5b0257b881e1827274667c5c17a9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.3.3 || ^7.0"
|
||||
"php": "^5.3.3 || ^7.0",
|
||||
"symfony/polyfill-ctype": "^1.8"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.6",
|
||||
@@ -3691,7 +3735,7 @@
|
||||
"check",
|
||||
"validate"
|
||||
],
|
||||
"time": "2018-01-29T19:49:41+00:00"
|
||||
"time": "2018-12-25T11:19:39+00:00"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
@@ -3706,7 +3750,8 @@
|
||||
"ext-mbstring": "*",
|
||||
"ext-openssl": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-zip": "*"
|
||||
"ext-zip": "*",
|
||||
"ext-json": "*"
|
||||
},
|
||||
"platform-dev": [],
|
||||
"platform-overrides": {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Core
|
||||
*
|
||||
@@ -7,6 +8,7 @@
|
||||
*/
|
||||
|
||||
namespace Grav;
|
||||
|
||||
define('GRAV_PHP_MIN', '5.6.4');
|
||||
|
||||
// Ensure vendor libraries exist
|
||||
@@ -29,7 +31,7 @@ if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) {
|
||||
}
|
||||
|
||||
// Register the auto-loader.
|
||||
$loader = require_once $autoload;
|
||||
$loader = require $autoload;
|
||||
|
||||
// Set timezone to default, falls back to system if php.ini not set
|
||||
date_default_timezone_set(@date_default_timezone_get());
|
||||
|
||||
99
system/blueprints/config/security.yaml
Normal file
99
system/blueprints/config/security.yaml
Normal file
@@ -0,0 +1,99 @@
|
||||
title: PLUGIN_ADMIN.SECURITY
|
||||
|
||||
form:
|
||||
validation: loose
|
||||
fields:
|
||||
|
||||
xss_section:
|
||||
type: section
|
||||
title: PLUGIN_ADMIN.XSS_SECURITY
|
||||
underline: true
|
||||
|
||||
xss_whitelist:
|
||||
type: selectize
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.XSS_WHITELIST_PERMISSIONS
|
||||
help: PLUGIN_ADMIN.XSS_WHITELIST_PERMISSIONS_HELP
|
||||
placeholder: 'admin.super'
|
||||
classes: fancy
|
||||
validate:
|
||||
type: commalist
|
||||
|
||||
xss_enabled.on_events:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.XSS_ON_EVENTS
|
||||
highlight: 1
|
||||
options:
|
||||
1: PLUGIN_ADMIN.YES
|
||||
0: PLUGIN_ADMIN.NO
|
||||
default: true
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
xss_enabled.invalid_protocols:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.XSS_INVALID_PROTOCOLS
|
||||
highlight: 1
|
||||
options:
|
||||
1: PLUGIN_ADMIN.YES
|
||||
0: PLUGIN_ADMIN.NO
|
||||
default: true
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
xss_enabled.moz_binding:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.XSS_MOZ_BINDINGS
|
||||
highlight: 1
|
||||
options:
|
||||
1: PLUGIN_ADMIN.YES
|
||||
0: PLUGIN_ADMIN.NO
|
||||
default: true
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
xss_enabled.html_inline_styles:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.XSS_HTML_INLINE_STYLES
|
||||
highlight: 1
|
||||
options:
|
||||
1: PLUGIN_ADMIN.YES
|
||||
0: PLUGIN_ADMIN.NO
|
||||
default: true
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
xss_enabled.dangerous_tags:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.XSS_DANGEROUS_TAGS
|
||||
highlight: 1
|
||||
options:
|
||||
1: PLUGIN_ADMIN.YES
|
||||
0: PLUGIN_ADMIN.NO
|
||||
default: true
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
xss_dangerous_tags:
|
||||
type: selectize
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.XSS_DANGEROUS_TAGS_LIST
|
||||
classes: fancy
|
||||
validate:
|
||||
type: commalist
|
||||
|
||||
uploads_section:
|
||||
type: section
|
||||
title: PLUGIN_ADMIN.UPLOADS_SECURITY
|
||||
underline: true
|
||||
|
||||
|
||||
uploads_dangerous_extensions:
|
||||
type: selectize
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.UPLOADS_DANGEROUS_EXTENSIONS
|
||||
help: PLUGIN_ADMIN.UPLOADS_DANGEROUS_EXTENSIONS_HELP
|
||||
classes: fancy
|
||||
validate:
|
||||
type: commalist
|
||||
|
||||
@@ -21,6 +21,9 @@ form:
|
||||
title: PLUGIN_ADMIN.CONTENT
|
||||
|
||||
fields:
|
||||
xss_check:
|
||||
type: xss
|
||||
|
||||
header.title:
|
||||
type: text
|
||||
autofocus: true
|
||||
|
||||
@@ -53,7 +53,7 @@ types:
|
||||
thumb: media/thumb-flv.png
|
||||
mime: video/x-flv
|
||||
webm:
|
||||
type: file
|
||||
type: video
|
||||
thumb: media/thumb-webm.png
|
||||
mime: video/webm
|
||||
ogv:
|
||||
|
||||
31
system/config/security.yaml
Normal file
31
system/config/security.yaml
Normal file
@@ -0,0 +1,31 @@
|
||||
xss_whitelist: [admin.super] # Whitelist of user access that should 'skip' XSS checking
|
||||
xss_enabled:
|
||||
on_events: true
|
||||
invalid_protocols: true
|
||||
moz_binding: true
|
||||
html_inline_styles: true
|
||||
dangerous_tags: true
|
||||
xss_dangerous_tags:
|
||||
- applet
|
||||
- meta
|
||||
- xml
|
||||
- blink
|
||||
- link
|
||||
- style
|
||||
- script
|
||||
- embed
|
||||
- object
|
||||
- iframe
|
||||
- frame
|
||||
- frameset
|
||||
- ilayer
|
||||
- layer
|
||||
- bgsound
|
||||
- title
|
||||
- base
|
||||
uploads_dangerous_extensions:
|
||||
- php
|
||||
- html
|
||||
- htm
|
||||
- js
|
||||
- exe
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
// Some standard defines
|
||||
define('GRAV', true);
|
||||
define('GRAV_VERSION', '1.5.1');
|
||||
define('GRAV_VERSION', '1.5.7');
|
||||
define('GRAV_TESTING', false);
|
||||
define('DS', '/');
|
||||
|
||||
|
||||
@@ -72,7 +72,6 @@ NICETIME:
|
||||
SEC: sec
|
||||
MIN: min
|
||||
HR: hr
|
||||
DAY: day
|
||||
WK: wk
|
||||
MO: mo
|
||||
YR: yr
|
||||
@@ -88,7 +87,6 @@ NICETIME:
|
||||
SEC_PLURAL: secs
|
||||
MIN_PLURAL: mins
|
||||
HR_PLURAL: hrs
|
||||
DAY_PLURAL: days
|
||||
WK_PLURAL: wks
|
||||
MO_PLURAL: mos
|
||||
YR_PLURAL: yrs
|
||||
|
||||
@@ -30,7 +30,6 @@ NICETIME:
|
||||
SEC: 秒
|
||||
MIN: 分
|
||||
HR: 時
|
||||
DAY: 日
|
||||
WK: 週
|
||||
MO: 月
|
||||
YR: 年
|
||||
@@ -46,7 +45,6 @@ NICETIME:
|
||||
SEC_PLURAL: 秒
|
||||
MIN_PLURAL: 分
|
||||
HR_PLURAL: 時
|
||||
DAY_PLURAL: 日
|
||||
WK_PLURAL: 週
|
||||
MO_PLURAL: 月
|
||||
YR_PLURAL: 年
|
||||
|
||||
@@ -109,6 +109,8 @@ class Config extends Data
|
||||
*/
|
||||
public function getLanguages()
|
||||
{
|
||||
user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.5, use Grav::instance()[\'languages\'] instead', E_USER_DEPRECATED);
|
||||
|
||||
return Grav::instance()['languages'];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
namespace Grav\Common;
|
||||
|
||||
use DebugBar\DataCollector\ConfigCollector;
|
||||
use DebugBar\DataCollector\MessagesCollector;
|
||||
use DebugBar\JavascriptRenderer;
|
||||
use DebugBar\StandardDebugBar;
|
||||
use Grav\Common\Config\Config;
|
||||
@@ -31,6 +32,11 @@ class Debugger
|
||||
|
||||
protected $timers = [];
|
||||
|
||||
/** @var string[] $deprecations */
|
||||
protected $deprecations = [];
|
||||
|
||||
protected $errorHandler;
|
||||
|
||||
/**
|
||||
* Debugger constructor.
|
||||
*/
|
||||
@@ -41,6 +47,9 @@ class Debugger
|
||||
|
||||
$this->debugbar = new StandardDebugBar();
|
||||
$this->debugbar['time']->addMeasure('Loading', $this->debugbar['time']->getRequestStartTime(), microtime(true));
|
||||
|
||||
// Set deprecation collector.
|
||||
$this->setErrorHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,9 +137,9 @@ class Debugger
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCaller($ignore = 2)
|
||||
public function getCaller($limit = 2)
|
||||
{
|
||||
$trace = debug_backtrace(false, $ignore);
|
||||
$trace = debug_backtrace(false, $limit);
|
||||
|
||||
return array_pop($trace);
|
||||
}
|
||||
@@ -177,6 +186,8 @@ class Debugger
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->addDeprecations();
|
||||
|
||||
echo $this->renderer->render();
|
||||
}
|
||||
|
||||
@@ -191,6 +202,7 @@ class Debugger
|
||||
public function sendDataInHeaders()
|
||||
{
|
||||
if ($this->enabled()) {
|
||||
$this->addDeprecations();
|
||||
$this->debugbar->sendDataInHeaders();
|
||||
}
|
||||
|
||||
@@ -208,6 +220,7 @@ class Debugger
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->addDeprecations();
|
||||
$this->timers = [];
|
||||
|
||||
return $this->debugbar->getData();
|
||||
@@ -279,4 +292,152 @@ class Debugger
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setErrorHandler()
|
||||
{
|
||||
$this->errorHandler = set_error_handler(
|
||||
[$this, 'deprecatedErrorHandler']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $errno
|
||||
* @param string $errstr
|
||||
* @param string $errfile
|
||||
* @param int $errline
|
||||
* @return bool
|
||||
*/
|
||||
public function deprecatedErrorHandler($errno, $errstr, $errfile, $errline)
|
||||
{
|
||||
if ($errno !== E_USER_DEPRECATED) {
|
||||
if ($this->errorHandler) {
|
||||
return \call_user_func($this->errorHandler, $errno, $errstr, $errfile, $errline);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$this->enabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$backtrace = debug_backtrace(false);
|
||||
|
||||
// Skip current call.
|
||||
array_shift($backtrace);
|
||||
|
||||
// Skip vendor libraries and the method where error was triggered.
|
||||
while ($current = array_shift($backtrace)) {
|
||||
if (isset($current['file']) && strpos($current['file'], 'vendor') !== false) {
|
||||
continue;
|
||||
}
|
||||
if (isset($current['function']) && ($current['function'] === 'user_error' || $current['function'] === 'trigger_error')) {
|
||||
$current = array_shift($backtrace);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Add back last call.
|
||||
array_unshift($backtrace, $current);
|
||||
|
||||
// Filter arguments.
|
||||
foreach ($backtrace as &$current) {
|
||||
if (isset($current['args'])) {
|
||||
$args = [];
|
||||
foreach ($current['args'] as $arg) {
|
||||
if (\is_string($arg)) {
|
||||
$args[] = "'" . $arg . "'";
|
||||
} elseif (\is_bool($arg)) {
|
||||
$args[] = $arg ? 'true' : 'false';
|
||||
} elseif (\is_scalar($arg)) {
|
||||
$args[] = $arg;
|
||||
} elseif (\is_object($arg)) {
|
||||
$args[] = get_class($arg) . ' $object';
|
||||
} elseif (\is_array($arg)) {
|
||||
$args[] = '$array';
|
||||
} else {
|
||||
$args[] = '$object';
|
||||
}
|
||||
}
|
||||
$current['args'] = $args;
|
||||
}
|
||||
}
|
||||
unset($current);
|
||||
|
||||
$this->deprecations[] = [
|
||||
'message' => $errstr,
|
||||
'file' => $errfile,
|
||||
'line' => $errline,
|
||||
'trace' => $backtrace,
|
||||
];
|
||||
|
||||
// Do not pass forward.
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function addDeprecations()
|
||||
{
|
||||
if (!$this->deprecations) {
|
||||
return;
|
||||
}
|
||||
|
||||
$collector = new MessagesCollector('deprecated');
|
||||
$this->addCollector($collector);
|
||||
$collector->addMessage('Your site is using following deprecated features:');
|
||||
|
||||
/** @var array $deprecated */
|
||||
foreach ($this->deprecations as $deprecated) {
|
||||
list($message, $scope) = $this->getDepracatedMessage($deprecated);
|
||||
|
||||
$collector->addMessage($message, $scope);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getDepracatedMessage($deprecated)
|
||||
{
|
||||
$scope = 'unknown';
|
||||
if (stripos($deprecated['message'], 'grav') !== false) {
|
||||
$scope = 'grav';
|
||||
} elseif (!isset($deprecated['file'])) {
|
||||
$scope = 'unknown';
|
||||
} elseif (stripos($deprecated['file'], 'twig') !== false) {
|
||||
$scope = 'twig';
|
||||
} elseif (stripos($deprecated['file'], 'yaml') !== false) {
|
||||
$scope = 'yaml';
|
||||
} elseif (stripos($deprecated['file'], 'vendor') !== false) {
|
||||
$scope = 'vendor';
|
||||
}
|
||||
|
||||
$trace = [];
|
||||
foreach ($deprecated['trace'] as $current) {
|
||||
$class = isset($current['class']) ? $current['class'] : '';
|
||||
$type = isset($current['type']) ? $current['type'] : '';
|
||||
$function = $this->getFunction($current);
|
||||
if (isset($current['file'])) {
|
||||
$current['file'] = str_replace(GRAV_ROOT . '/', '', $current['file']);
|
||||
}
|
||||
|
||||
unset($current['class'], $current['type'], $current['function'], $current['args']);
|
||||
|
||||
$trace[] = ['call' => $class . $type . $function] + $current;
|
||||
}
|
||||
|
||||
return [
|
||||
[
|
||||
'message' => $deprecated['message'],
|
||||
'trace' => $trace
|
||||
],
|
||||
$scope
|
||||
];
|
||||
}
|
||||
|
||||
protected function getFunction($trace)
|
||||
{
|
||||
if (!isset($trace['function'])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $trace['function'] . '(' . implode(', ', $trace['args']) . ')';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,13 @@ class BareHandler extends Handler
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$inspector = $this->getInspector();
|
||||
$code = $inspector->getException()->getCode();
|
||||
if ( ($code >= 400) && ($code < 600) )
|
||||
{
|
||||
$this->getRun()->sendHttpCode($code);
|
||||
}
|
||||
|
||||
return Handler::QUIT;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,5 +74,8 @@ class Errors
|
||||
}
|
||||
|
||||
$whoops->register();
|
||||
|
||||
// Re-register deprecation handler.
|
||||
$grav['debugger']->setErrorHandler();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,10 @@ class SimplePageHandler extends Handler
|
||||
$cssFile = $this->getResource("error.css");
|
||||
|
||||
$code = $inspector->getException()->getCode();
|
||||
if ( ($code >= 400) && ($code < 600) )
|
||||
{
|
||||
$this->getRun()->sendHttpCode($code);
|
||||
}
|
||||
$message = $inspector->getException()->getMessage();
|
||||
|
||||
if ($inspector->getException() instanceof \ErrorException) {
|
||||
|
||||
@@ -82,4 +82,28 @@ trait CompiledFile
|
||||
|
||||
return parent::content($var);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize file.
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
return [
|
||||
'filename',
|
||||
'extension',
|
||||
'raw',
|
||||
'content',
|
||||
'settings'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Unserialize file.
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
if (!isset(static::$instances[$this->filename])) {
|
||||
static::$instances[$this->filename] = $this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
namespace Grav\Common;
|
||||
|
||||
/**
|
||||
* @deprecated 2.0
|
||||
* @deprecated 1.4 Use Grav::instance() instead
|
||||
*/
|
||||
trait GravTrait
|
||||
{
|
||||
@@ -24,8 +24,7 @@ trait GravTrait
|
||||
self::$grav = Grav::instance();
|
||||
}
|
||||
|
||||
$caller = self::$grav['debugger']->getCaller();
|
||||
self::$grav['debugger']->addMessage("Deprecated GravTrait used in {$caller['file']}", 'deprecated');
|
||||
user_error(__TRAIT__ . ' is deprecated since Grav 1.4, use Grav::instance() instead', E_USER_DEPRECATED);
|
||||
|
||||
return self::$grav;
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ class Excerpts
|
||||
*/
|
||||
public static function processLinkExcerpt($excerpt, Page $page, $type = 'link')
|
||||
{
|
||||
$url = htmlspecialchars_decode(urldecode($excerpt['element']['attributes']['href']));
|
||||
$url = htmlspecialchars_decode(rawurldecode($excerpt['element']['attributes']['href']));
|
||||
|
||||
$url_parts = static::parseUrl($url);
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ class Language
|
||||
$uri = preg_replace("/\\" . $matches[1] . '/', '', $uri, 1);
|
||||
|
||||
// Store in session if language is different.
|
||||
if (isset($this->grav['session']) && $this->grav['session']->started()
|
||||
if (isset($this->grav['session']) && $this->grav['session']->isStarted()
|
||||
&& $this->config->get('system.languages.session_store_active', true)
|
||||
&& $this->grav['session']->active_language != $this->active
|
||||
) {
|
||||
@@ -189,7 +189,7 @@ class Language
|
||||
}
|
||||
} else {
|
||||
// Try getting language from the session, else no active.
|
||||
if (isset($this->grav['session']) && $this->grav['session']->started()
|
||||
if (isset($this->grav['session']) && $this->grav['session']->isStarted()
|
||||
&& $this->config->get('system.languages.session_store_active', true)) {
|
||||
$this->active = $this->grav['session']->active_language ?: null;
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ class ImageMedium extends Medium
|
||||
foreach ($this->alternatives as $ratio => $medium) {
|
||||
$srcset[] = $medium->url($reset) . ' ' . $medium->get('width') . 'w';
|
||||
}
|
||||
$srcset[] = $this->url($reset) . ' ' . $this->get('width') . 'w';
|
||||
$srcset[] = str_replace(' ', '%20', $this->url($reset)) . ' ' . $this->get('width') . 'w';
|
||||
|
||||
return implode(', ', $srcset);
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ class Page implements PageInterface
|
||||
$this->metadata();
|
||||
$this->url();
|
||||
$this->visible();
|
||||
$this->modularTwig($this->slug[0] === '_');
|
||||
$this->modularTwig(strpos($this->slug(), '_') === 0);
|
||||
$this->setPublishState();
|
||||
$this->published();
|
||||
$this->urlExtension();
|
||||
@@ -168,7 +168,7 @@ class Page implements PageInterface
|
||||
unset($process_fields[$field]);
|
||||
}
|
||||
}
|
||||
$text_header = Grav::instance()['twig']->processString(json_encode($process_fields), ['page' => $this]);
|
||||
$text_header = Grav::instance()['twig']->processString(json_encode($process_fields, JSON_UNESCAPED_UNICODE), ['page' => $this]);
|
||||
$this->header((object)(json_decode($text_header, true) + $ignored_fields));
|
||||
}
|
||||
}
|
||||
@@ -195,7 +195,7 @@ class Page implements PageInterface
|
||||
|
||||
$route = isset($aPage->header()->routes['default']) ? $aPage->header()->routes['default'] : $aPage->rawRoute();
|
||||
if (!$route) {
|
||||
$route = $aPage->slug();
|
||||
$route = $aPage->route();
|
||||
}
|
||||
|
||||
if ($onlyPublished && !$aPage->published()) {
|
||||
@@ -764,6 +764,8 @@ class Page implements PageInterface
|
||||
|
||||
// pages.markdown_extra is deprecated, but still check it...
|
||||
if (!isset($defaults['extra']) && (isset($this->markdown_extra) || $config->get('system.pages.markdown_extra') !== null)) {
|
||||
user_error('Configuration option \'system.pages.markdown_extra\' is deprecated since Grav 1.5, use \'system.pages.markdown.extra\' instead', E_USER_DEPRECATED);
|
||||
|
||||
$defaults['extra'] = $this->markdown_extra ?: $config->get('system.pages.markdown_extra');
|
||||
}
|
||||
|
||||
@@ -1582,7 +1584,7 @@ class Page implements PageInterface
|
||||
}
|
||||
|
||||
if (empty($this->slug)) {
|
||||
$this->slug = $this->adjustRouteCase(preg_replace(PAGE_ORDER_PREFIX_REGEX, '', $this->folder));
|
||||
$this->slug = $this->adjustRouteCase(preg_replace(PAGE_ORDER_PREFIX_REGEX, '', $this->folder)) ?: null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class InitializeProcessor extends ProcessorBase implements ProcessorInterface
|
||||
// Redirect pages with trailing slash if configured to do so.
|
||||
$path = $uri->path() ?: '/';
|
||||
if ($path !== '/' && $config->get('system.pages.redirect_trailing_slash', false) && Utils::endsWith($path, '/')) {
|
||||
$this->container->redirect(rtrim($path, '/'), 302);
|
||||
$this->container->redirectLangSafe(rtrim($path, '/'));
|
||||
}
|
||||
|
||||
$this->container->setLocale();
|
||||
|
||||
158
system/src/Grav/Common/Security.php
Normal file
158
system/src/Grav/Common/Security.php
Normal file
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Grav.Common
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Common;
|
||||
|
||||
class Security
|
||||
{
|
||||
|
||||
public static function detectXssFromPages($pages, callable $status = null)
|
||||
{
|
||||
$routes = $pages->routes();
|
||||
|
||||
// Remove duplicate for homepage
|
||||
unset($routes['/']);
|
||||
|
||||
$list = [];
|
||||
|
||||
// // This needs Symfony 4.1 to work
|
||||
// $status && $status([
|
||||
// 'type' => 'count',
|
||||
// 'steps' => count($routes),
|
||||
// ]);
|
||||
|
||||
foreach ($routes as $path) {
|
||||
|
||||
$status && $status([
|
||||
'type' => 'progress',
|
||||
]);
|
||||
|
||||
try {
|
||||
$page = $pages->get($path);
|
||||
|
||||
// call the content to load/cache it
|
||||
$header = (array) $page->header();
|
||||
$content = $page->value('content');
|
||||
|
||||
$data = ['header' => $header, 'content' => $content];
|
||||
$results = Security::detectXssFromArray($data);
|
||||
|
||||
if (!empty($results)) {
|
||||
$list[$page->filePathClean()] = $results;
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $array Array such as $_POST or $_GET
|
||||
* @param string $prefix Prefix for returned values.
|
||||
* @return array Returns flatten list of potentially dangerous input values, such as 'data.content'.
|
||||
*/
|
||||
public static function detectXssFromArray(array $array, $prefix = '')
|
||||
{
|
||||
$list = [];
|
||||
|
||||
foreach ($array as $key => $value) {
|
||||
if (\is_array($value)) {
|
||||
$list[] = static::detectXssFromArray($value, $prefix . $key . '.');
|
||||
}
|
||||
if ($result = static::detectXss($value)) {
|
||||
$list[] = [$prefix . $key => $result];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($list)) {
|
||||
return array_merge(...$list);
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if string potentially has a XSS attack. This simple function does not catch all XSS and it is likely to
|
||||
* return false positives because of it tags all potentially dangerous HTML tags and attributes without looking into
|
||||
* their content.
|
||||
*
|
||||
* @param string $string The string to run XSS detection logic on
|
||||
* @return boolean|string Type of XSS vector if the given `$string` may contain XSS, false otherwise.
|
||||
*
|
||||
* Copies the code from: https://github.com/symphonycms/xssfilter/blob/master/extension.driver.php#L138
|
||||
*/
|
||||
public static function detectXss($string)
|
||||
{
|
||||
// Skip any null or non string values
|
||||
if (null === $string || !\is_string($string) || empty($string)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Keep a copy of the original string before cleaning up
|
||||
$orig = $string;
|
||||
|
||||
// URL decode
|
||||
$string = urldecode($string);
|
||||
|
||||
// Convert Hexadecimals
|
||||
$string = (string)preg_replace_callback('!(&#|\\\)[xX]([0-9a-fA-F]+);?!u', function($m) {
|
||||
return \chr(hexdec($m[2]));
|
||||
}, $string);
|
||||
|
||||
// Clean up entities
|
||||
$string = preg_replace('!(�+[0-9]+)!u','$1;', $string);
|
||||
|
||||
// Decode entities
|
||||
$string = html_entity_decode($string, ENT_NOQUOTES, 'UTF-8');
|
||||
|
||||
// Strip whitespace characters
|
||||
$string = preg_replace('!\s!u','', $string);
|
||||
|
||||
$config = Grav::instance()['config'];
|
||||
|
||||
$dangerous_tags = $config->get('security.xss_dangerous_tags');
|
||||
$dangerous_tags = array_map('preg_quote', array_map("trim", $dangerous_tags));
|
||||
|
||||
$enabled_rules = $config->get('security.xss_enabled');
|
||||
|
||||
// Set the patterns we'll test against
|
||||
$patterns = [
|
||||
// Match any attribute starting with "on" or xmlns
|
||||
'on_events' => '#(<[^>]+[[a-z\x00-\x20\"\'\/])(\son|\sxmlns)[a-z].*=>?#iUu',
|
||||
|
||||
// Match javascript:, livescript:, vbscript:, mocha:, feed: and data: protocols
|
||||
'invalid_protocols' => '#((java|live|vb)script|mocha|feed|data):.*?#iUu',
|
||||
|
||||
// Match -moz-bindings
|
||||
'moz_binding' => '#-moz-binding[a-z\x00-\x20]*:#u',
|
||||
|
||||
// Match style attributes
|
||||
'html_inline_styles' => '#(<[^>]+[a-z\x00-\x20\"\'\/])(style=[^>]*(url\:|x\:expression).*)>?#iUu',
|
||||
|
||||
// Match potentially dangerous tags
|
||||
'dangerous_tags' => '#</*(' . implode('|', $dangerous_tags ) . ')[^>]*>?#ui'
|
||||
];
|
||||
|
||||
|
||||
// Iterate over rules and return label if fail
|
||||
foreach ((array) $patterns as $name => $regex) {
|
||||
if ($enabled_rules[$name] === true) {
|
||||
|
||||
if (preg_match($regex, $string) || preg_match($regex, $orig)) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -91,7 +91,7 @@ class SessionServiceProvider implements ServiceProviderInterface
|
||||
|
||||
// Define session message service.
|
||||
$container['messages'] = function ($c) {
|
||||
if (!isset($c['session']) || !$c['session']->started()) {
|
||||
if (!isset($c['session']) || !$c['session']->isStarted()) {
|
||||
/** @var Debugger $debugger */
|
||||
$debugger = $c['debugger'];
|
||||
$debugger->addMessage('Inactive session: session messages may disappear', 'warming');
|
||||
|
||||
@@ -15,10 +15,12 @@ class Session extends \Grav\Framework\Session\Session
|
||||
|
||||
/**
|
||||
* @return \Grav\Framework\Session\Session
|
||||
* @deprecated 1.5
|
||||
* @deprecated 1.5 Use getInstance() method instead
|
||||
*/
|
||||
public static function instance()
|
||||
{
|
||||
user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.5, use getInstance() method instead', E_USER_DEPRECATED);
|
||||
|
||||
return static::getInstance();
|
||||
}
|
||||
|
||||
@@ -51,10 +53,12 @@ class Session extends \Grav\Framework\Session\Session
|
||||
* Returns attributes.
|
||||
*
|
||||
* @return array Attributes
|
||||
* @deprecated 1.5
|
||||
* @deprecated 1.5 Use getAll() method instead
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.5, use getAll() method instead', E_USER_DEPRECATED);
|
||||
|
||||
return $this->getAll();
|
||||
}
|
||||
|
||||
@@ -62,10 +66,12 @@ class Session extends \Grav\Framework\Session\Session
|
||||
* Checks if the session was started.
|
||||
*
|
||||
* @return Boolean
|
||||
* @deprecated 1.5
|
||||
* @deprecated 1.5 Use isStarted() method instead
|
||||
*/
|
||||
public function started()
|
||||
{
|
||||
user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.5, use isStarted() method instead', E_USER_DEPRECATED);
|
||||
|
||||
return $this->isStarted();
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace Grav\Common\Twig\Node;
|
||||
|
||||
class TwigNodeScript extends \Twig_Node implements \Twig_NodeOutputInterface
|
||||
class TwigNodeScript extends \Twig_Node implements \Twig_NodeCaptureInterface
|
||||
{
|
||||
protected $tagName = 'script';
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace Grav\Common\Twig\Node;
|
||||
|
||||
class TwigNodeStyle extends \Twig_Node implements \Twig_NodeOutputInterface
|
||||
class TwigNodeStyle extends \Twig_Node implements \Twig_NodeCaptureInterface
|
||||
{
|
||||
protected $tagName = 'style';
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace Grav\Common\Twig\Node;
|
||||
|
||||
class TwigNodeSwitch extends \Twig_Node implements \Twig_NodeOutputInterface
|
||||
class TwigNodeSwitch extends \Twig_Node
|
||||
{
|
||||
public function __construct(
|
||||
\Twig_Node $value,
|
||||
|
||||
@@ -102,6 +102,28 @@ class Twig
|
||||
|
||||
$this->loader = new \Twig_Loader_Filesystem($this->twig_paths);
|
||||
|
||||
// Register all other prefixes as namespaces in twig
|
||||
foreach ($locator->getPaths('theme') as $prefix => $_) {
|
||||
if ($prefix === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$twig_paths = [];
|
||||
|
||||
// handle language templates if available
|
||||
if ($language->enabled()) {
|
||||
$lang_templates = $locator->findResource('theme://'.$prefix.'templates/' . ($active_language ? $active_language : $language->getDefault()));
|
||||
if ($lang_templates) {
|
||||
$twig_paths[] = $lang_templates;
|
||||
}
|
||||
}
|
||||
|
||||
$twig_paths = array_merge($twig_paths, $locator->findResources('theme://'.$prefix.'templates'));
|
||||
|
||||
$namespace = trim($prefix, '/');
|
||||
$this->loader->setPaths($twig_paths, $namespace);
|
||||
}
|
||||
|
||||
$this->grav->fireEvent('onTwigLoader');
|
||||
|
||||
$this->loaderArray = new \Twig_Loader_Array([]);
|
||||
@@ -115,9 +137,13 @@ class Twig
|
||||
|
||||
if (!$config->get('system.strict_mode.twig_compat', true)) {
|
||||
// Force autoescape on for all files if in strict mode.
|
||||
$params['autoescape'] = true;
|
||||
$params['autoescape'] = 'html';
|
||||
} elseif (!empty($this->autoescape)) {
|
||||
$params['autoescape'] = $this->autoescape;
|
||||
$params['autoescape'] = $this->autoescape ? 'html' : false;
|
||||
}
|
||||
|
||||
if (empty($params['autoescape'])) {
|
||||
user_error('Grav 2.0 will have Twig auto-escaping forced on (can be emulated by turning off \'system.strict_mode.twig_compat\' setting in your configuration)', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$this->twig = new TwigEnvironment($loader_chain, $params);
|
||||
@@ -411,8 +437,14 @@ class Twig
|
||||
* Overrides the autoescape setting
|
||||
*
|
||||
* @param boolean $state
|
||||
* @deprecated 1.5
|
||||
*/
|
||||
public function setAutoescape($state) {
|
||||
public function setAutoescape($state)
|
||||
{
|
||||
if (!$state) {
|
||||
user_error(__CLASS__ . '::' . __FUNCTION__ . '(false) is deprecated since Grav 1.5', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$this->autoescape = (bool) $state;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Grav\Common\Twig;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Page\Collection;
|
||||
use Grav\Common\Page\Media;
|
||||
use Grav\Common\Security;
|
||||
use Grav\Common\Twig\TokenParser\TwigTokenParserScript;
|
||||
use Grav\Common\Twig\TokenParser\TwigTokenParserStyle;
|
||||
use Grav\Common\Twig\TokenParser\TwigTokenParserSwitch;
|
||||
@@ -105,9 +106,9 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
|
||||
|
||||
// Casting values
|
||||
new \Twig_SimpleFilter('string', [$this, 'stringFilter']),
|
||||
new \Twig_SimpleFilter('int', [$this, 'intFilter'], ['is_safe' => true]),
|
||||
new \Twig_SimpleFilter('int', [$this, 'intFilter'], ['is_safe' => ['all']]),
|
||||
new \Twig_SimpleFilter('bool', [$this, 'boolFilter']),
|
||||
new \Twig_SimpleFilter('float', [$this, 'floatFilter'], ['is_safe' => true]),
|
||||
new \Twig_SimpleFilter('float', [$this, 'floatFilter'], ['is_safe' => ['all']]),
|
||||
new \Twig_SimpleFilter('array', [$this, 'arrayFilter']),
|
||||
];
|
||||
}
|
||||
@@ -155,7 +156,8 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
|
||||
new \Twig_SimpleFunction('read_file', [$this, 'readFileFunc']),
|
||||
new \Twig_SimpleFunction('nicenumber', [$this, 'niceNumberFunc']),
|
||||
new \Twig_SimpleFunction('nicefilesize', [$this, 'niceFilesizeFunc']),
|
||||
new \Twig_SimpleFunction('nicetime', [$this, 'nicetimeFilter']),
|
||||
new \Twig_SimpleFunction('nicetime', [$this, 'nicetimeFunc']),
|
||||
new \Twig_SimpleFunction('xss', [$this, 'xssFunc']),
|
||||
|
||||
// Translations
|
||||
new \Twig_simpleFunction('t', [$this, 'translate']),
|
||||
@@ -530,6 +532,27 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
|
||||
return "$difference $periods[$j] {$tense}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow quick check of a string for XSS Vulnerabilities
|
||||
*
|
||||
* @param $string
|
||||
* @return bool|string|array
|
||||
*/
|
||||
public function xssFunc($data)
|
||||
{
|
||||
if (is_array($data)) {
|
||||
$results = Security::detectXssFromArray($data);
|
||||
} else {
|
||||
return Security::detectXss($data);
|
||||
}
|
||||
|
||||
$results_parts = array_map(function($value, $key) {
|
||||
return $key.': \''.$value . '\'';
|
||||
}, array_values($results), array_keys($results));
|
||||
|
||||
return implode(', ', $results_parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $string
|
||||
*
|
||||
|
||||
@@ -15,6 +15,7 @@ use Grav\Common\Page\Pages;
|
||||
use Grav\Framework\Route\RouteFactory;
|
||||
use Grav\Framework\Uri\UriFactory;
|
||||
use Grav\Framework\Uri\UriPartsFilter;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
|
||||
class Uri
|
||||
{
|
||||
@@ -1139,6 +1140,8 @@ class Uri
|
||||
$this->scheme = $env['HTTP_X_FORWARDED_PROTO'];
|
||||
} elseif (isset($env['X-FORWARDED-PROTO'])) {
|
||||
$this->scheme = $env['X-FORWARDED-PROTO'];
|
||||
} elseif (isset($env['HTTP_CLOUDFRONT_FORWARDED_PROTO'])) {
|
||||
$this->scheme = $env['HTTP_CLOUDFRONT_FORWARDED_PROTO'];
|
||||
} elseif (isset($env['REQUEST_SCHEME'])) {
|
||||
$this->scheme = $env['REQUEST_SCHEME'];
|
||||
} else {
|
||||
@@ -1167,6 +1170,10 @@ class Uri
|
||||
$this->port = (int)$env['HTTP_X_FORWARDED_PORT'];
|
||||
} elseif (isset($env['X-FORWARDED-PORT'])) {
|
||||
$this->port = (int)$env['X-FORWARDED-PORT'];
|
||||
} elseif (isset($env['HTTP_CLOUDFRONT_FORWARDED_PROTO'])) {
|
||||
// Since AWS Cloudfront does not provide a forwarded port header,
|
||||
// we have to build the port using the scheme.
|
||||
$this->port = $this->port();
|
||||
} elseif (isset($env['SERVER_PORT'])) {
|
||||
$this->port = (int)$env['SERVER_PORT'];
|
||||
} else {
|
||||
@@ -1284,6 +1291,9 @@ class Uri
|
||||
} elseif (!empty($_POST)) {
|
||||
$this->post = (array)$_POST;
|
||||
}
|
||||
|
||||
$event = new Event(['post' => &$this->post]);
|
||||
Grav::instance()->fireEvent('onHttpPostFilter', $event);
|
||||
}
|
||||
|
||||
if ($this->post && null !== $element) {
|
||||
|
||||
@@ -266,6 +266,8 @@ class User extends Data
|
||||
*/
|
||||
public function authorise($action)
|
||||
{
|
||||
user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.5, use authorize() method instead', E_USER_DEPRECATED);
|
||||
|
||||
return $this->authorize($action);
|
||||
}
|
||||
|
||||
@@ -284,4 +286,29 @@ class User extends Data
|
||||
|
||||
return 'https://www.gravatar.com/avatar/' . md5($this->email);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize user.
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
return [
|
||||
'items',
|
||||
'storage'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Unserialize user.
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
$this->gettersVariable = 'items';
|
||||
$this->nestedSeparator = '.';
|
||||
|
||||
if (null === $this->blueprints) {
|
||||
$blueprints = new Blueprints;
|
||||
$this->blueprints = $blueprints->get('user/account');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,6 +478,51 @@ abstract class Utils
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mimetype based on filename
|
||||
*
|
||||
* @param string $filename Filename or path to file
|
||||
* @param string $default default value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getMimeByFilename($filename, $default = 'application/octet-stream')
|
||||
{
|
||||
return static::getMimeByExtension(pathinfo($filename, PATHINFO_EXTENSION), $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mimetype based on existing local file
|
||||
*
|
||||
* @param string $filename Path to the file
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
public static function getMimeByLocalFile($filename, $default = 'application/octet-stream')
|
||||
{
|
||||
$type = false;
|
||||
|
||||
// For local files we can detect type by the file content.
|
||||
if (!stream_is_local($filename) || !file_exists($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prefer using finfo if it exists.
|
||||
if (\extension_loaded('fileinfo')) {
|
||||
$finfo = finfo_open(FILEINFO_SYMLINK | FILEINFO_MIME_TYPE);
|
||||
$type = finfo_file($finfo, $filename);
|
||||
finfo_close($finfo);
|
||||
} else {
|
||||
// Fall back to use getimagesize() if it is available (not recommended, but better than nothing)
|
||||
$info = @getimagesize($filename);
|
||||
if ($info) {
|
||||
$type = $info['mime'];
|
||||
}
|
||||
}
|
||||
|
||||
return $type ?: static::getMimeByFilename($filename, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mimetype based on filename extension
|
||||
*
|
||||
@@ -520,6 +565,33 @@ abstract class Utils
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if filename is considered safe.
|
||||
*
|
||||
* @param string $filename
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkFilename($filename)
|
||||
{
|
||||
$dangerous_extensions = Grav::instance()['config']->get('security.uploads_dangerous_extensions', []);
|
||||
array_walk($dangerous_extensions, function(&$val) {
|
||||
$val = '.' . $val;
|
||||
});
|
||||
|
||||
$extension = '.' . pathinfo($filename, PATHINFO_EXTENSION);
|
||||
|
||||
return !(
|
||||
// Empty filenames are not allowed.
|
||||
!$filename
|
||||
// Filename should not contain horizontal/vertical tabs, newlines, nils or back/forward slashes.
|
||||
|| strtr($filename, "\t\v\n\r\0\\/", '_______') !== $filename
|
||||
// Filename should not start or end with dot or space.
|
||||
|| trim($filename, '. ') !== $filename
|
||||
// Filename should not contain .php in it.
|
||||
|| static::contains($extension, $dangerous_extensions)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize path by processing relative `.` and `..` syntax and merging path
|
||||
*
|
||||
@@ -696,6 +768,8 @@ abstract class Utils
|
||||
*/
|
||||
public static function resolve(array $array, $path, $default = null)
|
||||
{
|
||||
user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.5, use getDotNotation() method instead', E_USER_DEPRECATED);
|
||||
|
||||
return static::getDotNotation($array, $path, $default);
|
||||
}
|
||||
|
||||
|
||||
@@ -77,11 +77,11 @@ class InstallCommand extends ConsoleCommand
|
||||
} else {
|
||||
$this->output->writeln('<red>ERROR</red> Missing .dependencies file in <cyan>user/</cyan> folder');
|
||||
if ($this->input->getArgument('destination')) {
|
||||
$this->output->writeln('<yellow>HINT</yellow> <info>Are you trying to install a plugin or a theme? Make sure you use <cyan>bin/gpm install <something></cyan>, not <cyan>bin/grav install</cyan>. This command is only used to install Grav skeletons.');
|
||||
$this->output->writeln('<yellow>HINT</yellow> <info>Are you trying to install a plugin or a theme? Make sure you use <cyan>bin/gpm install <something></cyan>, not <cyan>bin/grav install</cyan>. This command is only used to install Grav skeletons.');
|
||||
} else {
|
||||
$this->output->writeln('<yellow>HINT</yellow> <info>Are you trying to install Grav? Grav is already installed. You need to run this command only if you download a skeleton from GitHub directly.');
|
||||
$this->output->writeln('<yellow>HINT</yellow> <info>Are you trying to install Grav? Grav is already installed. You need to run this command only if you download a skeleton from GitHub directly.');
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -169,19 +169,18 @@ class InstallCommand extends ConsoleCommand
|
||||
}
|
||||
|
||||
if (!$from) {
|
||||
$this->output->writeln('<red>source: ' . $from . ' does not exists, skipping...</red>');
|
||||
$this->output->writeln('');
|
||||
}
|
||||
|
||||
if (!file_exists($to)) {
|
||||
symlink($from, $to);
|
||||
$this->output->writeln('<green>SUCCESS</green> symlinked <magenta>' . $data['src'] . '</magenta> -> <cyan>' . $data['path'] . '</cyan>');
|
||||
$this->output->writeln('<red>source for ' . $data['src'] . ' does not exists, skipping...</red>');
|
||||
$this->output->writeln('');
|
||||
} else {
|
||||
$this->output->writeln('<red>destination: ' . $to . ' already exists, skipping...</red>');
|
||||
$this->output->writeln('');
|
||||
if (!file_exists($to)) {
|
||||
symlink($from, $to);
|
||||
$this->output->writeln('<green>SUCCESS</green> symlinked <magenta>' . $data['src'] . '</magenta> -> <cyan>' . $data['path'] . '</cyan>');
|
||||
$this->output->writeln('');
|
||||
} else {
|
||||
$this->output->writeln('<red>destination: ' . $to . ' already exists, skipping...</red>');
|
||||
$this->output->writeln('');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
113
system/src/Grav/Console/Cli/SecurityCommand.php
Normal file
113
system/src/Grav/Console/Cli/SecurityCommand.php
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Grav.Console
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Console\Cli;
|
||||
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Security;
|
||||
use Grav\Console\ConsoleCommand;
|
||||
use Symfony\Component\Console\Helper\ProgressBar;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
class SecurityCommand extends ConsoleCommand
|
||||
{
|
||||
/** @var ProgressBar $progress */
|
||||
protected $progress;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName("security")
|
||||
->setDescription("Capable of running various Security checks")
|
||||
->setHelp('The <info>security</info> runs various security checks on your Grav site');
|
||||
|
||||
$this->source = getcwd();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|null|void
|
||||
*/
|
||||
protected function serve()
|
||||
{
|
||||
|
||||
|
||||
/** @var Grav $grav */
|
||||
$grav = Grav::instance();
|
||||
|
||||
$grav['uri']->init();
|
||||
$grav['config']->init();
|
||||
$grav['debugger']->enabled(false);
|
||||
$grav['streams'];
|
||||
$grav['plugins']->init();
|
||||
$grav['themes']->init();
|
||||
|
||||
|
||||
$grav['twig']->init();
|
||||
$grav['pages']->init();
|
||||
|
||||
$this->progress = new ProgressBar($this->output, (count($grav['pages']->routes()) - 1));
|
||||
$this->progress->setFormat('Scanning <cyan>%current%</cyan> pages [<green>%bar%</green>] <white>%percent:3s%%</white> %elapsed:6s%');
|
||||
$this->progress->setBarWidth(100);
|
||||
|
||||
$io = new SymfonyStyle($this->input, $this->output);
|
||||
$io->title('Grav Security Check');
|
||||
|
||||
$output = Security::detectXssFromPages($grav['pages'], [$this, 'outputProgress']);
|
||||
|
||||
$io->newline(2);
|
||||
|
||||
if (!empty($output)) {
|
||||
|
||||
$counter = 1;
|
||||
foreach ($output as $route => $results) {
|
||||
|
||||
$results_parts = array_map(function($value, $key) {
|
||||
return $key.': \''.$value . '\'';
|
||||
}, array_values($results), array_keys($results));
|
||||
|
||||
$io->writeln($counter++ .' - <cyan>' . $route . '</cyan> → <red>' . implode(', ', $results_parts) . '</red>');
|
||||
}
|
||||
|
||||
$io->error('Security Scan complete: ' . count($output) . ' potential XSS issues found...');
|
||||
|
||||
} else {
|
||||
$io->success('Security Scan complete: No issues found...');
|
||||
}
|
||||
|
||||
$io->newline(1);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $args
|
||||
*/
|
||||
public function outputProgress($args)
|
||||
{
|
||||
switch ($args['type']) {
|
||||
case 'count':
|
||||
$steps = $args['steps'];
|
||||
$freq = intval($steps > 100 ? round($steps / 100) : $steps);
|
||||
$this->progress->setMaxSteps($steps);
|
||||
$this->progress->setRedrawFrequency($freq);
|
||||
break;
|
||||
case 'progress':
|
||||
if (isset($args['complete']) && $args['complete']) {
|
||||
$this->progress->finish();
|
||||
} else {
|
||||
$this->progress->advance();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ class IniFormatter implements FormatterInterface
|
||||
*/
|
||||
public function getFileExtension()
|
||||
{
|
||||
user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.5, use getDefaultFileExtension() method instead', E_USER_DEPRECATED);
|
||||
|
||||
return $this->getDefaultFileExtension();
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ class JsonFormatter implements FormatterInterface
|
||||
*/
|
||||
public function getFileExtension()
|
||||
{
|
||||
user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.5, use getDefaultFileExtension() method instead', E_USER_DEPRECATED);
|
||||
|
||||
return $this->getDefaultFileExtension();
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ class MarkdownFormatter implements FormatterInterface
|
||||
*/
|
||||
public function getFileExtension()
|
||||
{
|
||||
user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.5, use getDefaultFileExtension() method instead', E_USER_DEPRECATED);
|
||||
|
||||
return $this->getDefaultFileExtension();
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@ class SerializeFormatter implements FormatterInterface
|
||||
*/
|
||||
public function getFileExtension()
|
||||
{
|
||||
user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.5, use getDefaultFileExtension() method instead', E_USER_DEPRECATED);
|
||||
|
||||
return $this->getDefaultFileExtension();
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@ class YamlFormatter implements FormatterInterface
|
||||
*/
|
||||
public function getFileExtension()
|
||||
{
|
||||
user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.5, use getDefaultFileExtension() method instead', E_USER_DEPRECATED);
|
||||
|
||||
return $this->getDefaultFileExtension();
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@ namespace Grav\Framework\Session;
|
||||
*/
|
||||
class Session implements SessionInterface
|
||||
{
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
@@ -182,7 +184,10 @@ class Session implements SessionInterface
|
||||
unset($_COOKIE[session_name()]);
|
||||
}
|
||||
|
||||
$options = $readonly ? ['read_and_close' => '1'] : [];
|
||||
$options = $this->options;
|
||||
if ($readonly) {
|
||||
$options['read_and_close'] = '1';
|
||||
}
|
||||
|
||||
$success = @session_start($options);
|
||||
if (!$success) {
|
||||
@@ -224,8 +229,10 @@ class Session implements SessionInterface
|
||||
$params['httponly']
|
||||
);
|
||||
|
||||
session_unset();
|
||||
session_destroy();
|
||||
if ($this->isSessionStarted()) {
|
||||
session_unset();
|
||||
session_destroy();
|
||||
}
|
||||
|
||||
$this->started = false;
|
||||
|
||||
@@ -335,6 +342,7 @@ class Session implements SessionInterface
|
||||
$value = (string)$value;
|
||||
}
|
||||
|
||||
$this->options[$key] = $value;
|
||||
ini_set($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ To edit this page, simply navigate to the folder you installed **Grav** into, an
|
||||
|
||||
Creating a new page is a simple affair in **Grav**. Simply follow these simple steps:
|
||||
|
||||
1. Navigate to your pages folder: `user/pages/` and create a new folder. In this example, we will use [explicit default ordering](http://learn.getgrav.org/content/content-pages) and call the folder `03.mypage`.
|
||||
1. Navigate to your pages folder: `user/pages/` and create a new folder. In this example, we will use [explicit default ordering](http://learn.getgrav.org/content/content-pages) and call the folder `02.mypage`.
|
||||
2. Launch your text editor and paste in the following sample code:
|
||||
|
||||
---
|
||||
@@ -36,7 +36,7 @@ Creating a new page is a simple affair in **Grav**. Simply follow these simple
|
||||
|
||||
This is the body of **my new page** and I can easily use _Markdown_ syntax here.
|
||||
|
||||
3. Save this file in the `user/pages/03.mypage/` folder as `default.md`. This will tell **Grav** to render the page using the **default** template.
|
||||
3. Save this file in the `user/pages/02.mypage/` folder as `default.md`. This will tell **Grav** to render the page using the **default** template.
|
||||
4. That is it! Reload your browser to see your new page in the menu.
|
||||
|
||||
! NOTE: The page will automatically show up in the Menu after the "Home" menu item. If you wish to change the name that shows up in the Menu, simple add: `menu: My Page` between the dashes in the page content. This is called the YAML front matter, and it is where you configure page-specific options.
|
||||
|
||||
Reference in New Issue
Block a user