Compare commits

...

153 Commits
1.0.3 ... 1.0.7

Author SHA1 Message Date
Andy Miller
8ca14c7c65 Merge branch 'release/1.0.7' 2016-01-07 14:21:56 -07:00
Andy Miller
eff72b73ab version update 2016-01-07 14:21:48 -07:00
Andy Miller
eb29d68958 Safety check for array of nonces 2016-01-07 14:10:58 -07:00
Andy Miller
e0632dee09 Merge branch 'release/1.0.7' into develop 2016-01-07 13:27:02 -07:00
Andy Miller
4549574908 Merge branch 'release/1.0.7' 2016-01-07 13:27:01 -07:00
Andy Miller
0866a62a1f version update 2016-01-07 13:26:53 -07:00
Andy Miller
1a7fd382a9 Merge branch 'feature/https_gpm_urls' into develop 2016-01-07 13:23:43 -07:00
Flavio Copes
cdc96ca574 Improve comment messages for temporary nonce methods 2016-01-07 11:59:40 +01:00
Andy Miller
d121aa3415 Use https for GPM rather than http 2016-01-06 21:54:43 -07:00
Djamil Legato
6aaeb9e1f1 Fixed typo 2016-01-06 16:24:11 -08:00
Andy Miller
fa39629104 changelog updates 2016-01-06 17:10:00 -07:00
Andy Miller
9e13593c11 Merge pull request #592 from getgrav/feature/fix-nonces-ips
Fix nonces for proxied IPs
2016-01-06 15:47:21 -07:00
Flavio Copes
0b3970d7c1 Restore old generateNonceString in generateNonceStringOldStyle 2016-01-06 23:43:18 +01:00
Flavio Copes
95c09f2ce5 Add HTTP_CLIENT_IP too 2016-01-06 23:34:28 +01:00
Flavio Copes
c78619aad3 Temp generation of older token for this release only 2016-01-06 23:19:00 +01:00
Flavio Copes
566da30513 Fix getting the user's IP address when proxied 2016-01-06 23:15:06 +01:00
Djamil Legato
f8c8ac4371 Response Class: Following redirects when open_basedir is set 2016-01-06 13:31:50 -08:00
Andy Miller
3c4dd26c20 Fix for media with + in the name 2016-01-05 15:45:58 -07:00
Andy Miller
f5fc509f14 Added cache driver setting to debug out 2016-01-05 14:59:24 -07:00
Andy Miller
2d00203a1f updated changelog 2016-01-05 12:08:44 -07:00
Flavio Copes
ac23ab21b8 Merge pull request #587 from jeromegamez/readme-changelog
Update README and CHANGELOG
2016-01-05 11:57:43 +01:00
Jérôme Gamez
0261df0d48 Update README and CHANGELOG 2016-01-05 11:17:22 +01:00
Andy Miller
2709938f9f Merge pull request #586 from jeromegamez/feature/composer-branch-alias
composer.json: Add branch alias - fine with this :) 👍
2016-01-04 17:37:08 -07:00
Jérôme Gamez
53e1c790d8 Add branch alias 2016-01-05 01:24:17 +01:00
Andy Miller
f2f9fc4ed6 Merge pull request #585 from jeromegamez/feature/composer-project
Allow grav to be installed as a composer project
2016-01-04 16:51:08 -07:00
Jérôme Gamez
3cbf9c7101 Allow grav to be installed as a composer project 2016-01-04 23:55:16 +01:00
Flavio Copes
c655d9e8fc Revert "Merge pull request #571 from getgrav/feature/gpm-avoid-reinstalling-already-installed-packages"
This reverts commit 418f0972a9, reversing
changes made to 9a777efd52.
2016-01-04 20:50:15 +01:00
Andy Miller
2ef7f7cf36 Merge branch 'feature/hide_home_in_urls' into develop 2016-01-04 11:14:57 -07:00
Andy Miller
418f0972a9 Merge pull request #571 from getgrav/feature/gpm-avoid-reinstalling-already-installed-packages
Command line GPM: Avoid prompting to reinstall already installed packages
2016-01-04 10:36:10 -07:00
Andy Miller
9a777efd52 Merge pull request #569 from getgrav/feature/improve-gpm-unreachable-error-message
Improve error when trying to install a plugin/theme from the command line and GPM is unreachable
2016-01-04 10:30:22 -07:00
Andy Miller
aa8a329c7b Merge pull request #557 from getgrav/feature/use-rawurldecode
Allows '+' in the URLs, such as http://localhost/grav/blog/tag:c++
2016-01-04 10:19:18 -07:00
Andy Miller
e4930a144f Merge pull request #554 from getgrav/feature/session-improvements
Add secure and httponly parameters to sessions
2016-01-04 09:54:49 -07:00
Matias Griese
194014007f Merge pull request #583 from getgrav/feature/fix-checksum
Call finalizeObject on Config from loadCompiledFile() when cache is already built
2016-01-04 15:22:24 +02:00
Matias Griese
dc8f2c1466 Fixed page blueprints and theme inheritance issue (#534) 2016-01-04 15:18:50 +02:00
Flavio Copes
6ee48c74f7 Call finalizeObject on Config from loadCompiledFile() when cache is already built
finalizeObject, which assigns the checksum to the Config object, was
never called after the cache was built
2016-01-03 19:10:17 +01:00
Flavio Copes
136a9e8218 Also check for GPM permissions. Fixes #579 2016-01-02 16:25:31 +01:00
Andy Miller
34045ea62b whitespace removal 2016-01-01 17:27:28 -07:00
Andy Miller
267edbee7d optimization 2015-12-31 16:25:27 -07:00
Andy Miller
da882ebcd2 set twig_first: false by default due to modular pages 2015-12-31 15:35:54 -07:00
Andy Miller
ed0ba1ed98 Merge pull request #577 from mholt/patch-1
Update Caddyfile
2015-12-31 12:42:11 -07:00
Matt Holt
ef9dd3aa28 Update Caddyfile
fastcgi was using php preset defaults, anyway
2015-12-31 12:40:56 -07:00
Andy Miller
73b9abd38b Added a global setting for twig_first processing, and set it to true (was false) 2015-12-31 12:25:22 -07:00
Andy Miller
6e399fe0ed maintain md5 keys during sorting process #566 2015-12-31 12:06:46 -07:00
Andy Miller
5f9ed17091 Added support for APCu and PHP 7.0 2015-12-31 11:47:50 -07:00
Flavio Copes
1f4b3913b6 Typo in changelog 2015-12-31 12:32:10 +01:00
Andy Miller
dc9b9509d7 Moved onPageContentProccessed into content building section so it's fired more reliably 2015-12-30 16:28:02 -07:00
Andy Miller
b4f34c8643 Added plugins config to debugger 2015-12-30 16:26:59 -07:00
Andy Miller
52544a8b25 Fix for not fully reprocessing content with cache_enable: false 2015-12-30 15:44:42 -07:00
Flavio Copes
017500a6b5 Add a Page::topParent() method to retrieve the topmost parent of a page
Adding to this branch as it's needed for the Admin change that handles
this branch change
2015-12-29 19:10:30 +01:00
Andy Miller
425ae30e62 fix for attributes on external urls 2015-12-29 09:56:13 -07:00
Andy Miller
1aa09d8987 Merge branch 'develop' of https://github.com/getgrav/grav into develop 2015-12-28 15:49:25 -07:00
Andy Miller
a45196dc97 regular date: header should not impact published visibility 2015-12-28 15:49:17 -07:00
Djamil Legato
8d7ab6fdd3 Ignore security yaml 2015-12-28 12:55:34 -08:00
Andy Miller
87870bcde7 Fix for new webserver-config folder 2015-12-28 13:15:51 -07:00
Flavio Copes
9b85c1b0f7 Remove all hardcoded older PHP required version, use GRAV_PHP_MIN constant instead
Thanks @MATsxm for the hint in https://github.com/getgrav/grav/pull/570
2015-12-28 18:46:14 +01:00
Flavio Copes
104012228c Command line GPM: Avoid prompting to reinstall already installed packages 2015-12-28 18:22:16 +01:00
Flavio Copes
e3deb40f69 Improve error when trying to install a plugin/theme from the command line and GPM is unreachable
Previously it listed four times `PHP Warning:  Invalid argument
supplied for foreach()...`, now it fails with an error message
2015-12-28 08:53:23 +01:00
Flavio Copes
492b290845 Fix #565 handle case where we only have inline data for css or js 2015-12-26 08:54:33 +01:00
Andy Miller
3eb2a5664a logic to strip home from Page routes and urls (optional) 2015-12-24 17:42:02 -07:00
Djamil Legato
15fd233e56 Added new --installed-only | -I option for bin/gpm index that filters only the installed packages 2015-12-24 14:44:57 -08:00
Djamil Legato
912f697cff Give ZipBackup a larger timeout when possible (10mins) 2015-12-24 14:30:20 -08:00
Flavio Copes
d827228dc2 Add new languages to Grav 2015-12-24 19:11:24 +01:00
Flavio Copes
84073a53cb Add MONTHS_OF_THE_YEAR and DAYS_OF_THE_WEEK to the Grav language file,
Took translations from
https://github.com/getgrav/grav-theme-twentyfifteen/blob/develop/languag
es.yaml
2015-12-24 19:05:13 +01:00
Flavio Copes
f562573640 Add a contributing readme 2015-12-23 20:13:37 +01:00
Flavio Copes
66aa66954c Add empty thumb.png image as default 2015-12-23 16:30:12 +01:00
Flavio Copes
99275dfe59 Optimize images, save 38% in file size 2015-12-23 16:29:58 +01:00
Flavio Copes
efded08d6e Uses Uri::host() to calculate the host. If localhost, set it to ''
Now also works with Chrome on localhost SSL sites. The problem was,
Chrome on Localhost wants the domain to be `""` or `false` even if the
site is accessed with another domain name.
Worked fine in other browsers.
2015-12-23 09:18:27 +01:00
Andy Miller
d726f15aa3 PHP version update 2015-12-22 21:54:07 -07:00
Andy Miller
7c6cd30aea Merge branch 'release/1.0.6' into develop 2015-12-22 17:15:45 -07:00
Andy Miller
f0145aa659 Merge branch 'release/1.0.6' 2015-12-22 17:15:44 -07:00
Andy Miller
879b5ef272 version update 2015-12-22 17:15:34 -07:00
Flavio Copes
91a57e1a16 Allows '+' in the URLs, such as http://localhost/grav/blog/tag:c++ 2015-12-22 19:06:04 +01:00
Flavio Copes
3698afb8a6 Add secure and httponly parameters to sessions 2015-12-22 17:03:39 +01:00
Matias Griese
8e1b2bc6e4 FastCGI: Use Apache's mod_deflate if Grav's builtin gzip compression was turned off (#548) 2015-12-22 11:54:20 +02:00
Andy Miller
37dd107281 Revert "Fix orientation for images added via twig"
This reverts commit 484a34cd92.
2015-12-21 22:01:38 -07:00
Andy Miller
2d3b41c62d Revert "Fix for images orientation in page content"
This reverts commit 4581077dcd.
2015-12-21 22:01:32 -07:00
Andy Miller
c9b8fc0e1b Revert "Cleanup"
This reverts commit b2c7e22634.
2015-12-21 22:01:18 -07:00
Andy Miller
7eb57b674a Merge branch 'develop' of https://github.com/getgrav/grav into develop 2015-12-21 21:58:47 -07:00
Andy Miller
25b33d0204 Revert "Proposed fix for #541"
This reverts commit 6c6871f607.
2015-12-21 21:58:31 -07:00
Flavio Copes
d47faed870 Cleanup 2015-12-21 21:58:31 -07:00
Flavio Copes
9a8efdf9cd Fix for images orientation in page content 2015-12-21 21:58:31 -07:00
Flavio Copes
593fd20a15 Fix orientation for images added via twig 2015-12-21 21:58:31 -07:00
Flavio Copes
ef75582e20 Proposed fix for #541
After reading http://stackoverflow.com/a/6998242 rawurldecode (and
rawurlencode) is better over urldecode/urlencode: "rawurlencode is the
way to go most of the time. It deals with the modern scheme for URI
components, where as urlencode does things the old school way, where +
meant "space."
2015-12-21 21:58:31 -07:00
Andy Miller
7440074491 Revert "Proposed fix for #541"
This reverts commit 6c6871f607.
2015-12-21 21:46:36 -07:00
Andy Miller
9688ed0f51 Merge pull request #543 from getgrav/features/use-rawurldecode-encode
Use rawurldecode and rawurlencode instead of urldecode/urlencode
2015-12-21 21:16:59 -07:00
Andy Miller
45d415e547 Merge branch 'feature/exif-auto-fix-orientation' into develop 2015-12-21 21:13:09 -07:00
Flavio Copes
b2c7e22634 Cleanup 2015-12-21 19:18:51 +01:00
Flavio Copes
4581077dcd Fix for images orientation in page content 2015-12-21 19:10:19 +01:00
Flavio Copes
729f83b3d4 Fix regression in image parameters handling introduced in 23a9a73600
Parameters without a value (e.g. `sepia`, `grayscale`, `emboss` and
others) were not applied any more)
2015-12-21 18:02:25 +01:00
Flavio Copes
bf361db5fc File field validation, handle case multiple not specified 2015-12-21 16:26:05 +01:00
Flavio Copes
328e9b20de Also add config save to themes 2015-12-21 16:16:26 +01:00
Flavio Copes
484a34cd92 Fix orientation for images added via twig 2015-12-21 13:55:29 +01:00
Andy Miller
5ab4d916b0 tweaked whoops sidebar 2015-12-20 12:32:23 -07:00
Andy Miller
f0974e0d24 minor whoops styling 2015-12-20 12:30:15 -07:00
Andy Miller
06a5aa6d01 Manually rolled back APCu support for PHP7 until it is available in the released version of Doctrine (currently only in master branch) 2015-12-20 11:58:53 -07:00
Andy Miller
a88829bd57 Merge branch 'feature/update-whoops' into develop 2015-12-20 11:51:44 -07:00
Andy Miller
c023c74ae5 Merge branch 'feature/update-whoops' of https://github.com/getgrav/grav into feature/update-whoops 2015-12-20 11:51:14 -07:00
Andy Miller
a8ad14222d moved sample web server configs into a dedicated directory 2015-12-20 11:50:45 -07:00
Flavio Copes
6c6871f607 Proposed fix for #541
After reading http://stackoverflow.com/a/6998242 rawurldecode (and
rawurlencode) is better over urldecode/urlencode: "rawurlencode is the
way to go most of the time. It deals with the modern scheme for URI
components, where as urlencode does things the old school way, where +
meant "space."
2015-12-20 14:18:56 +01:00
Flavio Copes
5764e5e686 Merge branch 'develop' into feature/update-whoops 2015-12-20 11:52:52 +01:00
Flavio Copes
b89044a709 Fix language string 2015-12-20 11:51:48 +01:00
Flavio Copes
5fc4755d3b Merge pull request #537 from fbardel/patch-1
Update fr.yaml
2015-12-19 18:39:33 +01:00
François
2f2adaaee8 Update fr.yaml 2015-12-19 18:17:07 +01:00
Flavio Copes
e2ae24faa9 Merge branch 'develop' into feature/update-whoops 2015-12-19 15:30:08 +01:00
Flavio Copes
55bc84c118 Fix #535 case insensitive https check 2015-12-19 14:20:45 +01:00
Flavio Copes
a47d5d00b3 Merge branch 'develop' into feature/update-whoops 2015-12-19 11:53:52 +01:00
Flavio Copes
05c2b98929 Fix #523 locale in url with base_url_* variables, even if include_default_lang is set to false 2015-12-19 10:48:52 +01:00
Flavio Copes
c5d3098b25 Only call extra method on blueprints if blueprints exist
Reverts partial change made in

https://github.com/getgrav/grav/commit/ac3396e6c46f9bcd8d5cbb45370b5daad
c84aadc
2015-12-19 10:28:06 +01:00
Flavio Copes
6805f32a13 Merge pull request #533 from mikewink/patch-1
Fixed hardcoded string "Security"
2015-12-19 09:33:56 +01:00
Andy Miller
b8aa250a22 Merge branch 'develop' into feature/update-whoops 2015-12-18 23:08:31 -07:00
Andy Miller
bf05a36dfe Updated some libs 2015-12-18 23:08:14 -07:00
Andy Miller
8f9cdad916 Updated spelling in Parsedown to match imminent update 2015-12-18 20:50:27 -07:00
Djamil Legato
d2ed424a7c Fixed Travis parsing error [ci skip] 2015-12-18 16:05:35 -08:00
Andy Miller
08cbd9553f Merge branch 'release/1.0.5' 2015-12-18 16:50:33 -07:00
Andy Miller
369d2cb390 Merge branch 'release/1.0.5' into develop 2015-12-18 16:50:33 -07:00
Andy Miller
dcaa9a35c3 Missed changeling entry 2015-12-18 16:50:19 -07:00
Andy Miller
4a80691e07 version update 2015-12-18 16:49:03 -07:00
Mike Wink
215b2cdfa8 Fixed hardcoded string "Security"
Added the PLUGIN_ADMIN.SECURITY constant instead. Will add this to the admin language files too.
2015-12-19 00:12:01 +01:00
Andy Miller
425831a7ae Fix for empty file when writing cache 2015-12-18 15:09:21 -07:00
Djamil Legato
984e0455b1 'informations' is not a thing 😞 2015-12-18 13:44:59 -08:00
Djamil Legato
00ecfb30f3 Ensuring gpm selfupgrades doesn't continue if PHP min version requirement isn't met. Gracefully abort with error and details. 2015-12-18 13:38:28 -08:00
Djamil Legato
c18f20e483 Added GRAV_PHP_MIN 2015-12-18 13:37:19 -08:00
Djamil Legato
71c5ff8c51 Added new Upgrader::meetsRequirements method
Ensures the PHP version meets the Grav's mininum required one.
2015-12-18 13:35:31 -08:00
Djamil Legato
1996dd7de8 Allowing Installer to set errors as string 2015-12-18 13:33:57 -08:00
Andy Miller
e87daa2361 Added support to get plugin languages from individual language files in languages folder of plugin 2015-12-18 12:29:45 -07:00
Flavio Copes
987feb1385 Make saveConfig static so it's more easily accessible 2015-12-18 15:42:33 +01:00
Flavio Copes
8d048c689f Persists to disk the plugin parameters currently stored in the Grav Config object 2015-12-18 14:44:03 +01:00
Flavio Copes
139ef04e0a Handle non-array values in file validation 2015-12-18 10:38:10 +01:00
Flavio Copes
4c01e6c93e Merge pull request #530 from mufac/mufac-patch-1
Prevent error if no collections present
2015-12-18 10:04:11 +01:00
Andy Miller
27744ba747 Merge branch 'feature/markdown_extendability' into develop 2015-12-17 18:09:28 -07:00
Andy Miller
3d3c6f4eba missing doc blocks 2015-12-17 18:09:11 -07:00
Andy Miller
fb4abc5f5f Use Grav's version of Parsedown until PR is accepted (crossing fingers) 2015-12-17 17:52:20 -07:00
mufac
f29b141d69 Prevent error if no collections present
If there are no collections you can get a "Invalid argument supplied for foreach()" without an empty default.
2015-12-17 16:14:48 -06:00
Andy Miller
1cecd09423 requires changes in parsedown 2015-12-17 10:35:22 -07:00
Andy Miller
0142e76270 cleanup 2015-12-16 21:51:38 -07:00
Andy Miller
5f8c7f41ec Add ability to extend markdown 2015-12-16 19:50:10 -07:00
Flavio Copes
451baff26e filterFile if the file field allows multiple items returns an array, otherwise a string 2015-12-16 15:16:14 +01:00
Flavio Copes
78accfe98b Bump whoops version 2015-12-15 22:58:31 +01:00
Flavio Copes
0e8e27877e Fix https://github.com/getgrav/grav-plugin-admin/issues/335, when looping the fields param in a list field, first check it exists 2015-12-15 11:52:27 +01:00
Andy Miller
d8a993bc86 Properly convert comma to spaces for multiple attributes #518 2015-12-14 18:30:55 -07:00
Andy Miller
ec7dbbdc8b Added 7z format to standard file types #521 2015-12-14 18:13:14 -07:00
Flavio Copes
c45652de81 Make sure Grav can work with the 2.0.0-alpha1 Whoops update, and with the current 1.1 too 2015-12-14 14:21:39 +01:00
Djamil Legato
e152cfd10f Forcing travis VM to western most date and echo a Travis date to catch it on log 2015-12-12 17:47:19 -08:00
Andy Miller
747daa46f1 Merge branch 'release/1.0.4' 2015-12-12 13:03:34 -07:00
Andy Miller
17a0590ee4 Merge branch 'release/1.0.4' into develop 2015-12-12 13:03:34 -07:00
Andy Miller
653edb064b version update 2015-12-12 13:03:22 -07:00
Andy Miller
40f5d57737 Default value not in quotes. Needs to be a string for Admin compatibility - https://docs.saltstack.com/en/latest/topics/troubleshooting/yaml_idiosyncrasies.html#integers-are-parsed-as-integers 2015-12-12 08:43:41 -07:00
Flavio Copes
566c5cb38f Revert "Fix issue in images cache permissions"
This reverts commit 7e3058e3f0.
2015-12-12 10:18:32 +01:00
Flavio Copes
7e3058e3f0 Fix issue in images cache permissions
the leading '0' in the default 0755 was omitted as interpreted as an
integer, leading to errors in setting the images cache folder
permissions (not readable by Grav)
2015-12-12 10:13:21 +01:00
Djamil Legato
053d8a3fd5 Merge branch 'develop' of https://github.com/getgrav/grav into develop 2015-12-11 21:17:30 -08:00
Djamil Legato
0e810c15e2 Keep going if files are not found while creating a new project 2015-12-11 21:17:19 -08:00
Andy Miller
6b9154d1f3 Fix for cleaning build on linux 2015-12-11 22:08:59 -07:00
Andy Miller
2d7a3232cc Merge branch 'release/1.0.3' into develop 2015-12-11 21:52:41 -07:00
85 changed files with 1098 additions and 440 deletions

1
.gitignore vendored
View File

@@ -35,3 +35,4 @@ Thumbs.db
# phpstorm
.idea/*
user/config/security.yaml

View File

@@ -44,7 +44,7 @@ RewriteRule .* index.php [L]
## Begin - Security
# Block all direct access for these folders
RewriteRule ^(.git|cache|bin|logs|backup)/(.*) error [F]
RewriteRule ^(.git|cache|bin|logs|backup|webserver-configs)/(.*) error [F]
# Block access to specific file types for these system folders
RewriteRule ^(system|vendor)/(.*)\.(txt|xml|md|html|yaml|php|pl|py|cgi|twig|sh|bat)$ error [F]
# Block access to specific file types for these user folders
@@ -54,7 +54,7 @@ RewriteRule \.md$ error [F]
# Block all direct access to files and folders beginning with a dot
RewriteRule (^\.|/\.) - [F]
# Block access to specific files in the root folder
RewriteRule ^(LICENSE.txt|composer.lock|composer.json|nginx.conf|web.config|htaccess.txt|\.htaccess)$ error [F]
RewriteRule ^(LICENSE.txt|composer.lock|composer.json|\.htaccess)$ error [F]
## End - Security
</IfModule>

View File

@@ -40,8 +40,10 @@ env:
- TRAVIS_TAG=$(curl --fail --user ${GH_API_USER} -s https://api.github.com/repos/getgrav/grav/releases/latest | grep tag_name | head -n 1 | cut -d '"' -f 4)
before_install:
- export TZ=Pacific/Honolulu
- composer self-update
- go get github.com/aktau/github-release
- echo "Travis Date - `date`"
- git clone --quiet --depth=50 --branch=master https://${BB_TOKEN}bitbucket.org/rockettheme/grav-devtools.git $RT_DEVTOOLS &>/dev/null;
- if [ ! -z "$TRAVIS_TAG" ]; then
cd "${RT_DEVTOOLS}";

View File

@@ -1,3 +1,79 @@
# v1.0.7
## 01/07/2016
1. [](#new)
* Added `composer create-project` as an additional installation method #585
* New optional system config setting to strip home from page routs and urls #561
* Added Greek, Finnish, Norwegian, Polish, Portuguese, and Romanian languages
* Added new `Page->topParent()` method to return top most parent of a page
* Added plugins configuration tab to debugger
* Added support for APCu and PHP7.0 via new Doctrine Cache release
* Added global setting for `twig_first` processing (false by default)
* New configuration options for Session settings #553
1. [](#improved)
* Switched to SSL for GPM calls
* Use `URI->host()` for session domain
* Add support for `open_basedir` when installing packages via GPM
* Improved `Utils::generateNonceString()` method to handle reverse proxies
* Optimized core thumbnails saving 38% in file size
* Added new `bin/gpm index --installed-only` option
* Improved GPM errors to provider more helpful diagnostic of issues
* Removed old hardcoded PHP version references
* Moved `onPageContentProcessed()` event so it's fired more reliably
* Maintain md5 keys during sorting of Assets #566
* Update to Caddyfile for Caddy web server
1. [](#bugfix)
* Fixed an issue with cache/config checksum not being set on cache load
* Fix for page blueprint and theme inheritance issue #534
* Set `ZipBackup` timeout to 10 minutes if possible
* Fix case where we only have inline data for CSS or JS #565
* Fix `bin/grav sandbox` command to work with new `webserver-config` folder
* Fix for markdown attributes on external URLs
* Fixed issue where `data:` page header was acting as `publish_date:`
* Fix for special characters in URL parameters (e.g. /tag:c++) #541
* Safety check for an array of nonces to only use the first one
# v1.0.6
## 12/22/2015
1. [](#new)
* Set minimum requirements to [PHP 5.5.9](http://bit.ly/1Jt9OXO)
* Added `saveConfig` to Themes
1. [](#improved)
* Updated Whoops to new 2.0 version (PHP 7.0 compatible)
* Moved sample web server configs into dedicated directory
* FastCGI will use Apache's `mod_deflate` if gzip turned off
1. [](#bugfix)
* Fix broken media image operators
* Only call extra method of blueprints if blueprints exist
* Fix lang prefix in url twig variables #523
* Fix case insensitive HTTPS check #535
* Field field validation handles case `multiple` missing
# v1.0.5
## 12/18/2015
1. [](#new)
* Add ability to extend markdown with plugins
* Added support for plugins to have individual language files
* Added `7z` to media formats
* Use Grav's fork of Parsedown until PR is merged
* New function to persist plugin configuration to disk
* GPM `selfupgrade` will now check PHP version requirements
1. [](#improved)
* If the field allows multiple files, return array
* Handle non-array values in file validation
1. [](#bugfix)
* Fix when looping `fields` param in a `list` field
* Properly convert commas to spaces for media attributes
* Forcing Travis VM to HI timezone to address future files in zip file
# v1.0.4
## 12/12/2015
1. [](#bugfix)
* Needed to put default image folder permissions for YAML compatibility
# v1.0.3
## 12/11/2015
@@ -13,7 +89,7 @@
# v1.0.1
## 12/11/2015
1. [](#improved)
1. [](#improved)
* Reduced package sizes by removing extra vendor dev bits
1. [](#bugfix)
* Fix issue when you enable debugger from admin plugin
@@ -26,7 +102,7 @@
* Added setters to set state of CSS/JS pipelining
* Added `user/accounts` to `.gitignore`
* Added configurable permissions option for Image cache
1. [](#improved)
1. [](#improved)
* Hungarian translation updated
* Refactored Theme initialization for improved flexibility
* Wrapped security section of account blueprints in an 'super user' authorize check
@@ -60,7 +136,7 @@
* Automatically create unique security salt for each configuration
* Added Hungarian translation
* Added support for User groups
1. [](#improved)
1. [](#improved)
* Improved robots.txt to disallow crawling of non-user folders
* Nonces only generated once per action and process
* Added IP into Nonce string calculation

122
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,122 @@
# Contributing to Grav
:+1::tada: First, thanks for getting involved with Grav! :tada::+1:
Please take a moment to review this document in order to make the contribution
process easy and effective for everyone involved.
Following these guidelines helps to communicate that you respect the time of
the developers managing and developing this open source project. In return,
they should reciprocate that respect in addressing your issue or assessing
patches and features.
## Grav, Plugins, Themes and Skeletons
Grav is a large open source project—it's made up of over 100 repositories. When you initially consider contributing to Grav, you might be unsure about which of those 200 repositories implements the functionality you want to change or report a bug for.
[https://github.com/getgrav/grav](https://github.com/getgrav/grav) is the main Grav repository. The core of Grav is provided by this repo.
[https://github.com/getgrav/grav-plugin-admin](https://github.com/getgrav/grav-plugin-admin) is the Admin Plugin repository.
Every Plugin and Theme has its own repository. If you have a problem you think is specific to a Theme or Plugin, please report it in its corresponding repository. Please read the Plugin or Theme documentation to ensure the problem is not addressed there already.
Every Skeleton also has its own repository, so if an issue is not specific to a theme or plugin but rather to its usage in the skeleton, report it in the skeleton repository.
## Using the issue tracker
The issue tracker is the preferred channel for [bug reports](#bugs),
[features requests](#features) and [submitting pull
requests](#pull-requests), but please respect the following restrictions:
* Please **do not** use the issue tracker for support requests. Use
[the Forum](http://getgrav.org/forum) or [the Gitter chat](https://gitter.im/getgrav/grav).
<a name="bugs"></a>
## Bug reports
A bug is a _demonstrable problem_ that is caused by the code in the repository.
Good bug reports are extremely helpful - thank you!
Guidelines for bug reports:
1. **Check you satisfy the Grav requirements** &mdash; [http://learn.getgrav.org/basics/requirements](http://learn.getgrav.org/basics/requirements)
2. **Check this happens on a clean Grav install** &mdash; check if the issue happens on any Grav site, or just with a specific configuration of plugins / theme
3. **Use the GitHub issue search** &mdash; check if the issue has already been
reported.
4. **Check if the issue is already being solved in a PR** &mdash; check the open Pull Requests to see if one already solves the problem you're having
5. **Check if the issue has been fixed** &mdash; try to reproduce it using the
latest `develop` branch in the repository.
6. **Isolate the problem** &mdash; create a [reduced test
case](http://css-tricks.com/reduced-test-cases/) and provide a step-by-step instruction set on how to recreate the problem. Include code samples, page snippets or yaml configurations if needed.
A good bug report shouldn't leave others needing to chase you up for more
information. Please try to be as detailed as possible in your report.
What is your environment? Is it localhost, OSX, Linux, on a remote server? Same happening locally and or the server, or just locally or just on Linux?
What steps will reproduce the issue? What browser(s) and OS experience the problem?
What would you expect to be the outcome?
Did the problem start happening recently (e.g. after updating to a new version of Grav) or was this always a problem?
If the problem started happening recently, can you reproduce the problem in an older version of Grav? What's the most recent version in which the problem doesn't happen? You can download older versions of Grav from the releases page on Github.
Can you reliably reproduce the issue? If not, provide details about how often the problem happens and under which conditions it normally happens.
All these details will help people to fix any potential bugs.
Important: [include Code Samples in triple backticks](https://help.github.com/articles/github-flavored-markdown/#fenced-code-blocks) so that Github will provide a proper indentation. [Add the language name after the backticks](https://help.github.com/articles/github-flavored-markdown/#syntax-highlighting) to add syntax highlighting to the code snippets.
Example:
> Short and descriptive example bug report title
>
> A summary of the issue and the browser/OS environment in which it occurs. If
> suitable, include the steps required to reproduce the bug.
>
> 1. This is the first step
> 2. This is the second step
> 3. Further steps, etc.
>>
> Any other information you want to share that is relevant to the issue being
> reported. This might include the lines of code that you have identified as
> causing the bug, and potential solutions (and your opinions on their
> merits).
<a name="features"></a>
## Feature requests
Feature requests are welcome. But take a moment to find out whether your idea
fits with the scope and aims of the project. It's up to *you* to make a strong
case to convince the project's developers of the merits of this feature. Please
provide as much detail and context as possible.
<a name="pull-requests"></a>
## Pull requests
Good pull requests - patches, improvements, new features - are a fantastic
help. They should remain focused in scope and avoid containing unrelated
commits.
**Please ask first** in Gitter or in the Forum before embarking on any significant pull request (e.g.
implementing features, refactoring code..),
otherwise you risk spending a lot of time working on something that the
project's developers might not want to merge into the project.
Please adhere to the coding conventions used throughout the project (indentation,
accurate comments, etc.) and any other requirements.
See [Using Pull Request](https://help.github.com/articles/using-pull-requests/) and [Fork a Repo](https://help.github.com/articles/fork-a-repo/) if you're not familiar with Pull Requests.
**IMPORTANT**: By submitting a patch, you agree to allow the project owner to
license your work under the same license as that used by the project.

View File

@@ -18,17 +18,25 @@ The underlying architecture of Grav is designed to use well-established and _bes
# Requirements
- PHP 5.4 or higher. Check the [required modules list](http://learn.getgrav.org/basics/requirements#php-requirements)
- PHP 5.5.9 or higher. Check the [required modules list](http://learn.getgrav.org/basics/requirements#php-requirements)
- Check the [Apache](http://learn.getgrav.org/basics/requirements#apache-requirements) or [IIS](http://learn.getgrav.org/basics/requirements#iis-requirements) requirements
# QuickStart
You have two options to get Grav:
These are the options to get Grav:
### Downloading a Grav Package
You can download a **ready-built** package from the [Downloads page on http://getgrav.org](http://getgrav.org/downloads)
### With composer
You can create a new project with the latest **stable** Grav release with the following command:
```
$ composer create-project getgrav/grav ~/webroot/grav
```
### From GitHub
1. Clone the Grav repository from [https://github.com/getgrav/grav]() to a folder in the webroot of your server, e.g. `~/webroot/grav`. Launch a **terminal** or **console** and navigate to the webroot folder:

View File

@@ -2,10 +2,6 @@
<?php
define('GRAV_CLI', true);
if (version_compare($ver = PHP_VERSION, $req = '5.4.0', '<')) {
exit(sprintf("You are running PHP %s, but Grav needs at least PHP %s to run.\n", $ver, $req));
}
if (!file_exists(__DIR__ . '/../vendor')){
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
}
@@ -25,6 +21,10 @@ use Grav\Common\Grav;
$autoload = require_once(__DIR__ . '/../vendor/autoload.php');
if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) {
exit(sprintf("You are running PHP %s, but Grav needs at least PHP %s to run.\n", $ver, $req));
}
if (!ini_get('date.timezone')) {
date_default_timezone_set('UTC');
}

View File

@@ -2,10 +2,6 @@
<?php
define('GRAV_CLI', true);
if (version_compare($ver = PHP_VERSION, $req = '5.4.0', '<')) {
exit(sprintf("You are running PHP %s, but Grav needs at least PHP %s to run.\n", $ver, $req));
}
if (!file_exists(__DIR__ . '/../vendor')){
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
}
@@ -24,6 +20,10 @@ use Symfony\Component\Console\Application;
require_once __DIR__ . '/../vendor/autoload.php';
if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) {
exit(sprintf("You are running PHP %s, but Grav needs at least PHP %s to run.\n", $ver, $req));
}
if (!ini_get('date.timezone')) {
date_default_timezone_set('UTC');
}

View File

@@ -2,10 +2,6 @@
<?php
define('GRAV_CLI', true);
if (version_compare($ver = PHP_VERSION, $req = '5.4.0', '<')) {
exit(sprintf("You are running PHP %s, but Grav needs at least PHP %s to run.\n", $ver, $req));
}
if (!file_exists(__DIR__ . '/../vendor')) {
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
}
@@ -29,6 +25,10 @@ use Grav\Common\Filesystem\Folder;
$autoload = require_once(__DIR__ . '/../vendor/autoload.php');
if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) {
exit(sprintf("You are running PHP %s, but Grav needs at least PHP %s to run.\n", $ver, $req));
}
if (!ini_get('date.timezone')) {
date_default_timezone_set('UTC');
}

View File

@@ -1,12 +1,12 @@
{
"name": "getgrav/grav",
"type": "library",
"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",
"license": "MIT",
"require": {
"php": ">=5.4.0",
"php": ">=5.5.9",
"twig/twig": "~1.23",
"erusev/parsedown-extra": "~0.7",
"symfony/yaml": "~2.8",
@@ -15,7 +15,7 @@
"symfony/var-dumper": "~2.8",
"symfony/polyfill-iconv": "~1.0",
"doctrine/cache": "~1.5",
"filp/whoops": "1.1.10",
"filp/whoops": "2.0.0-alpha2",
"monolog/monolog": "~1.0",
"gregwar/image": "~2.0",
"ircmaxell/password-compat": "1.0.*",
@@ -25,6 +25,12 @@
"rockettheme/toolbox": "~1.2",
"maximebf/debugbar": "~1.10"
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/getgrav/parsedown"
}
],
"autoload": {
"psr-4": {
"Grav\\": "system/src/Grav"
@@ -33,5 +39,13 @@
},
"archive": {
"exclude": ["VERSION"]
},
"scripts": {
"post-create-project-cmd": "bin/grav install"
},
"extra": {
"branch-alias": {
"dev-develop": "1.x-dev"
}
}
}

122
composer.lock generated
View File

@@ -4,38 +4,38 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "09fcc6b4528be7d9c8af68a66e85f0b2",
"content-hash": "69bee250cbc5160401d50cc47c8d6aba",
"hash": "85173a1bfa9ece106f687d69402d99d8",
"content-hash": "410b016e6cd8af6cd8ee9cdb6d5fd7a4",
"packages": [
{
"name": "doctrine/cache",
"version": "v1.5.2",
"version": "v1.6.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
"reference": "47c7128262da274f590ae6f86eb137a7a64e82af"
"reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/cache/zipball/47c7128262da274f590ae6f86eb137a7a64e82af",
"reference": "47c7128262da274f590ae6f86eb137a7a64e82af",
"url": "https://api.github.com/repos/doctrine/cache/zipball/f8af318d14bdb0eff0336795b428b547bd39ccb6",
"reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
"php": "~5.5|~7.0"
},
"conflict": {
"doctrine/common": ">2.2,<2.4"
},
"require-dev": {
"phpunit/phpunit": ">=3.7",
"phpunit/phpunit": "~4.8|~5.0",
"predis/predis": "~1.0",
"satooshi/php-coveralls": "~0.6"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.5.x-dev"
"dev-master": "1.6.x-dev"
}
},
"autoload": {
@@ -75,7 +75,7 @@
"cache",
"caching"
],
"time": "2015-12-03 10:50:37"
"time": "2015-12-31 16:37:02"
},
{
"name": "donatj/phpuseragentparser",
@@ -133,12 +133,12 @@
"version": "1.6.0",
"source": {
"type": "git",
"url": "https://github.com/erusev/parsedown.git",
"url": "https://github.com/getgrav/parsedown.git",
"reference": "3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/erusev/parsedown/zipball/3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7",
"url": "https://api.github.com/repos/getgrav/parsedown/zipball/3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7",
"reference": "3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7",
"shasum": ""
},
@@ -148,7 +148,6 @@
"Parsedown": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
@@ -165,6 +164,9 @@
"markdown",
"parser"
],
"support": {
"source": "https://github.com/getgrav/parsedown/tree/1.6.0"
},
"time": "2015-10-04 16:44:32"
},
{
@@ -213,36 +215,41 @@
},
{
"name": "filp/whoops",
"version": "1.1.10",
"version": "2.0.0-alpha2",
"source": {
"type": "git",
"url": "https://github.com/filp/whoops.git",
"reference": "72538eeb70bbfb11964412a3d098d109efd012f7"
"reference": "eb1ce6439db161a9f00cd57f33a9cfa1355229ec"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/filp/whoops/zipball/72538eeb70bbfb11964412a3d098d109efd012f7",
"reference": "72538eeb70bbfb11964412a3d098d109efd012f7",
"url": "https://api.github.com/repos/filp/whoops/zipball/eb1ce6439db161a9f00cd57f33a9cfa1355229ec",
"reference": "eb1ce6439db161a9f00cd57f33a9cfa1355229ec",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
"php": ">=5.5.9"
},
"require-dev": {
"mockery/mockery": "0.9.*"
"mockery/mockery": "0.9.*",
"phpunit/phpunit": "^4.8 || ^5.0"
},
"suggest": {
"symfony/var-dumper": "Pretty print complex values better with var-dumper available",
"whoops/soap": "Formats errors as SOAP responses"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2-dev"
"dev-master": "2.0-dev"
}
},
"autoload": {
"psr-0": {
"Whoops": "src/"
"psr-4": {
"Whoops\\": "src/Whoops/"
},
"classmap": [
"src/deprecated"
"files": [
"src/Whoops/functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -263,11 +270,10 @@
"exception",
"handling",
"library",
"silex-provider",
"whoops",
"zf2"
],
"time": "2015-06-29 05:42:04"
"time": "2015-12-15 12:27:17"
},
{
"name": "gregwar/cache",
@@ -720,16 +726,16 @@
},
{
"name": "symfony/console",
"version": "v2.8.0",
"version": "v2.8.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "d232bfc100dfd32b18ccbcab4bcc8f28697b7e41"
"reference": "2e06a5ccb19dcf9b89f1c6a677a39a8df773635a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/d232bfc100dfd32b18ccbcab4bcc8f28697b7e41",
"reference": "d232bfc100dfd32b18ccbcab4bcc8f28697b7e41",
"url": "https://api.github.com/repos/symfony/console/zipball/2e06a5ccb19dcf9b89f1c6a677a39a8df773635a",
"reference": "2e06a5ccb19dcf9b89f1c6a677a39a8df773635a",
"shasum": ""
},
"require": {
@@ -776,11 +782,11 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"time": "2015-11-30 12:35:10"
"time": "2015-12-22 10:25:57"
},
{
"name": "symfony/event-dispatcher",
"version": "v2.8.0",
"version": "v2.8.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
@@ -840,21 +846,24 @@
},
{
"name": "symfony/polyfill-iconv",
"version": "v1.0.0",
"version": "v1.0.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-iconv.git",
"reference": "21a18998764e569c1675efc7191887130b319605"
"reference": "541cce29a46d6ee18bb9271c6ac3ca783b0faab0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/21a18998764e569c1675efc7191887130b319605",
"reference": "21a18998764e569c1675efc7191887130b319605",
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/541cce29a46d6ee18bb9271c6ac3ca783b0faab0",
"reference": "541cce29a46d6ee18bb9271c6ac3ca783b0faab0",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-iconv": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
@@ -892,25 +901,28 @@
"portable",
"shim"
],
"time": "2015-11-04 20:28:58"
"time": "2015-11-20 09:19:13"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.0.0",
"version": "v1.0.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "0b6a8940385311a24e060ec1fe35680e17c74497"
"reference": "49ff736bd5d41f45240cec77b44967d76e0c3d25"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0b6a8940385311a24e060ec1fe35680e17c74497",
"reference": "0b6a8940385311a24e060ec1fe35680e17c74497",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/49ff736bd5d41f45240cec77b44967d76e0c3d25",
"reference": "49ff736bd5d41f45240cec77b44967d76e0c3d25",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
@@ -948,20 +960,20 @@
"portable",
"shim"
],
"time": "2015-11-04 20:28:58"
"time": "2015-11-20 09:19:13"
},
{
"name": "symfony/var-dumper",
"version": "v2.8.0",
"version": "v2.8.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "e6f3855005f2bfad7d7e72431d374a6478893fe3"
"reference": "f943f29ae69c42511a2d85adee9d13d835b5c803"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/e6f3855005f2bfad7d7e72431d374a6478893fe3",
"reference": "e6f3855005f2bfad7d7e72431d374a6478893fe3",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/f943f29ae69c42511a2d85adee9d13d835b5c803",
"reference": "f943f29ae69c42511a2d85adee9d13d835b5c803",
"shasum": ""
},
"require": {
@@ -1011,20 +1023,20 @@
"debug",
"dump"
],
"time": "2015-11-18 13:45:00"
"time": "2015-12-05 11:09:21"
},
{
"name": "symfony/yaml",
"version": "v2.8.0",
"version": "v2.8.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "f79824187de95064a2f5038904c4d7f0227fedb5"
"reference": "ac84cbb98b68a6abbc9f5149eb96ccc7b07b8966"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/f79824187de95064a2f5038904c4d7f0227fedb5",
"reference": "f79824187de95064a2f5038904c4d7f0227fedb5",
"url": "https://api.github.com/repos/symfony/yaml/zipball/ac84cbb98b68a6abbc9f5149eb96ccc7b07b8966",
"reference": "ac84cbb98b68a6abbc9f5149eb96ccc7b07b8966",
"shasum": ""
},
"require": {
@@ -1060,7 +1072,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"time": "2015-11-30 12:35:10"
"time": "2015-12-26 13:37:56"
},
{
"name": "twig/twig",
@@ -1127,11 +1139,13 @@
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"stability-flags": {
"filp/whoops": 15
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=5.4.0"
"php": ">=5.5.9"
},
"platform-dev": []
}

View File

@@ -1,9 +1,6 @@
<?php
namespace Grav;
if (version_compare($ver = PHP_VERSION, $req = '5.4.0', '<')) {
throw new \RuntimeException(sprintf('You are running PHP %s, but Grav needs at least <strong>PHP %s</strong> to run.', $ver, $req));
}
// Ensure vendor libraries exist
$autoload = __DIR__ . '/vendor/autoload.php';
@@ -16,6 +13,10 @@ use Grav\Common\Grav;
// Register the auto-loader.
$loader = require_once $autoload;
if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) {
throw new \RuntimeException(sprintf('You are running PHP %s, but Grav needs at least <strong>PHP %s</strong> to run.', $ver, $req));
}
// Set timezone to default, falls back to system if php.ini not set
date_default_timezone_set(@date_default_timezone_get());

View File

@@ -1,110 +1,19 @@
body {
background-color: #eee;
}
body header {
background: #349886;
border-left: 8px solid #29796B;
background: #8552A2;
}
body .clipboard {
width: 28px;
height: 28px;
background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcAQMAAABIw03XAAAAA3NCSVQICAjb4U/gAAAABlBMVEX///////9VfPVsAAAAAnRSTlP/AOW3MEoAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAcdEVYdFNvZnR3YXJlAEFkb2JlIEZpcmV3b3JrcyBDUzbovLKMAAAAFnRFWHRDcmVhdGlvbiBUaW1lADEwLzE1LzE0xr/LJAAAADhJREFUCJlj+P///wcGBPGDQR5E8OMi2IEEczOIaAQRHSCioQBGHAAR/7AT/z+DiA8MMALVXhABAJf9Sr5aY+UFAAAAAElFTkSuQmCC);
body .left-panel {
background: inherit;
}
body .exc-title-primary {
color: #1C3631;
text-shadow: none;
color: #fff;
}
body .exc-title {
color: #2F5B52;
text-shadow: none;
}
body .data-table-container label {
color: #0082BA;
}
body .frame {
border: 0;
}
body .frames-container {
overflow-y: auto;
overflow-x: hidden;
}
body .active .frame-class {
color: #E3D8E9;
}
body .frame-class {
color: #9055AF;
}
body .frame.active {
border: 0;
box-shadow: none;
background-color: #9055AF;
color: #ddd;
}
body .frame:not(.active):hover {
background: #e9e9e9;
}
body .frame-file, body .data-table tbody {
font-family: "DejaVu Sans Mono", Menlo, Monaco, Consolas, Courier, monospace;
font-size: 13px;
}
body .frame-code {
background: #305669;
border-left: 8px solid #253A47;
padding: 1rem;
}
body .frame-code .frame-file {
background: #253A47;
color: #eee;
text-shadow: none;
box-shadow: none;
font-family: inherit;
}
body .frame-code .frame-file strong {
color: #fff;
font-weight: normal;
}
body .frame-comments {
background: #283E4D;
box-shadow: none;
}
body .frame-comments.empty:before {
color: #789AAB;
}
body .details-container {
border: 0;
}
body .details {
background-color: #eee;
border-left: 8px solid #ddd;
padding: 1rem;
}
body .code-block {
background: #2C4454;
box-shadow: none;
font-family: "DejaVu Sans Mono", Menlo, Monaco, Consolas, Courier, monospace;
font-size: 13px;
}
body .handler.active {
background: #666;
background: #e6e6e6;
}

View File

@@ -20,6 +20,18 @@ form:
show_root: false
help: PLUGIN_ADMIN.HOME_PAGE_HELP
home.hide_in_urls:
type: toggle
label: PLUGIN_ADMIN.HIDE_HOME_IN_URLS
help: PLUGIN_ADMIN.HIDE_HOME_IN_URLS_HELP
highlight: 0
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
pages.theme:
type: themeselect
classes: fancy
@@ -221,6 +233,19 @@ form:
validate:
type: bool
pages.twig_first:
type: toggle
label: PLUGIN_ADMIN.TWIG_FIRST
highlight: asc
default: desc
help: PLUGIN_ADMIN.TWIG_FIRST_HELP
highlight: 0
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
languages:
type: section
title: PLUGIN_ADMIN.LANGUAGES
@@ -793,6 +818,29 @@ form:
label: PLUGIN_ADMIN.NAME
help: PLUGIN_ADMIN.SESSION_NAME_HELP
session.secure:
type: toggle
label: PLUGIN_ADMIN.SESSION_SECURE
help: PLUGIN_ADMIN.SESSION_SECURE_HELP
highlight: 1
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
default: false
validate:
type: bool
session.httponly:
type: toggle
label: PLUGIN_ADMIN.SESSION_HTTPONLY
help: PLUGIN_ADMIN.SESSION_HTTPONLY_HELP
highlight: 1
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
default: true
validate:
type: bool
advanced:
type: section

View File

@@ -55,7 +55,7 @@ form:
help: PLUGIN_ADMIN.LANGUAGE_HELP
security:
title: Security
title: PLUGIN_ADMIN.ACCESS_LEVELS
type: section
security: admin.super
@@ -82,4 +82,4 @@ form:
label: PLUGIN_ADMIN.SITE_ACCESS
multiple: false
validate:
type: array
type: array

View File

@@ -168,6 +168,10 @@ zip:
type: file
thumb: media/thumb-zip.png
mime: application/zip
7z:
type: file
thumb: media/thumb-7zip.png
mime: application/x-7z-compressed
gz:
type: file
thumb: media/thumb-gz.png

View File

@@ -15,6 +15,7 @@ languages:
home:
alias: '/home' # Default path for home, ie /
hide_in_urls: false # Hide the home route in URLs
pages:
theme: antimatter # Default theme (defaults to "antimatter" theme)
@@ -31,6 +32,7 @@ pages:
process:
markdown: true # Process Markdown
twig: false # Process Twig
twig_first: false # Process Twig before markdown when processing both on a page
events:
page: true # Enable page level events
twig: true # Enable twig level events
@@ -97,7 +99,7 @@ debugger:
images:
default_image_quality: 85 # Default image quality to use when resampling images (85%)
cache_all: false # Cache all image by default
cache_perms: 0755 # Default cache folder perms. Usually 0755 or 0775 depending on setup
cache_perms: '0755' # MUST BE IN QUOTES!! Default cache folder perms. Usually '0755' or '0775'
debug: false # Show an overlay over images indicating the pixel depth of the image when working with retina for example
media:
@@ -110,5 +112,5 @@ session:
enabled: true # Enable Session support
timeout: 1800 # Timeout in seconds
name: grav-site # Name prefix of the session cookie. Use alphanumeric, dashes or underscores only. Do not use dots in the session name
secure: false # Set session secure. If true, indicates that communication for this cookie must be over an encrypted transmission. Enable this only on sites that run exclusively on HTTPS
httponly: true # Set session HTTP only. If true, indicates that cookies should be used only over HTTP, and JavaScript modification is not allowed.

View File

@@ -2,8 +2,9 @@
// Some standard defines
define('GRAV', true);
define('GRAV_VERSION', '1.0.3');
define('GRAV_VERSION', '1.0.7');
define('DS', '/');
define('GRAV_PHP_MIN', '5.5.9');
// Directories and Paths
if (!defined('GRAV_ROOT')) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

View File

@@ -35,3 +35,5 @@ NICETIME:
MO_PLURAL: m
YR_PLURAL: r
DEC_PLURAL: dek
MONTHS_OF_THE_YEAR: ['Leden', 'Únor', 'Březen', 'Duben', 'Květen', 'Červen', 'Červenec', 'Srpen', 'Září', 'Říjen', 'Listopad', 'Prosinec']
DAYS_OF_THE_WEEK: ['Pondělí', 'Úterý', 'Středa', 'Čtvrtek', 'Pátek', 'Sobota', 'Neděle']

View File

@@ -41,3 +41,5 @@ NICETIME:
MO_PLURAL: Monate
YR_PLURAL: Jahre
DEC_PLURAL: Dekaden
MONTHS_OF_THE_YEAR: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember']
DAYS_OF_THE_WEEK: ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag']

2
system/languages/el.yaml Normal file
View File

@@ -0,0 +1,2 @@
MONTHS_OF_THE_YEAR: ['Ιανουάριος', 'Φεβρουάριος', 'Μάρτιος', 'Απρίλιος', 'Μάιος', 'Ιούνιος', 'Ιούλιος', 'Αύγουστος', 'Σεπτέμβριος', 'Οκτώβριος', 'Νοέμβριος', 'Δεκέμβριος']
DAYS_OF_THE_WEEK: ['Δευτέρα', 'Τρλιτη', 'Τετάρτη', 'Πέμπτη', 'Παρασκευή', 'Σαββάτο', 'Κυριακή']

View File

@@ -96,3 +96,5 @@ FORM:
VALIDATION_FAIL: <b>Validation failed:</b>
INVALID_INPUT: Invalid input in
MISSING_REQUIRED_FIELD: Missing required field:
MONTHS_OF_THE_YEAR: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
DAYS_OF_THE_WEEK: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

View File

@@ -39,4 +39,6 @@ FORM:
VALIDATION_FAIL: <b>Falló la validación. </b>
INVALID_INPUT: "Dato inválido en: "
MISSING_REQUIRED_FIELD: "Falta el campo requerido: "
MONTHS_OF_THE_YEAR: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Augosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre']
DAYS_OF_THE_WEEK: ['Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado', 'Domingo']

2
system/languages/fi.yaml Normal file
View File

@@ -0,0 +1,2 @@
MONTHSOFTHE_YEAR: ['Tammikuu', 'Helmikuu', 'Maaliskuu', 'Huhtikuu', 'Toukokuu', 'Kesäkuu', 'Heinäkuu', 'Elokuu', 'Syyskuu', 'Lokakuu', 'Marraskuu', 'Joulukuu']
DAYSOFTHE_WEEK: ['Maanantai', 'Tiistai', 'Keskiviikko', 'Torstai', 'Perjantai', 'Lauantai', 'Sunnuntai']

View File

@@ -43,13 +43,13 @@ INFLECTOR_SINGULAR:
'/([ti])a$/i': '\1um'
'/(n)ews$/i': '\1ews'
'/s$/i': ''
INFLECTOR_UNCOUNTABLE: ['équipment', 'information', 'riz', 'argent', 'espèces', 'séries', 'poisson', 'mouton']
INFLECTOR_UNCOUNTABLE: ['équipement', 'information', 'riz', 'argent', 'espèces', 'séries', 'poisson', 'mouton']
INFLECTOR_IRREGULAR:
'person': 'personnes'
'man': 'Hommes'
'man': 'hommes'
'child': 'enfants'
'sex': 'sexes'
'move': 'déplacemements'
'move': 'déplacements'
INFLECTOR_ORDINALS:
'default': 'ème'
'first': 'er'
@@ -96,3 +96,5 @@ FORM:
VALIDATION_FAIL: <b>La validation a échoué :</b>
INVALID_INPUT: Saisie non valide
MISSING_REQUIRED_FIELD: Champ obligatoire manquant :
MONTHS_OF_THE_YEAR: ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre']
DAYS_OF_THE_WEEK: ['Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi', 'Dimanche']

View File

@@ -23,3 +23,5 @@ FORM:
VALIDATION_FAIL: <b>Validazione fallita:</b>
INVALID_INPUT: Input invalido in
MISSING_REQUIRED_FIELD: Campo richiesto mancante:
MONTHS_OF_THE_YEAR: ['Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno', 'Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre']
DAYS_OF_THE_WEEK: ['Lunedi', 'Martedi', 'Mercoledi', 'Giovedi', 'Venerdi', 'Sabato', 'Domenica']

2
system/languages/nb.yaml Normal file
View File

@@ -0,0 +1,2 @@
MONTHS_OF_THE_YEAR: ['januar', 'februar', 'mars', 'april', 'mai', 'juni', 'juli', 'august', 'september', 'oktober', 'november', 'desember']
DAYS_OF_THE_WEEK: ['mandag', 'tirsdag', 'onsdag', 'torsdag', 'fredag', 'lørdag', 'søndag']

View File

@@ -41,3 +41,5 @@ NICETIME:
MO_PLURAL: maanden
YR_PLURAL: jaren
DEC_PLURAL: decs
MONTHS_OF_THE_YEAR: ['Januari', 'Februari', 'Maart', 'April', 'Mei', 'Juni', 'Juli', 'Augustus', 'September', 'Oktober', 'November', 'December']
DAYS_OF_THE_WEEK: ['Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrijdag', 'Zaterdag', 'Zondag']

2
system/languages/pl.yaml Normal file
View File

@@ -0,0 +1,2 @@
MONTHS_OF_THE_YEAR: ['Styczeń', 'Luty', 'Marzec', 'Kwiecień', 'Maj', 'Czerwiec', 'Lipiec', 'Sierpień', 'Wrzesień', 'Październik', 'Listopad', 'Grudzień']
DAYS_OF_THE_WEEK: ['Poniedziałek', 'Wtorek', 'Środa', 'Czwartek', 'Piątek', 'Sobota', 'Niedziela']

2
system/languages/pt.yaml Normal file
View File

@@ -0,0 +1,2 @@
MONTHS_OF_THE_YEAR: ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro']
DAYS_OF_THE_WEEK: ['Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado', 'Domingo']

2
system/languages/ro.yaml Normal file
View File

@@ -0,0 +1,2 @@
MONTHS_OF_THE_YEAR: ['Ianuarie', 'Februarie', 'Martie', 'Aprilue', 'Mai', 'Iunie', 'Iulie', 'August', 'Septembrie', 'Octombrie', 'Noiembrie', 'Decembrie']
DAYS_OF_THE_WEEK: ['Luni', 'Marti', 'Miercuri', 'Joi', 'Vineri', 'Sâmbătă', 'Duminică']

View File

@@ -41,3 +41,5 @@ NICETIME:
MO_PLURAL: мес
YR_PLURAL: г.
DEC_PLURAL: гг.
MONTHS_OF_THE_YEAR: ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь']
DAYS_OF_THE_WEEK: ['Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье']

View File

@@ -186,7 +186,7 @@ class Assets
$this->base_url = $base_url . '/';
// Register any preconfigured collections
foreach ($config->get('system.assets.collections') as $name => $collection) {
foreach ($config->get('system.assets.collections', []) as $name => $collection) {
$this->registerCollection($name, (array)$collection);
}
}
@@ -485,20 +485,20 @@ class Assets
*/
public function css($group = 'head', $attributes = [])
{
if (!$this->css) {
if (!$this->css && !$this->inline_css) {
return null;
}
// Sort array by priorities (larger priority first)
if (self::getGrav()) {
usort($this->css, function ($a, $b) {
uasort($this->css, function ($a, $b) {
if ($a['priority'] == $b['priority']) {
return $b['order'] - $a['order'];
}
return $a['priority'] - $b['priority'];
});
usort($this->inline_css, function ($a, $b) {
uasort($this->inline_css, function ($a, $b) {
if ($a['priority'] == $b['priority']) {
return $b['order'] - $a['order'];
}
@@ -558,19 +558,19 @@ class Assets
*/
public function js($group = 'head', $attributes = [])
{
if (!$this->js) {
if (!$this->js && !$this->inline_js) {
return null;
}
// Sort array by priorities (larger priority first)
usort($this->js, function ($a, $b) {
uasort($this->js, function ($a, $b) {
if ($a['priority'] == $b['priority']) {
return $b['order'] - $a['order'];
}
return $a['priority'] - $b['priority'];
});
usort($this->inline_js, function ($a, $b) {
uasort($this->inline_js, function ($a, $b) {
if ($a['priority'] == $b['priority']) {
return $b['order'] - $a['order'];
}

View File

@@ -64,6 +64,8 @@ class ZipBackup
$zip = new \ZipArchive();
$zip->open($destination, \ZipArchive::CREATE);
$max_execution_time = ini_set('max_execution_time', 600);
static::folderToZip(GRAV_ROOT, $zip, strlen(rtrim(GRAV_ROOT, DS) . DS), $messager);
$messager && $messager([
@@ -85,6 +87,10 @@ class ZipBackup
$zip->close();
if ($max_execution_time !== false) {
ini_set('max_execution_time', $max_execution_time);
}
return $destination;
}

View File

@@ -40,6 +40,8 @@ class Cache extends Getters
protected $driver_name;
protected $driver_setting;
/**
* @var bool
*/
@@ -108,13 +110,15 @@ class Cache extends Getters
// Cache key allows us to invalidate all cache on configuration changes.
$this->key = ($prefix ? $prefix : 'g') . '-' . substr(md5($uri->rootUrl(true) . $this->config->key() . GRAV_VERSION), 2, 8);
$this->driver_setting = $this->config->get('system.cache.driver');
$this->driver = $this->getCacheDriver();
// Set the cache namespace to our unique key
$this->driver->setNamespace($this->key);
// Dump Cache state
$grav['debugger']->addMessage('Cache: [' . ($this->enabled ? 'true' : 'false') . '] Driver: [' . $this->driver_name . ']');
$grav['debugger']->addMessage('Cache: [' . ($this->enabled ? 'true' : 'false') . '] Setting: [' . $this->driver_setting . '] Driver: [' . $this->driver_name . ']');
}
@@ -127,11 +131,13 @@ class Cache extends Getters
*/
public function getCacheDriver()
{
$setting = $this->config->get('system.cache.driver');
$setting = $this->driver_setting;
$driver_name = 'file';
if (!$setting || $setting == 'auto') {
if (extension_loaded('apc')) {
if (extension_loaded('apcu')) {
$driver_name = 'apcu';
} elseif (extension_loaded('apc')) {
$driver_name = 'apc';
} elseif (extension_loaded('wincache')) {
$driver_name = 'wincache';
@@ -149,6 +155,10 @@ class Cache extends Getters
$driver = new \Doctrine\Common\Cache\ApcCache();
break;
case 'apcu':
$driver = new \Doctrine\Common\Cache\ApcuCache();
break;
case 'wincache':
$driver = new \Doctrine\Common\Cache\WinCacheCache();
break;

View File

@@ -192,7 +192,9 @@ abstract class CompiledBase
}
$this->createObject($cache['data']);
$this->finalizeObject();
return true;
}

View File

@@ -338,8 +338,10 @@ class Blueprint implements \ArrayAccess, ExportInterface
if ($field['type'] === 'list') {
// we loop through list to get the actual field
foreach($field['fields'] as $subName => &$subField) {
$this->parseFormField($subField);
if (isset($field['fields']) && $field['fields']) {
foreach($field['fields'] as $subName => &$subField) {
$this->parseFormField($subField);
}
}
} else {
$this->parseFormField($field);

View File

@@ -211,7 +211,7 @@ class Data implements DataInterface, \ArrayAccess, \Countable, ExportInterface
*/
public function extra()
{
return $this->blueprints()->extra($this->items);
return $this->blueprints ? $this->blueprints->extra($this->items) : array();
}
/**

View File

@@ -283,7 +283,15 @@ class Validation
protected static function filterFile($value, array $params, array $field)
{
return (array) $value;
if (isset($field['multiple']) && $field['multiple'] == true) {
return (array) $value;
}
if (is_array($value)) {
return reset($value);
}
return $value;
}
/**

View File

@@ -28,7 +28,8 @@ class Debugger
$this->grav = Grav::instance();
if ($this->enabled()) {
$this->debugbar->addCollector(new \DebugBar\DataCollector\ConfigCollector((array)$this->grav['config']->get('system')));
$this->debugbar->addCollector(new \DebugBar\DataCollector\ConfigCollector((array)$this->grav['config']->get('system'), 'Config'));
$this->debugbar->addCollector(new \DebugBar\DataCollector\ConfigCollector((array)$this->grav['config']->get('plugins'), 'Plugins'));
}
return $this;
}

View File

@@ -2,51 +2,54 @@
namespace Grav\Common\Errors;
use Grav\Common\Grav;
use Whoops\Handler\CallbackHandler;
use Whoops\Handler\HandlerInterface;
use Whoops\Run;
use Whoops;
/**
* Class Debugger
* @package Grav\Common
*/
class Errors extends Run
class Errors
{
public function pushHandler($handler, $key = null)
{
if (is_callable($handler)) {
$handler = new CallbackHandler($handler);
}
if (!$handler instanceof HandlerInterface) {
throw new \InvalidArgumentException(
"Argument to " . __METHOD__ . " must be a callable, or instance of"
. "Whoops\\Handler\\HandlerInterface"
);
}
// Store with key if provided
if ($key) {
$this->handlerStack[$key] = $handler;
} else {
$this->handlerStack[] = $handler;
}
return $this;
}
public function resetHandlers()
{
$grav = Grav::instance();
$config = $grav['config']->get('system.errors');
if (isset($config['display']) && !$config['display']) {
unset($this->handlerStack['pretty']);
$this->handlerStack = array('simple' => new SimplePageHandler()) + $this->handlerStack;
}
if (isset($config['log']) && !$config['log']) {
unset($this->handlerStack['log']);
}
}
// Setup Whoops-based error handler
$whoops = new \Whoops\Run;
if (isset($config['display'])) {
if ($config['display']) {
$error_page = new Whoops\Handler\PrettyPageHandler;
$error_page->setPageTitle('Crikey! There was an error...');
$error_page->addResourcePath(GRAV_ROOT . '/system/assets');
$error_page->addCustomCss('whoops.css');
$whoops->pushHandler($error_page);
} else {
$whoops->pushHandler(new SimplePageHandler);
}
}
if (function_exists('Whoops\isAjaxRequest')) { //Whoops 2
if (Whoops\isAjaxRequest()) {
$whoops->pushHandler(new Whoops\Handler\JsonResponseHandler);
}
} else { //Whoops 1
$json_page = new Whoops\Handler\JsonResponseHandler;
$json_page->onlyForAjaxRequests(true);
}
if (isset($config['log']) && $config['log']) {
$logger = $grav['log'];
$whoops->pushHandler(function($exception, $inspector, $run) use ($logger) {
try {
$logger->addCritical($exception->getMessage() . ' - Trace: ' . $exception->getTraceAsString());
} catch (\Exception $e) {
echo $e;
}
}, 'log');
}
$whoops->register();
}
}

View File

@@ -323,13 +323,24 @@ class GPM extends Iterator
return $found;
}
foreach ($this->getRepositoryThemes() as $slug => $theme) {
$themes = $this->getRepositoryThemes();
$plugins = $this->getRepositoryPlugins();
if (!$themes && !$plugins) {
if (!is_writable(ROOT_DIR . '/cache/gpm')) {
throw new \RuntimeException("The cache/gpm folder is not writable. Please check the folder permissions.");
}
throw new \RuntimeException("GPM not reachable. Please check your internet connection or check the Grav site is reachable");
}
if ($themes) foreach ($themes as $slug => $theme) {
if ($search == $slug || $search == $theme->name) {
return $theme;
}
}
foreach ($this->getRepositoryPlugins() as $slug => $plugin) {
if ($plugins) foreach ($plugins as $slug => $plugin) {
if ($search == $slug || $search == $plugin->name) {
return $plugin;
}

View File

@@ -281,6 +281,10 @@ class Installer
{
$msg = 'Unknown Error';
if (is_string(self::$error)) {
return self::$error;
}
switch (self::$error) {
case 0:
$msg = 'No Error';
@@ -333,7 +337,7 @@ class Installer
/**
* Allows to manually set an error
* @param $error the Error code
* @param int|string $error the Error code
*/
public static function setError($error)

View File

@@ -5,7 +5,7 @@ use \Doctrine\Common\Cache\FilesystemCache;
class Grav extends AbstractPackageCollection
{
protected $repository = 'http://getgrav.org/downloads/grav.json';
protected $repository = 'https://getgrav.org/downloads/grav.json';
private $data;
private $version;

View File

@@ -12,7 +12,7 @@ class Plugins extends AbstractPackageCollection
*/
protected $type = 'plugins';
protected $repository = 'http://getgrav.org/downloads/plugins.json';
protected $repository = 'https://getgrav.org/downloads/plugins.json';
/**
* Local Plugins Constructor

View File

@@ -12,7 +12,7 @@ class Themes extends AbstractPackageCollection
*/
protected $type = 'themes';
protected $repository = 'http://getgrav.org/downloads/themes.json';
protected $repository = 'https://getgrav.org/downloads/themes.json';
/**
* Local Themes Constructor

View File

@@ -7,23 +7,26 @@ class Response
{
/**
* The callback for the progress
*
* @var callable Either a function or callback in array notation
*/
public static $callback = null;
/**
/**
* Which method to use for HTTP calls, can be 'curl', 'fopen' or 'auto'. Auto is default and fopen is the preferred method
*
* @var string
*/
private static $method = 'auto';
/**
* Default parameters for `curl` and `fopen`
*
* @var array
*/
private static $defaults = [
'curl' => [
'curl' => [
CURLOPT_REFERER => 'Grav GPM',
CURLOPT_USERAGENT => 'Grav GPM',
CURLOPT_RETURNTRANSFER => true,
@@ -51,7 +54,9 @@ class Response
/**
* Sets the preferred method to use for making HTTP calls.
*
* @param string $method Default is `auto`
*
* @return Response
*/
public static function setMethod($method = 'auto')
@@ -67,9 +72,11 @@ class Response
/**
* Makes a request to the URL by using the preferred method
* @param string $uri URL to call
* @param array $options An array of parameters for both `curl` and `fopen`
*
* @param string $uri URL to call
* @param array $options An array of parameters for both `curl` and `fopen`
* @param callable $callback Either a function or callback in array notation
*
* @return string The response of the request
*/
public static function get($uri = '', $options = [], $callback = null)
@@ -83,7 +90,8 @@ class Response
if (!Utils::isFunctionDisabled('set_time_limit') && !ini_get('safe_mode') && function_exists('set_time_limit')) {
set_time_limit(0);
}
} catch (\Exception $e) {}
} catch (\Exception $e) {
}
$options = array_replace_recursive(self::$defaults, $options);
$method = 'get' . ucfirst(strtolower(self::$method));
@@ -92,9 +100,31 @@ class Response
return static::$method($uri, $options, $callback);
}
/**
* Checks if cURL is available
*
* @return boolean
*/
public static function isCurlAvailable()
{
return function_exists('curl_version');
}
/**
* Checks if the remote fopen request is enabled in PHP
*
* @return boolean
*/
public static function isFopenAvailable()
{
return preg_match('/1|yes|on|true/i', ini_get('allow_url_fopen'));
}
/**
* Progress normalized for cURL and Fopen
*
* @param args Variable length of arguments passed in by stream method
*
* @return array Normalized array with useful data.
* Format: ['code' => int|false, 'filesize' => bytes, 'transferred' => bytes, 'percent' => int]
*/
@@ -115,7 +145,7 @@ class Response
}
if ($bytes_transferred > 0) {
if ($notification_code == STREAM_NOTIFY_PROGRESS|STREAM_NOTIFY_COMPLETED || $isCurlResource) {
if ($notification_code == STREAM_NOTIFY_PROGRESS | STREAM_NOTIFY_COMPLETED || $isCurlResource) {
$progress = [
'code' => $notification_code,
@@ -131,31 +161,14 @@ class Response
}
}
/**
* Checks if cURL is available
* @return boolean
*/
public static function isCurlAvailable()
{
return function_exists('curl_version');
}
/**
* Checks if the remote fopen request is enabled in PHP
* @return boolean
*/
public static function isFopenAvailable()
{
return preg_match('/1|yes|on|true/i', ini_get('allow_url_fopen'));
}
/**
* Automatically picks the preferred method
*
* @return string The response of the request
*/
private static function getAuto()
{
if (self::isFopenAvailable()) {
if (!ini_get('open_basedir') && self::isFopenAvailable()) {
return self::getFopen(func_get_args());
}
@@ -164,46 +177,9 @@ class Response
}
}
/**
* Starts a HTTP request via cURL
* @return string The response of the request
*/
private static function getCurl()
{
$args = func_get_args();
$args = count($args) > 1 ? $args : array_shift($args);
$uri = $args[0];
$options = $args[1];
$callback = $args[2];
$ch = curl_init($uri);
curl_setopt_array($ch, $options['curl']);
if ($callback) {
curl_setopt_array(
$ch,
[
CURLOPT_NOPROGRESS => false,
CURLOPT_PROGRESSFUNCTION => ['self', 'progress']
]
);
}
$response = curl_exec($ch);
if ($errno = curl_errno($ch)) {
$error_message = curl_strerror($errno);
throw new \RuntimeException("cURL error ({$errno}):\n {$error_message}");
}
curl_close($ch);
return $response;
}
/**
* Starts a HTTP request via fopen
*
* @return string The response of the request
*/
private static function getFopen()
@@ -229,4 +205,99 @@ class Response
return $content;
}
/**
* Starts a HTTP request via cURL
*
* @return string The response of the request
*/
private static function getCurl()
{
$args = func_get_args();
$args = count($args) > 1 ? $args : array_shift($args);
$uri = $args[0];
$options = $args[1];
$callback = $args[2];
$ch = curl_init($uri);
$response = static::_curl_exec_follow($ch, $options, $callback);
if ($errno = curl_errno($ch)) {
$error_message = curl_strerror($errno);
throw new \RuntimeException("cURL error ({$errno}):\n {$error_message}");
}
curl_close($ch);
return $response;
}
private static function _curl_exec_follow($ch, $options, $callback)
{
if ($callback) {
curl_setopt_array(
$ch,
[
CURLOPT_NOPROGRESS => false,
CURLOPT_PROGRESSFUNCTION => ['self', 'progress']
]
);
}
// no open_basedir set, we can proceed normally
if (!ini_get('open_basedir')) {
curl_setopt_array($ch, $options['curl']);
return curl_exec($ch);
}
$max_redirects = isset($options['curl'][CURLOPT_MAXREDIRS]) ? $options['curl'][CURLOPT_MAXREDIRS] : 3;
$options['curl'][CURLOPT_FOLLOWLOCATION] = false;
// open_basedir set but no redirects to follow, we can disable followlocation and proceed normally
curl_setopt_array($ch, $options['curl']);
if ($max_redirects <= 0) {
return curl_exec($ch);
}
$uri = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
$rch = curl_copy_handle($ch);
curl_setopt($rch, CURLOPT_HEADER, true);
curl_setopt($rch, CURLOPT_NOBODY, true);
curl_setopt($rch, CURLOPT_FORBID_REUSE, false);
curl_setopt($rch, CURLOPT_RETURNTRANSFER, true);
do {
curl_setopt($rch, CURLOPT_URL, $uri);
$header = curl_exec($rch);
if (curl_errno($rch)) {
$code = 0;
} else {
$code = curl_getinfo($rch, CURLINFO_HTTP_CODE);
if ($code == 301 || $code == 302) {
preg_match('/Location:(.*?)\n/', $header, $matches);
$uri = trim(array_pop($matches));
} else {
$code = 0;
}
}
} while ($code && --$max_redirects);
curl_close($rch);
if (!$max_redirects) {
if ($max_redirects === null) {
trigger_error('Too many redirects. When following redirects, libcurl hit the maximum amount.', E_USER_WARNING);
}
return false;
}
curl_setopt($ch, CURLOPT_URL, $uri);
return curl_exec($ch);
}
}

View File

@@ -1,22 +1,32 @@
<?php
namespace Grav\Common\GPM;
use Grav\Common\Grav;
/**
* Class Upgrader
*
* @package Grav\Common\GPM
*/
class Upgrader
{
/**
* Remote details about latest Grav version
*
* @var Packages
*/
private $remote;
/**
* Internal cache
*
* @var Iterator
*/
protected $cache;
/**
* Creates a new GPM instance with Local and Remote packages available
*
* @param boolean $refresh Applies to Remote Packages only and forces a refetch of data
* @param callable $callback Either a function or callback in array notation
*/
@@ -27,6 +37,7 @@ class Upgrader
/**
* Returns the release date of the latest version of Grav
*
* @return string
*/
public function getReleaseDate()
@@ -36,6 +47,7 @@ class Upgrader
/**
* Returns the version of the installed Grav
*
* @return string
*/
public function getLocalVersion()
@@ -45,6 +57,7 @@ class Upgrader
/**
* Returns the version of the remotely available Grav
*
* @return string
*/
public function getRemoteVersion()
@@ -54,6 +67,7 @@ class Upgrader
/**
* Returns an array of assets available to download remotely
*
* @return array
*/
public function getAssets()
@@ -63,6 +77,7 @@ class Upgrader
/**
* Returns the changelog list for each version of Grav
*
* @param string $diff the version number to start the diff from
*
* @return array return the changelog list for each version
@@ -72,8 +87,21 @@ class Upgrader
return $this->remote->getChangelog($diff);
}
/**
* @return bool
*/
public function meetsRequirements()
{
if (version_compare(PHP_VERSION, GRAV_PHP_MIN, '<')) {
return false;
}
return true;
}
/**
* Checks if the currently installed Grav is upgradable to a newer version
*
* @return boolean True if it's upgradable, False otherwise.
*/
public function isUpgradable()
@@ -83,6 +111,7 @@ class Upgrader
/**
* Checks if Grav is currently symbolically linked
*
* @return boolean True if Grav is symlinked, False otherwise.
*/

View File

@@ -57,8 +57,6 @@ class Grav extends Container
$container['grav'] = $container;
$container['debugger'] = new Debugger();
$container['debugger']->startTimer('_init', 'Initialize');
@@ -185,8 +183,6 @@ class Grav extends Container
/** @var Debugger $debugger */
$debugger = $this['debugger'];
// Initialize configuration.
$debugger->startTimer('_config', 'Configuration');
$this['config']->init();
@@ -417,41 +413,49 @@ class Grav extends Container
*/
public function shutdown()
{
if ($this['config']->get('system.debugger.shutdown.close_connection')) {
// Prevent user abort.
if (function_exists('ignore_user_abort')) {
@ignore_user_abort(true);
}
// Close the session.
if (isset($this['session'])) {
$this['session']->close();
}
if ($this['config']->get('system.cache.gzip')) {
// Flush gzhandler buffer if gzip was enabled.
ob_end_flush();
} else {
// Otherwise prevent server from compressing the output.
header('Content-Encoding: none');
}
// Get length and close the connection.
header('Content-Length: ' . ob_get_length());
header("Connection: close");
// flush the regular buffer
ob_end_flush();
@ob_flush();
flush();
// Fix for fastcgi close connection issue.
if (function_exists('fastcgi_finish_request')) {
@fastcgi_finish_request();
}
// Prevent user abort allowing onShutdown event to run without interruptions.
if (function_exists('ignore_user_abort')) {
@ignore_user_abort(true);
}
// Close the session allowing new requests to be handled.
if (isset($this['session'])) {
$this['session']->close();
}
if ($this['config']->get('system.debugger.shutdown.close_connection', true)) {
// Flush the response and close the connection to allow time consuming tasks to be performed without leaving
// the connection to the client open. This will make page loads to feel much faster.
// FastCGI allows us to flush all response data to the client and finish the request.
$success = function_exists('fastcgi_finish_request') ? @fastcgi_finish_request() : false;
if (!$success) {
// Unfortunately without FastCGI there is no way to close the connection. We need to ask browser to
// close the connection for us.
if ($this['config']->get('system.cache.gzip')) {
// Flush gzhandler buffer if gzip setting was enabled.
ob_end_flush();
} else {
// Without gzip we have no other choice than to prevent server from compressing the output.
// This action turns off mod_deflate which would prevent us from closing the connection.
header('Content-Encoding: none');
}
// Get length and close the connection.
header('Content-Length: ' . ob_get_length());
header("Connection: close");
// Finally flush the regular buffer.
ob_end_flush();
@ob_flush();
flush();
}
}
// Run any time consuming tasks.
$this->fireEvent('onShutdown');
}
@@ -484,7 +488,7 @@ class Grav extends Container
if ($page) {
$media = $page->media()->all();
$parsed_url = parse_url(urldecode($uri->basename()));
$parsed_url = parse_url(rawurldecode($uri->basename()));
$media_file = $parsed_url['path'];

View File

@@ -3,6 +3,7 @@ namespace Grav\Common\Markdown;
use Grav\Common\GravTrait;
use Grav\Common\Uri;
use RocketTheme\Toolbox\Event\Event;
/**
* A trait to add some custom processing to the identifyLink() method in Parsedown and ParsedownExtra
@@ -15,9 +16,11 @@ trait ParsedownGravTrait
protected $base_url;
protected $pages_dir;
protected $special_chars;
protected $twig_link_regex = '/\!*\[(?:.*)\]\((\{([\{%#])\s*(.*?)\s*(?:\2|\})\})\)/';
public $completable_blocks = [];
public $continuable_blocks = [];
/**
* Initialization function to setup key variables needed by the MarkdownGravLinkTrait
*
@@ -26,8 +29,10 @@ trait ParsedownGravTrait
*/
protected function init($page, $defaults)
{
$grav = self::getGrav();
$this->page = $page;
$this->pages = self::getGrav()['pages'];
$this->pages = $grav['pages'];
$this->BlockTypes['{'] [] = "TwigTag";
$this->base_url = rtrim(self::getGrav()['base_url'] . self::getGrav()['pages']->base(), '/');
$this->pages_dir = self::getGrav()['locator']->findResource('page://');
@@ -41,8 +46,67 @@ trait ParsedownGravTrait
$this->setUrlsLinked($defaults['auto_url_links']);
$this->setMarkupEscaped($defaults['escape_markup']);
$this->setSpecialChars($defaults['special_chars']);
$grav->fireEvent('onMarkdownInitialized', new Event(['markdown' => $this]));
}
/**
* Be able to define a new Block type or override an existing one
*
* @param $type
* @param $tag
*/
public function addBlockType($type, $tag, $continuable = false, $completable = false)
{
$this->BlockTypes[$type] []= $tag;
if ($continuable) {
$this->continuable_blocks[] = $tag;
}
if ($completable) {
$this->completable_blocks[] = $tag;
}
}
/**
* Be able to define a new Inline type or override an existing one
*
* @param $type
* @param $tag
*/
public function addInlineType($type, $tag)
{
$this->InlineTypes[$type] []= $tag;
$this->inlineMarkerList .= $type;
}
/**
* Overrides the default behavior to allow for plugin-provided blocks to be continuable
*
* @param $Type
* @return bool
*/
protected function isBlockContinuable($Type)
{
$continuable = in_array($Type, $this->continuable_blocks) || method_exists($this, 'block'.$Type.'Continue');
return $continuable;
}
/**
* Overrides the default behavior to allow for plugin-provided blocks to be completable
*
* @param $Type
* @return bool
*/
protected function isBlockCompletable($Type)
{
$completable = in_array($Type, $this->completable_blocks) || method_exists($this, 'block'.$Type.'Complete');
return $completable;
}
/**
* Make the element function publicly accessible, Medium uses this to render from Twig
*
@@ -73,7 +137,7 @@ trait ParsedownGravTrait
*/
protected function blockTwigTag($Line)
{
if (preg_match('/[{%|{{|{#].*[#}|}}|%}]/', $Line['body'], $matches)) {
if (preg_match('/(?:{{|{%|{#)(.*)(?:}}|%}|#})/', $Line['body'], $matches)) {
$Block = array(
'markup' => $Line['body'],
);
@@ -145,9 +209,9 @@ trait ParsedownGravTrait
}
// if there is a media file that matches the path referenced..
if ($media && isset($media->all()[$url['path']])) {
if ($media && isset($media->all()[$path_parts['basename']])) {
// get the medium object
$medium = $media->all()[$url['path']];
$medium = $media->all()[$path_parts['basename']];
// if there is a query, then parse it and build action calls
if (isset($url['query'])) {
@@ -208,7 +272,7 @@ trait ParsedownGravTrait
if (isset($url['query'])) {
$actions = array_reduce(explode('&', $url['query']), function ($carry, $item) {
$parts = explode('=', $item, 2);
$value = isset($parts[1]) ? $parts[1] : null;
$value = isset($parts[1]) ? $parts[1] : true;
$carry[$parts[0]] = $value;
return $carry;
@@ -230,7 +294,7 @@ trait ParsedownGravTrait
if ($attrib == 'classes') {
$attrib = 'class';
}
$excerpt['element']['attributes'][$attrib] = $value;
$excerpt['element']['attributes'][$attrib] = str_replace(',', ' ', $value);
unset($actions[$key]);
}
}
@@ -245,14 +309,23 @@ trait ParsedownGravTrait
unset ($url['query']);
}
// if there is no scheme, the file is local
// if there is no scheme, the file is local and we'll need to convert that URL
if (!isset($url['scheme']) && (count($url) > 0)) {
// convert the URl is required
$excerpt['element']['attributes']['href'] = Uri::convertUrl($this->page, Uri::buildUrl($url), $type, true);
} else {
$excerpt['element']['attributes']['href'] = Uri::buildUrl($url);
}
}
return $excerpt;
}
// For extending this class via plugins
public function __call($method, $args)
{
if (isset($this->$method) === true) {
$func = $this->$method;
return call_user_func_array($func, $args);
}
}
}

View File

@@ -85,6 +85,8 @@ class Page
protected $markdown_extra;
protected $etag;
protected $last_modified;
protected $home_route;
protected $hide_home_route;
/**
* @var Page Unmodified (original) version of the page. Used for copying and moving the page.
@@ -118,6 +120,10 @@ class Page
*/
public function init(\SplFileInfo $file, $extension = null)
{
$config = self::getGrav()['config'];
$this->hide_home_route = $config->get('system.home.hide_in_urls', false);
$this->home_route = $config->get('system.home.alias');
$this->filePath($file->getPathName());
$this->modified($file->getMTime());
$this->id($this->modified().md5($this->filePath()));
@@ -132,6 +138,8 @@ class Page
$this->published();
$this->urlExtension();
// some extension logic
if (empty($extension)) {
$this->extension('.'.$file->getExtension());
@@ -473,6 +481,9 @@ class Page
// Get media
$this->media();
/** @var Config $config */
$config = self::getGrav()['config'];
// Load cached content
/** @var Cache $cache */
$cache = self::getGrav()['cache'];
@@ -481,51 +492,46 @@ class Page
$process_markdown = $this->shouldProcess('markdown');
$process_twig = $this->shouldProcess('twig');
$cache_twig = isset($this->header->cache_enable) ? $this->header->cache_enable : true;
$twig_first = isset($this->header->twig_first) ? $this->header->twig_first : false;
$twig_already_processed = false;
$cache_enable = isset($this->header->cache_enable) ? $this->header->cache_enable : $config->get('system.cache.enabled', true);
$twig_first = isset($this->header->twig_first) ? $this->header->twig_first : $config->get('system.pages.twig_first', true);
// if no cached-content run everything
if ($this->content === false) {
if ($this->content === false || $cache_enable == false) {
$this->content = $this->raw_content;
self::getGrav()->fireEvent('onPageContentRaw', new Event(['page' => $this]));
if ($twig_first) {
if ($process_twig) {
$this->processTwig();
$twig_already_processed = true;
}
if ($process_markdown) {
$this->processMarkdown();
}
if ($cache_twig) {
$this->cachePageContent();
}
// Content Processed but not cached yet
self::getGrav()->fireEvent('onPageContentProcessed', new Event(['page' => $this]));
} else {
if ($process_markdown) {
$this->processMarkdown();
}
if (!$cache_twig) {
$this->cachePageContent();
}
// Content Processed but not cached yet
self::getGrav()->fireEvent('onPageContentProcessed', new Event(['page' => $this]));
if ($process_twig) {
$this->processTwig();
$twig_already_processed = true;
}
if ($cache_twig) {
$this->cachePageContent();
}
}
// content cached, but twig cache off
}
// only markdown content cached, process twig if required and not already processed
if ($process_twig && !$cache_twig && !$twig_already_processed) {
$this->processTwig();
if ($cache_enable) {
$this->cachePageContent();
}
}
// Handle summary divider
$delimiter = self::getGrav()['config']->get('site.summary.delimiter', '===');
$delimiter = $config->get('site.summary.delimiter', '===');
$divider_pos = mb_strpos($this->content, "<p>{$delimiter}</p>");
if ($divider_pos !== false) {
$this->summary_size = $divider_pos;
@@ -582,8 +588,6 @@ class Page
{
$cache = self::getGrav()['cache'];
$cache_id = md5('page'.$this->id());
self::getGrav()->fireEvent('onPageContentProcessed', new Event(['page' => $this]));
$cache->save($cache_id, $this->content);
}
@@ -1079,10 +1083,6 @@ class Page
$this->publish_date = Utils::date2timestamp($var);
}
if ($this->publish_date === null) {
$this->publish_date = $this->date();
}
return $this->publish_date;
}
@@ -1303,8 +1303,18 @@ class Page
}
if (empty($this->route)) {
$baseRoute = null;
// calculate route based on parent slugs
$baseRoute = $this->parent ? (string) $this->parent()->route() : null;
$parent = $this->parent();
if (isset($parent)) {
if ($this->hide_home_route && $parent->route() == $this->home_route) {
$baseRoute = '';
} else {
$baseRoute = (string) $parent->route();
}
}
$this->route = isset($baseRoute) ? $baseRoute . '/'. $this->slug() : null;
if (!empty($this->routes) && isset($this->routes['default'])) {
@@ -1698,6 +1708,31 @@ class Page
return $pages->get($this->parent);
}
/**
* Gets the top parent object for this page
*
* @return Page|null the top parent page object if it exists.
*/
public function topParent()
{
$topParent = $this->parent();
if (!$topParent) {
return null;
}
while (true) {
$theParent = $topParent->parent();
if ($theParent != null && $theParent->parent() !== null) {
$topParent = $theParent;
} else {
break;
}
}
return $topParent;
}
/**
* Returns children of this page.
*
@@ -2227,7 +2262,7 @@ class Page
}
}
// publish if required, if not clear cache right before page is published
if ($this->publishDate() != $this->modified() && $this->publishDate() > time()) {
if ($this->publishDate() && $this->publishDate() && $this->publishDate() > time()) {
$this->published(false);
self::getGrav()['cache']->setLifeTime($this->publishDate());
}

View File

@@ -103,8 +103,11 @@ class Types implements \ArrayAccess, \Iterator, \Countable
'value' => 'PathName',
];
$list = [];
foreach ((array) $paths as $path) {
return Folder::all($path, $options);
$list += Folder::all($path, $options);
}
return $list;
}
}

View File

@@ -6,6 +6,7 @@ use Grav\Common\Page\Page;
use Grav\Common\Config\Config;
use RocketTheme\Toolbox\Event\EventDispatcher;
use RocketTheme\Toolbox\Event\EventSubscriberInterface;
use RocketTheme\Toolbox\File\YamlFile;
/**
* The Plugin object just holds the id and path to a plugin.
@@ -182,4 +183,26 @@ class Plugin implements EventSubscriberInterface
// Return configurations as a new data config class
return new Data($header);
}
/**
* Persists to disk the plugin parameters currently stored in the Grav Config object
*
* @param string $plugin_name The name of the plugin whose config it should store.
*
* @return true
*/
public static function saveConfig($plugin_name) {
if (!$plugin_name) {
return false;
}
$locator = Grav::instance()['locator'];
$filename = 'config://plugins/' . $plugin_name . '.yaml';
$file = YamlFile::instance($locator->findResource($filename, true, true));
$content = Grav::instance()['config']->get('plugins.' . $plugin_name);
$file->save($content);
$file->free();
return true;
}
}

View File

@@ -108,10 +108,45 @@ class ConfigServiceProvider implements ServiceProviderInterface
$files += (new ConfigFileFinder)->locateFiles($paths);
$paths = $locator->findResources('plugins://');
$files += (new ConfigFileFinder)->setBase('plugins')->locateInFolders($paths, 'languages');
$paths = static::pluginFolderPaths($paths, 'languages');
$files += (new ConfigFileFinder)->locateFiles($paths);
}
$languages = new CompiledLanguages($cache, $files, GRAV_ROOT);
return $languages->name("master-{$setup->environment}")->load();
}
/**
* Find specific paths in plugins
*
* @param $plugins
* @param $folder_path
* @return array
*/
private static function pluginFolderPaths($plugins, $folder_path)
{
$paths = [];
foreach ($plugins as $path) {
$iterator = new \DirectoryIterator($path);
/** @var \DirectoryIterator $directory */
foreach ($iterator as $directory) {
if (!$directory->isDir() || $directory->isDot()) {
continue;
}
// Path to the languages folder
$lang_path = $directory->getPathName() . '/' . $folder_path;
// If this folder exists, add it to the list of paths
if (file_exists($lang_path)) {
$paths []= $lang_path;
}
}
}
return $paths;
}
}

View File

@@ -12,33 +12,7 @@ class ErrorServiceProvider implements ServiceProviderInterface
{
public function register(Container $container)
{
// Setup Whoops-based error handler
$errors = new Errors;
$error_page = new PrettyPageHandler;
$error_page->setPageTitle('Crikey! There was an error...');
$error_page->setEditor('sublime');
$error_page->addResourcePath(GRAV_ROOT . '/system/assets');
$error_page->addCustomCss('whoops.css');
$json_page = new JsonResponseHandler;
$json_page->onlyForAjaxRequests(true);
$errors->pushHandler($error_page, 'pretty');
$errors->pushHandler(new PlainTextHandler, 'text');
$errors->pushHandler($json_page, 'json');
$logger = $container['log'];
$errors->pushHandler(function (\Exception $exception, $inspector, $run) use ($logger) {
try {
$logger->addCritical($exception->getMessage() . ' - Trace: ' . $exception->getTraceAsString());
} catch (\Exception $e) {
echo $e;
}
}, 'log');
$errors->register();
$container['errors'] = $errors;
}
}

View File

@@ -36,18 +36,23 @@ class Session extends \RocketTheme\Toolbox\Session\Session
}
if ($config->get('system.session.enabled') || $is_admin) {
// Define session service.
parent::__construct(
$session_timeout,
$session_path
);
$domain = $uri->host();
if ($domain == 'localhost') {
$domain = '';
}
$secure = $config->get('system.session.secure', false);
$httponly = $config->get('system.session.httponly', true);
$unique_identifier = GRAV_ROOT;
$this->setName($config->get('system.session.name', 'grav_site') . '-' . substr(md5($unique_identifier), 0, 7) . ($is_admin ? '-admin' : ''));
$this->start();
setcookie(session_name(), session_id(), time() + $session_timeout, $session_path);
setcookie(session_name(), session_id(), time() + $session_timeout, $session_path, $domain, $secure, $httponly);
}
}
}

View File

@@ -20,4 +20,26 @@ class Theme extends Plugin
parent::__construct($name, $grav, $config);
}
/**
* Persists to disk the theme parameters currently stored in the Grav Config object
*
* @param string $theme_name The name of the theme whose config it should store.
*
* @return true
*/
public static function saveConfig($theme_name) {
if (!$theme_name) {
return false;
}
$locator = Grav::instance()['locator'];
$filename = 'config://themes/' . $theme_name . '.yaml';
$file = YamlFile::instance($locator->findResource($filename, true, true));
$content = Grav::instance()['config']->get('themes.' . $theme_name);
$file->save($content);
$file->free();
return true;
}
}

View File

@@ -80,7 +80,10 @@ class Twig
$active_language = $language->getActive();
$language_append = $active_language ? '/'.$active_language : '';
$language_append = '';
if ($language->getDefault() != $active_language || $config->get('system.languages.include_default_lang') === true) {
$language_append = $active_language ? '/' . $active_language : '';
}
// handle language templates if available
if ($language->enabled()) {

View File

@@ -20,6 +20,10 @@ trait WriteCacheFileTrait
*/
protected function writeCacheFile($file, $content)
{
if (empty($file)) {
return;
}
if (!isset(self::$umask)) {
self::$umask = self::getGrav()['config']->get('system.twig.umask_fix', false);
}

View File

@@ -46,7 +46,7 @@ class Uri
// set the base
if (isset($_SERVER['HTTPS'])) {
$base = (@$_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://';
$base = (strtolower(@$_SERVER['HTTPS']) == 'on') ? 'https://' : 'http://';
} else {
$base = 'http://';
}
@@ -170,7 +170,7 @@ class Uri
if (strpos($bit, $delimiter) !== false) {
$param = explode($delimiter, $bit);
if (count($param) == 2) {
$plain_var = filter_var(urldecode($param[1]), FILTER_SANITIZE_STRING);
$plain_var = filter_var(rawurldecode($param[1]), FILTER_SANITIZE_STRING);
$this->params[$param[0]] = $plain_var;
}
} else {
@@ -206,7 +206,7 @@ class Uri
*/
public function route($absolute = false, $domain = false)
{
return urldecode(($absolute ? $this->rootUrl($domain) : '') . '/' . implode('/', $this->paths));
return rawurldecode(($absolute ? $this->rootUrl($domain) : '') . '/' . implode('/', $this->paths));
}
/**
@@ -268,7 +268,7 @@ class Uri
public function param($id)
{
if (isset($this->params[$id])) {
return urldecode($this->params[$id]);
return rawurldecode($this->params[$id]);
} else {
return false;
}
@@ -545,8 +545,8 @@ class Uri
if (file_exists($full_path)) {
// do nothing
} elseif (file_exists(urldecode($full_path))) {
$full_path = urldecode($full_path);
} elseif (file_exists(rawurldecode($full_path))) {
$full_path = rawurldecode($full_path);
} else {
return $normalized_url;
}

View File

@@ -453,6 +453,36 @@ abstract class Utils
* @return string the nonce string
*/
private static function generateNonceString($action, $plusOneTick = false)
{
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
$username = '';
if (isset(self::getGrav()['user'])) {
$user = self::getGrav()['user'];
$username = $user->username;
}
$username .= $ip;
$token = session_id();
$i = self::nonceTick();
if ($plusOneTick) {
$i++;
}
return ( $i . '|' . $action . '|' . $username . '|' . $token . '|' . self::getGrav()['config']->get('security.salt'));
}
//Added in version 1.0.8 to ensure that existing nonces are not broken.
//TODO: to be removed
private static function generateNonceStringOldStyle($action, $plusOneTick = false)
{
if (isset(self::getGrav()['user'])) {
$user = self::getGrav()['user'];
@@ -463,14 +493,11 @@ abstract class Utils
} else {
$username = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
}
$token = session_id();
$i = self::nonceTick();
if ($plusOneTick) {
$i++;
}
return ( $i . '|' . $action . '|' . $username . '|' . $token . '|' . self::getGrav()['config']->get('security.salt'));
}
@@ -509,6 +536,20 @@ abstract class Utils
return static::$nonces[$action];
}
//Added in version 1.0.8 to ensure that existing nonces are not broken.
//TODO: to be removed
public static function getNonceOldStyle($action, $plusOneTick = false)
{
// Don't regenerate this again if not needed
if (isset(static::$nonces[$action])) {
return static::$nonces[$action];
}
$nonce = md5(self::generateNonceStringOldStyle($action, $plusOneTick));
static::$nonces[$action] = $nonce;
return static::$nonces[$action];
}
/**
* Verify the passed nonce for the give action
*
@@ -519,6 +560,11 @@ abstract class Utils
*/
public static function verifyNonce($nonce, $action)
{
//Safety check for multiple nonces
if (is_array($nonce)) {
$nonce = array_shift($nonce);
}
//Nonce generated 0-12 hours ago
if ($nonce == self::getNonce($action)) {
return true;
@@ -530,6 +576,21 @@ abstract class Utils
return true;
}
//Added in version 1.0.8 to ensure that existing nonces are not broken.
//TODO: to be removed
//Nonce generated 0-12 hours ago
if ($nonce == self::getNonceOldStyle($action)) {
return true;
}
//Nonce generated 12-24 hours ago
$plusOneTick = true;
if ($nonce == self::getNonceOldStyle($action, $plusOneTick)) {
return true;
}
//End TODO: to be removed
//Invalid nonce
return false;
}

View File

@@ -93,7 +93,7 @@ class CleanCommand extends Command
'vendor/maximebf/debugbar/bower.json',
'vendor/maximebf/debugbar/composer.json',
'vendor/maximebf/debugbar/.bowerrc',
'vendor/maximebf/debugbar/src/Debugbar/Resources/vendor',
'vendor/maximebf/debugbar/src/DebugBar/Resources/vendor',
'vendor/maximebf/debugbar/demo',
'vendor/maximebf/debugbar/docs',
'vendor/maximebf/debugbar/tests',

View File

@@ -35,8 +35,6 @@ class SandboxCommand extends ConsoleCommand
protected $files = array(
'/.dependencies',
'/.htaccess',
'/nginx.conf',
'/web.config',
'/user/config/site.yaml',
'/user/config/system.yaml',
);
@@ -45,16 +43,18 @@ class SandboxCommand extends ConsoleCommand
* @var array
*/
protected $mappings = array(
'/.editorconfig' => '/.editorconfig',
'/.gitignore' => '/.gitignore',
'/CHANGELOG.md' => '/CHANGELOG.md',
'/LICENSE.txt' => '/LICENSE.txt',
'/README.md' => '/README.md',
'/index.php' => '/index.php',
'/composer.json' => '/composer.json',
'/bin' => '/bin',
'/system' => '/system',
'/vendor' => '/vendor',
'/.editorconfig' => '/.editorconfig',
'/.gitignore' => '/.gitignore',
'/CHANGELOG.md' => '/CHANGELOG.md',
'/LICENSE.txt' => '/LICENSE.txt',
'/README.md' => '/README.md',
'/CONTRIBUTING.md' => '/CONTRIBUTING.md',
'/index.php' => '/index.php',
'/composer.json' => '/composer.json',
'/bin' => '/bin',
'/system' => '/system',
'/vendor' => '/vendor',
'/webserver-configs' => '/webserver-configs',
);
/**
@@ -162,7 +162,7 @@ class SandboxCommand extends ConsoleCommand
$to = $this->destination . $target;
$this->output->writeln(' <cyan>' . $source . '</cyan> <comment>-></comment> ' . $to);
Folder::rcopy($from, $to);
@Folder::rcopy($from, $to);
}
}

View File

@@ -68,6 +68,12 @@ class IndexCommand extends ConsoleCommand
InputOption::VALUE_NONE,
'Filters the results to Updatable Themes and Plugins only'
)
->addOption(
'installed-only',
'I',
InputOption::VALUE_NONE,
'Filters the results to only the Themes and Plugins you have installed'
)
->addOption(
'sort',
's',
@@ -176,7 +182,14 @@ class IndexCommand extends ConsoleCommand
unset($data['plugins']);
}
if ($this->options['filter'] || $this->options['updates-only'] || $this->options['desc']) {
$filter = [
$this->options['filter'],
$this->options['installed-only'],
$this->options['updates-only'],
$this->options['desc']
];
if (count(array_filter($filter))) {
foreach ($data as $type => $packages) {
foreach ($packages as $slug => $package) {
$filter = true;
@@ -186,6 +199,12 @@ class IndexCommand extends ConsoleCommand
$filter = preg_grep('/(' . (implode('|', $this->options['filter'])) . ')/i', [$slug, $package->name]);
}
// Filtering updatables only
if ($this->options['installed-only'] && $filter) {
$method = ucfirst(preg_replace("/s$/", '', $package->package_type));
$filter = $this->gpm->{'is' . $method . 'Installed'}($package->slug);
}
// Filtering updatables only
if ($this->options['updates-only'] && $filter) {
$method = ucfirst(preg_replace("/s$/", '', $package->package_type));

View File

@@ -82,6 +82,18 @@ class SelfupgradeCommand extends ConsoleCommand
$remote = $this->upgrader->getRemoteVersion();
$release = strftime('%c', strtotime($this->upgrader->getReleaseDate()));
if (!$this->upgrader->meetsRequirements()) {
$this->output->writeln("");
$this->output->writeln("<red>ATTENTION:</red>");
$this->output->writeln(" Grav has increased the minimum PHP requirement.");
$this->output->writeln(" You are currently running PHP <red>" . PHP_VERSION . "</red>, but PHP <green>" . GRAV_PHP_MIN . "</green> is required.");
$this->output->writeln(" Additional information: <white>http://getgrav.org/blog/changing-php-requirements-to-5.5</white>");
$this->output->writeln("");
$this->output->writeln("Selfupgrade aborted.");
$this->output->writeln("");
exit;
}
if (!$this->upgrader->isUpgradable()) {
$this->output->writeln("You are already running the latest version of Grav (v" . $local . ") released on " . $release);
exit;

View File

@@ -0,0 +1,8 @@
:8080
gzip
fastcgi / 127.0.0.1:9000 php
rewrite {
regexp .*
ext /
to /index.php?_url={uri}
}

View File

@@ -44,7 +44,7 @@ RewriteRule .* index.php [L]
## Begin - Security
# Block all direct access for these folders
RewriteRule ^(.git|cache|bin|logs|backup)/(.*) error [F]
RewriteRule ^(.git|cache|bin|logs|backup|webserver-configs)/(.*) error [F]
# Block access to specific file types for these system folders
RewriteRule ^(system|vendor)/(.*)\.(txt|xml|md|html|yaml|php|pl|py|cgi|twig|sh|bat)$ error [F]
# Block access to specific file types for these user folders
@@ -54,7 +54,7 @@ RewriteRule \.md$ error [F]
# Block all direct access to files and folders beginning with a dot
RewriteRule (^\.|/\.) - [F]
# Block access to specific files in the root folder
RewriteRule ^(LICENSE.txt|composer.lock|composer.json|nginx.conf|web.config|htaccess.txt|\.htaccess)$ error [F]
RewriteRule ^(LICENSE.txt|composer.lock|composer.json|\.htaccess)$ error [F]
## End - Security
</IfModule>