Compare commits

...

441 Commits

Author SHA1 Message Date
Andy Miller
7b6cadbeeb Merge branch 'release/1.0.10' 2016-02-11 15:37:25 -07:00
Andy Miller
bf91d13222 version update 2016-02-11 15:37:14 -07:00
Andy Miller
0bd60d24b7 updated libraries 2016-02-11 15:28:57 -07:00
Andy Miller
864f14344e Add method to get contentMeta and initialize content if needed 2016-02-11 12:59:46 -07:00
Matias Griese
81e25e314b Hide streams blueprint from admin 2016-02-11 20:55:48 +02:00
Flavio Copes
028554dbf8 Fix languages in Grav 2016-02-11 16:27:34 +01:00
Flavio Copes
bda8de3076 Typo 2016-02-11 16:27:34 +01:00
Andy Miller
36be17617d use old cache_id mechanism for safety 2016-02-10 22:48:04 -07:00
Andy Miller
bb23f6157f Support content level meta data .. so you can store things in cache alongside content 2016-02-10 22:44:54 -07:00
Flavio Copes
39ac423bce Merge pull request #665 from gracix/Add-Language-Ja
Add Ja language file.
2016-02-09 08:23:50 +01:00
Takefumi Ota
39b1eed912 Add Ja language file. 2016-02-09 10:27:57 +09:00
Andy Miller
360286f3d4 moved build status 2016-02-06 17:53:43 -07:00
Djamil Legato
88c84ed028 Updated auth token (and kicking of unit tests) 2016-02-05 16:10:51 -08:00
Djamil Legato
f03a7ced06 Check if php version starts with 5.6 for the release 2016-02-05 15:32:51 -08:00
Andy Miller
5605b69844 Merge branch 'release/1.0.9' into develop 2016-02-05 16:00:23 -07:00
Andy Miller
652c5cd4bd Merge branch 'release/1.0.9' 2016-02-05 16:00:22 -07:00
Andy Miller
bfe3a7750e version update 2016-02-05 15:59:40 -07:00
Andy Miller
1d23d29485 Various PSR fixes 2016-02-05 12:39:04 -07:00
Andy Miller
3bec73049b Revert "use ConsoleCommand"
This reverts commit 990663cd60.
2016-02-05 12:35:32 -07:00
Andy Miller
cd7366ca8d removed unused stuff 2016-02-05 12:35:21 -07:00
Andy Miller
63812cc6b1 Use strict boolean compare 2016-02-05 12:26:29 -07:00
Andy Miller
de9b6df2c7 removed TODOs.. 2016-02-05 12:17:08 -07:00
Andy Miller
990663cd60 use ConsoleCommand 2016-02-05 12:11:57 -07:00
Andy Miller
9701908aaa updated changelog 2016-02-05 11:54:05 -07:00
Flavio Copes
49facba84a Composer update 2016-02-05 18:01:50 +01:00
Flavio Copes
7953271265 Linting fixes 2016-02-05 18:01:28 +01:00
Flavio Copes
3f3adfc5c6 Moved Parsedown tests to tests/unit/Grav/Common/Markdown/ParsedownTest.php 2016-02-05 16:59:51 +01:00
Andy Miller
b6c289067f Translations from crowdin 2016-02-04 16:22:32 -07:00
Djamil Legato
71176f52e9 Added Slack notifications 2016-02-04 11:24:45 -08:00
Flavio Copes
0d97710ffb Merge pull request #658 from Vivalldi/develop
Add composer test command for windows
2016-02-04 09:57:37 +01:00
Tyler Cosgrove
1d65344aa5 Add composer test command for windows
Windows is dumb... gotta use those backslashes
2016-02-03 21:16:28 -05:00
Andy Miller
82a5afa732 Fixed an issue in code and in the tests for untouched image file locations 2016-02-03 12:48:22 -07:00
Andy Miller
72836982e6 various fixes for broken tests 2016-02-02 22:45:42 -07:00
Andy Miller
d12c8b10a2 Merge branch 'feature/converturl-rewrite' into develop 2016-02-02 22:02:21 -07:00
Andy Miller
b208ced437 various fixes 2016-02-02 22:01:56 -07:00
Andy Miller
c4e72819a6 various improvements to image handling .. still some places to fix 2016-02-02 18:48:39 -07:00
Andy Miller
3541ea8ec8 some fixes for image processing 2016-02-02 15:22:25 -07:00
Andy Miller
e4cda6383f Init the URI object 2016-02-02 10:34:11 -07:00
Andy Miller
3cc6700845 Init the URI object 2016-02-02 10:33:25 -07:00
Flavio Copes
36ec6ad513 Fix tests 2016-02-02 15:46:55 +01:00
Flavio Copes
aec95f3fa6 More Pages class tests 2016-02-02 15:31:46 +01:00
Flavio Copes
1fe190998c Add testing page 2016-02-02 15:31:37 +01:00
Flavio Copes
aeca73bdd3 Add "tests" stream location 2016-02-02 15:31:29 +01:00
Flavio Copes
848497774b 🎨 format and PHPDoc Twig folder 2016-02-02 11:09:22 +01:00
Andy Miller
1d440035a4 Added some language tests 2016-02-01 22:53:24 -07:00
Andy Miller
51104a1d55 Added language support to the initializeFromUrl() method 2016-02-01 22:53:13 -07:00
Andy Miller
6222b22e2a Added a root-level test 2016-02-01 19:55:22 -07:00
Andy Miller
b332e497ab reordered 2016-02-01 19:44:55 -07:00
Andy Miller
75419120be fix for externals with absolute_urls enabled 2016-02-01 19:44:43 -07:00
Andy Miller
94feeac119 fixed a conflict with environment and host 2016-02-01 19:20:03 -07:00
Andy Miller
cf058bb662 bit more progress on links.. images are fubar though 2016-02-01 18:59:58 -07:00
Andy Miller
1e56e92502 Merge branch 'release/converturl_rewrite' into feature/converturl-rewrite 2016-02-01 18:32:52 -07:00
Andy Miller
2025e7c28a most page links working 2016-02-01 18:31:48 -07:00
Djamil Legato
1d08090560 Use more reliable and cross server $_SERVER to retrieve the accepted content type 2016-02-01 16:45:13 -08:00
Djamil Legato
485df7517d Merge branch 'develop' of https://github.com/getgrav/grav into develop 2016-02-01 16:39:04 -08:00
Djamil Legato
2a4030e399 Whoops: Serve JSON errors when the Content-Type Request is application/json, rather than blindly rely only on HTTP_X_REQUESTED_WITH 2016-02-01 16:38:58 -08:00
Andy Miller
5743d7e048 commented out some root level test failures that need to be addressed 2016-02-01 13:52:24 -07:00
Djamil Legato
3b8da60cf9 Merge branch 'develop' of https://github.com/getgrav/grav into develop 2016-02-01 12:26:08 -08:00
Djamil Legato
49a7b11e2b Travis potential fix for PRs and tests runner 2016-02-01 12:26:03 -08:00
Andy Miller
e5d255accd Merge branch 'develop' of https://github.com/getgrav/grav into develop 2016-02-01 11:23:02 -07:00
Andy Miller
0e6bf74db1 renamed and added some more tests 2016-02-01 11:22:53 -07:00
Flavio Copes
9d67f1ac33 Fix assertSame param order 2016-02-01 18:55:33 +01:00
Flavio Copes
8c738d0687 Merge pull request #651 from Vivalldi/develop
Server config updates
2016-02-01 18:02:07 +01:00
Tyler Cosgrove
7d35475104 LICENSE renamed to LICENSE.txt 2016-02-01 11:48:12 -05:00
Tyler Cosgrove
1f5641069b Merge pull request #1 from getgrav/develop
Sync Fork
2016-02-01 11:44:48 -05:00
Flavio Copes
f8eeac70a2 Only initialize new pages location once in tests 2016-02-01 17:19:52 +01:00
Flavio Copes
1279cb4ef3 Add Unit module available methods for future usage 2016-02-01 17:19:34 +01:00
Flavio Copes
2934157fb4 Add pages content 2016-02-01 15:18:35 +01:00
Flavio Copes
ddaca8a312 Merge pull request #652 from getgrav/feature/fix-testing-separate-pages-folder
Fix testing separate pages folder
2016-02-01 15:08:48 +01:00
Flavio Copes
57cd5c9e6f Add second set of pages to test 2016-02-01 14:37:19 +01:00
Flavio Copes
31940c03b1 Disable system cache 2016-02-01 14:33:31 +01:00
Andy Miller
56f267ec79 reordered tests 2016-01-31 22:09:27 -07:00
Andy Miller
5f6b09b032 fixed a markdown test 2016-01-31 21:54:57 -07:00
Andy Miller
7de21b1f52 went back to dev-master of Parsedown until release 2016-01-31 21:54:08 -07:00
Andy Miller
9c0deea6c8 added some tests that test various URL and subduer scenarios 2016-01-31 19:06:00 -07:00
Andy Miller
62dbf9b02b Initiate the Uri->init() in bootstrap stage 2016-01-31 19:05:37 -07:00
Andy Miller
0ddfd4c546 value is getting overridden so not needed here 2016-01-31 19:05:15 -07:00
Andy Miller
5abb4060f3 moved grav-based base_uri values into Uri->init() 2016-01-31 19:04:58 -07:00
Tyler Cosgrove
9ba4ced65d Extensive update.
Simplify a few blocks into one.
2016-01-31 12:02:41 -05:00
Tyler Cosgrove
49c4dd197e Deny access to tests folder 2016-01-31 11:48:53 -05:00
Tyler Cosgrove
3d830fb608 Deny access to tests folder 2016-01-31 11:47:53 -05:00
Tyler Cosgrove
47b5cd7db7 Deny access to tests folder 2016-01-31 11:46:43 -05:00
Flavio Copes
d4aeb8e223 Merge pull request #640 from Vivalldi/patch-2
Fix for #612
2016-01-31 15:27:46 +01:00
Flavio Copes
c76be3c4dd Merge pull request #649 from Vivalldi/patch-3
Change user to USER - Easy to note replacement
2016-01-31 15:27:08 +01:00
Tyler Cosgrove
b17a3780ab Change user to USER - Easy to note replacement
Primarily going to be used for install script but it makes it more apparent that someone may need to change their root path.
2016-01-30 18:15:28 -05:00
Flavio Copes
b612347ee7 🚧 Drop unneeded pages unset. Remove second set of pages test, currently not working 2016-01-30 12:20:07 +01:00
Andy Miller
06a76579db more tests 2016-01-30 00:06:15 -07:00
Andy Miller
13db4025b6 reset the pages 2016-01-29 21:32:34 -07:00
Andy Miller
07fa7da920 renaming some tests 2016-01-29 21:32:16 -07:00
Andy Miller
0be127eda7 Merge branch 'feature/page_level_ssl' into develop 2016-01-29 17:40:48 -07:00
Andy Miller
fe01f29872 slug and directory relative links 2016-01-29 17:40:20 -07:00
Andy Miller
a1dca420e4 More progress with tests using page references. 2016-01-29 17:32:44 -07:00
Djamil Legato
2585512946 Typo 2016-01-29 13:33:57 -08:00
Andy Miller
7a1e10ee13 Merge branch 'develop' into feature/page_level_ssl 2016-01-29 14:33:39 -07:00
Andy Miller
99c16d5514 fixes for merge 2016-01-29 14:31:57 -07:00
Djamil Legato
ee99cb7990 Disable xdebug only on non hhvm envs 2016-01-29 13:30:26 -08:00
Djamil Legato
c2fb252a6e Disable xdebug on Travis 2016-01-29 13:27:43 -08:00
Djamil Legato
7d00941876 Updated hipchat notification 2016-01-29 13:23:02 -08:00
Djamil Legato
db59caa764 Added automatic Unit Tests runner in Travis 2016-01-29 12:34:52 -08:00
Djamil Legato
4218e3f81b Removed extra quotes 2016-01-29 12:10:47 -08:00
Djamil Legato
11a14aed76 Updated composer.lock 2016-01-29 12:06:42 -08:00
Djamil Legato
ae3ca8aa2d 😱 Fixed missing variable 2016-01-29 10:26:27 -08:00
Djamil Legato
0bce4a95b7 Refractored Metadata generator. [BC included]
Metadata are now only flat array. To use social metas, such as open graph, specify the key property with the separator in it (ie, 'og:title'). Grav will automatically treat it as social media and render with both `property` and `name`.
Any other meta will be regularly treated as `name` (ie, 'title' or 'description')
2016-01-29 10:13:14 -08:00
Flavio Copes
60ab5cefd0 🚧 Reset instances, children and routes properties in Pages::init() prior to calling buildPages()
Useful when calling Pages::init() multiple times, or the properties are
never reset and the subsequent buildPages() calls fail
2016-01-29 18:32:52 +01:00
Flavio Copes
793f14c3e0 📚 PHPDoc 2016-01-29 18:32:52 +01:00
Flavio Copes
bb1e49dd8e Return $this in Page constructor and Page::init() to allow method chaining 2016-01-29 18:32:52 +01:00
Flavio Copes
4108c7710b First Pages testing in place with first simple site stub structure provided under tests/fake 2016-01-29 18:32:52 +01:00
Flavio Copes
3fb684d608 🚧 Add error log for tests 2016-01-29 18:32:52 +01:00
Flavio Copes
e2d00bec41 Add tear down method 2016-01-29 18:32:52 +01:00
Flavio Copes
aa4fb96b8b Drop generated files, ignored 2016-01-29 18:32:52 +01:00
Flavio Copes
c307f63e1f Cleanup tests 2016-01-29 18:32:52 +01:00
Flavio Copes
1494247c85 Tests code cleanup 2016-01-29 18:32:52 +01:00
Andy Miller
d6b8ae6297 Merge branch 'develop' into feature/page_level_ssl
# Conflicts:
#	system/src/Grav/Common/Markdown/ParsedownGravTrait.php
#	system/src/Grav/Common/Uri.php
2016-01-29 10:30:47 -07:00
Andy Miller
d3202b3210 Merge branch 'feature/proxy_support' into develop 2016-01-28 10:37:06 -07:00
Andy Miller
a08b5a1863 Added proxy_url to config blueprints 2016-01-28 10:34:50 -07:00
Andy Miller
1f75e014d3 added example 2016-01-28 10:30:24 -07:00
Flavio Copes
19891408db 🎨 Code cleanup and PHPDoc 2016-01-28 17:33:23 +01:00
Flavio Copes
57c4f13e53 🎨 PHPDoc 2016-01-28 17:13:19 +01:00
Flavio Copes
4854c72cbb 🐛 Fix typo 2016-01-28 13:51:07 +01:00
Flavio Copes
d440739b8b 🎨 Adjust spacing and PHPDoc 2016-01-28 13:32:18 +01:00
Flavio Copes
2d49054a95 🎨 Fix spacing and code formatting 2016-01-28 11:34:33 +01:00
Flavio Copes
2fb22d813f 🎨 Fix spacing and code formatting 2016-01-28 11:21:17 +01:00
Flavio Copes
6c02bf0c70 🎨 Fix spacing and code formatting 2016-01-28 11:20:26 +01:00
Flavio Copes
172600415d 🎨 Fix spacing and code formatting 2016-01-28 11:18:17 +01:00
Flavio Copes
c55b032928 🎨 Fix spacing and code formatting 2016-01-28 11:11:54 +01:00
Flavio Copes
1d79ef60c3 🎨 PHPDoc and type hints, code style 2016-01-28 10:59:49 +01:00
Flavio Copes
e279817839 🐛 Lookup the correct property for the home route 2016-01-28 10:59:22 +01:00
Flavio Copes
c8983bf7db 🎨 PHPDoc 2016-01-28 10:35:34 +01:00
Flavio Copes
ab5233032d 🎨 Correct inflector method call 2016-01-28 10:31:14 +01:00
Flavio Copes
535e3c982d 🎨 PHPDoc and coding style 2016-01-28 10:29:56 +01:00
Flavio Copes
2d5f721301 🎨 Improve type hints and coding style 2016-01-28 09:52:30 +01:00
Andy Miller
5c746f869a fix for curl 2016-01-27 17:45:58 -07:00
Andy Miller
4485aa3109 remove tests folder when running 'clean' command 2016-01-27 17:17:29 -07:00
Andy Miller
b8437fbd01 Added support for proxy_url to enable GPM behind proxy servers #639 2016-01-27 17:15:39 -07:00
Andy Miller
7e20ef5dd6 Added start of Markdown tests 2016-01-27 15:49:52 -07:00
Andy Miller
04116b3a37 don't process links on special protocols 2016-01-27 14:00:45 -07:00
Andy Miller
086f791c9f removed block shortcode handler, moved to shortcode-core plugin 2016-01-27 14:00:17 -07:00
Andy Miller
86c22c2e29 Merge branch 'develop' of https://github.com/getgrav/grav into develop 2016-01-27 11:45:46 -07:00
Andy Miller
95241da47c don't iterate over empty redirects/routes 2016-01-27 11:45:41 -07:00
Andy Miller
683b8a2848 if an empty string is passed to array, return null 2016-01-27 11:45:18 -07:00
Andy Miller
8dbe06941c comment out default routes/aliases from system/config/site.yaml 2016-01-27 11:44:46 -07:00
Tyler Cosgrove
af2e416ea1 Fix for #612 2016-01-27 13:25:42 -05:00
Flavio Copes
e576b05078 🎨 Add use statements. Add docblocks. Improve code readability and type hints 2016-01-27 15:57:39 +01:00
Flavio Copes
78c6d60655 🎨 Fix the return type for better type hinting 2016-01-27 15:49:14 +01:00
Flavio Copes
cbb1cc2b85 Test using Streams in Assets::addDir() 2016-01-27 12:09:04 +01:00
Flavio Copes
8a3636d10f 🐛 Fix Assets::addDir() (add addCssDir/addJsDir) to work as expected
Was looking up assets in the /assets folder, which is reserved for
Grav-compiled assets.

Now
- Looks up paths from the Grav ROOT_DIR or from a stream location
- Internally uses Assets::addJs() and Assets::addJs() instead of
directly accessing the assets arrays
- Removed the file extension determination effort already done in
Assets::add(), use Assets::add() instead
2016-01-27 12:08:41 +01:00
Flavio Copes
2721e681ef Test Assets::addDirCss(), Assets::addDirJs(), Assets::addDir() 2016-01-27 11:46:53 +01:00
Flavio Copes
8a41b2e08d 🎨 Move similar methods near each other. 2016-01-27 11:23:48 +01:00
Flavio Copes
dec78b9cbd Test Assets::resetJs() and Assets::resetCss()
Also fix closing parentheses. Added PHPDoc
2016-01-27 10:51:04 +01:00
Flavio Copes
7ab75811ad 📚 Drop old link in README 2016-01-27 10:27:49 +01:00
Flavio Copes
15043e1a11 🐛 In Assets::reset() also reset the inline CSS and inline JS arrays 2016-01-27 10:27:24 +01:00
Flavio Copes
4ef5236a53 Test Assets::registerCollection() 2016-01-27 10:26:03 +01:00
Flavio Copes
2a06cfc5e2 Test Assets::reset() 2016-01-27 10:25:53 +01:00
Flavio Copes
60876f2f09 Test Assets::exists() 2016-01-27 10:24:57 +01:00
Flavio Copes
74fdca79f0 Test Assets::getCollections() 2016-01-27 10:24:47 +01:00
Flavio Copes
c3c7c78e46 Test Assets::getCss() and Assets::getJs() 2016-01-27 09:25:07 +01:00
Andy Miller
24a5c2c03c Fix for #610 when you have an array of just empty string [''] 2016-01-26 21:34:36 -07:00
Andy Miller
9113c86196 Add other method signature items to internal lookup hash 2016-01-26 17:35:16 -07:00
Andy Miller
06b993181c typo in buildRootPath() after refactor 2016-01-26 17:34:38 -07:00
Andy Miller
a579544130 Missed one error 2016-01-26 15:09:31 -07:00
Andy Miller
a8bfa88cac Fix URITest with static methods 2016-01-26 15:08:52 -07:00
Andy Miller
d1b24d0077 Merge branch 'develop' of https://github.com/getgrav/grav into develop 2016-01-26 11:25:14 -07:00
Andy Miller
8d93df1633 updated lock file 2016-01-26 11:24:54 -07:00
Flavio Copes
ef095d4fc0 📚 Drop IRC, add link to gitter 2016-01-26 19:23:58 +01:00
Andy Miller
1df6173041 Merge pull request #588 from getgrav/feature/introduce-testing
Introduce testing
2016-01-26 10:54:15 -07:00
Andy Miller
fb50c4a4f0 Merge pull request #623 from getgrav/feature/fix-loading-js-and-css-from-collections
Fix loading js and css from collections
2016-01-26 10:53:49 -07:00
Flavio Copes
febe3123dd Use new jQuery filename 2016-01-26 18:02:27 +01:00
Flavio Copes
23ad20ed13 Test addAsyncJs addInlineCss, addInlineJs 2016-01-26 18:02:03 +01:00
Flavio Copes
bce084841e Ⓜ️ Merge branch 'develop' into feature/introduce-testing 2016-01-26 17:36:12 +01:00
Flavio Copes
172236e58d 🚧 Rename jquery-2.2.0.min.js to jquery-2.x.min.js
When stored in the user config, configuration for collections might
still reference old shipped releases. We move to jquery-2.x.min.js for
all future 2.x releases, and we'll have a jquery-3.x.min.js when it's
shipped.
2016-01-26 13:24:29 +01:00
Flavio Copes
b848f98481 🆙 Update Twig to 1.24. Up composer.lock 2016-01-26 13:06:28 +01:00
Djamil Legato
a69e7ee7cf 🔙 Restored jQuery 2.1.4 for Backward Compatibility 2016-01-25 10:52:32 -08:00
Flavio Copes
e5493573d5 🐛 Also accept a single group as a string instead of requiring an array
In addition to

```yaml
groups:
  - a-group
```

also accept

```yaml
groups: a-group
```

syntax.
2016-01-25 17:11:09 +01:00
Flavio Copes
bdbc14b9c1 🐛 If a user belongs to more than one group, if one group gives us a permission we end the loop and take that permission for granted 2016-01-25 16:40:05 +01:00
Flavio Copes
f82b40ef49 Merge branch 'develop' into feature/fix-loading-js-and-css-from-collections 2016-01-25 09:34:01 +01:00
Flavio Copes
7958db6a17 Merge branch 'develop' into feature/introduce-testing 2016-01-25 09:07:00 +01:00
Andy Miller
ed8cd7f30e Merge pull request #632 from robwent/develop
fix for #631
2016-01-24 20:41:16 -07:00
Robert Went
43f11f5d49 Removing bat's for pull 2016-01-25 02:36:45 +00:00
Robert Went
5a1fa1025d fixes #631 2016-01-25 02:26:24 +00:00
Robert Went
879f0815cb Merge branch 'develop' of https://github.com/robwent/grav into develop 2016-01-25 02:24:52 +00:00
Robert Went
bff84ae8d5 makes cli commands available on windows machines from site root 2016-01-25 02:24:24 +00:00
Andy Miller
4e0db8e540 Merge pull request #622 from getgrav/feature/fix-Append-URL-extension-home-link
Remove any URL extension for the home link
2016-01-24 18:36:03 -07:00
Andy Miller
85ff412768 Merge pull request #624 from getgrav/feature/update-jquery
Update jQuery to 2.2.0
2016-01-24 18:35:37 -07:00
Andy Miller
2b695a985d Merge pull request #630 from getgrav/feature/drop-useless-default-hash-fallback
💫 Drop useless hash fallback, as we always have a system.security.default_hash set
2016-01-24 18:29:59 -07:00
Flavio Copes
a1a75954ae 💫 Drop useless hash fallback, as we always have a system.security.default_hash set 2016-01-24 21:15:07 +01:00
Flavio Copes
c8a5e846c1 Fix permissions when the user has no access level set at all 2016-01-24 20:50:47 +01:00
Flavio Copes
515f257ee3 Update jQuery to 2.2.0 2016-01-22 18:25:24 +01:00
Flavio Copes
71795fd775 Add tests/_support/_generated/* and tests/cache/* to .gitignore 2016-01-22 18:10:06 +01:00
Flavio Copes
8cda9a08da Improve Assets class code style 2016-01-22 13:10:33 +01:00
Flavio Copes
684503245c Call addCss & addJs instead of add(), as otherwise it will lose group and loading information 2016-01-22 12:59:22 +01:00
Flavio Copes
77c8458fbf 🐛 Fix addJs and addCSS problem
Changes supported by tests in
https://github.com/getgrav/grav/commit/27af9432e0fa9a7abb2b6a2e3f3a6f6d1
55a37e9
2016-01-22 10:43:41 +01:00
Flavio Copes
7f7ba5306d Add test info to readme 2016-01-22 10:39:36 +01:00
Flavio Copes
612e2126ee 🚨 Initialize assets in tests 2016-01-22 10:39:24 +01:00
Flavio Copes
dd43b3b7da 🚨 Remove acceptance test example 2016-01-22 10:39:15 +01:00
Flavio Copes
27af9432e0 🚨 Added a bunch of tests to make sure Assets addJs and addCSS works as expected 2016-01-22 10:38:56 +01:00
Flavio Copes
774cf2d6d0 Recreated an issue in calling with an array of values {% do assets.addJs('jquery', {'loading':'async'}) %} introduced in d5bd99b363 2016-01-22 00:09:14 +01:00
Flavio Copes
8270edbc78 Fix loading js and css from collections
Calling add() lose information on

- CSS: $group
- JS: $loading, $group
2016-01-21 21:24:26 +01:00
Flavio Copes
563a990f0d Also continue to handle Whoops 2.0.0-alpha if installed 2016-01-21 12:51:26 +01:00
Flavio Copes
b248b39dc7 Add test script to composer 2016-01-21 12:41:32 +01:00
Flavio Copes
a9ec2af342 Remove any URL extension for the home link 2016-01-21 12:31:20 +01:00
Flavio Copes
1fdc34b43c PHPdoc 2016-01-21 12:07:28 +01:00
Flavio Copes
11dc04262b Fix Whoops APIs after updating Whoops to 2.0 2016-01-21 11:01:44 +01:00
Flavio Copes
82a4176816 Merge pull request #616 from Vivalldi/patch-2
Update Whoops to latest
2016-01-21 09:49:28 +01:00
Flavio Copes
722bc3e74b More testing for assets 2016-01-20 11:35:40 +01:00
Flavio Copes
1616fadfe9 Started testing assets 2016-01-20 10:55:31 +01:00
Flavio Copes
71e8ba44fc Test Composer class 2016-01-20 09:21:15 +01:00
Andy Miller
e801c8f44e Added support for absolute_urls: true and page level ssl 2016-01-19 15:48:18 -07:00
Andy Miller
4fa04f6eec added scheme to URI 2016-01-19 15:46:09 -07:00
Andy Miller
f308587624 add SSL page variable and also force include_host if absolute_urls: true 2016-01-19 15:45:51 -07:00
Tyler Cosgrove
8406802a05 Change to next significant release 2016-01-19 14:46:30 -05:00
Tyler Cosgrove
778ae8aced Update Whoops to latest
Should have line highlights.
2016-01-19 14:15:12 -05:00
Flavio Copes
49dd8b3c9d Cleanup 2016-01-19 14:16:15 +01:00
Flavio Copes
1ecd4bfd5a Add Browser test 2016-01-19 14:16:06 +01:00
Flavio Copes
235b7e5ff3 Document Browser 2016-01-19 13:49:39 +01:00
Flavio Copes
68c582a02a Use unused $locator var 2016-01-19 13:38:03 +01:00
Flavio Copes
d0ef86c9a8 Remove unused variables 2016-01-19 13:37:56 +01:00
Flavio Copes
9c89f55274 Merge branch 'develop' into feature/introduce-testing 2016-01-19 13:30:40 +01:00
Flavio Copes
26434d26fe Finish Uri testing with test of Uri::addNonce() 2016-01-19 13:27:50 +01:00
Flavio Copes
d237a1e037 Test Uri::buildUrl() 2016-01-19 13:19:19 +01:00
Flavio Copes
6c7a1b335b Improve test 2016-01-19 13:17:45 +01:00
Flavio Copes
ad65816c35 Fix case 2016-01-19 13:17:36 +01:00
Flavio Copes
ed28a5dc62 Test Uri::referrer(), Uri::ip(), Uri::isExternal(), Uri::currentPage(), Uri::rootUrl(), Uri::base(), Uri::basename() 2016-01-19 13:17:16 +01:00
Flavio Copes
9fee3d4c59 Test Uri::environment() 2016-01-19 13:16:15 +01:00
Flavio Copes
0349169097 Add utility method 2016-01-19 13:15:55 +01:00
Flavio Copes
09e1c844f4 Ensure consistency in port handling, always set as string and not as integer 2016-01-19 11:38:06 +01:00
Flavio Copes
9b1b69fcae Test Uri::port() 2016-01-19 11:37:46 +01:00
Flavio Copes
4dd57daec0 Test Uri::host() 2016-01-19 11:37:35 +01:00
Flavio Copes
7813d18b1b Test Uri::extension() 2016-01-19 11:37:25 +01:00
Flavio Copes
f35bff4f59 Test Uri::path() 2016-01-19 11:37:14 +01:00
Flavio Copes
fd47620817 Test Uri::url() 2016-01-19 11:37:01 +01:00
Flavio Copes
b949b512e2 Test Uri::param() 2016-01-19 11:18:22 +01:00
Andy Miller
00aefa50ed Merge pull request #609 from getgrav/feature/drop-password-compat
Remove ircmaxell/password-compat as it's intended to provide forward compatibility for PHP 5.4
2016-01-18 21:51:50 -07:00
Flavio Copes
1a5abcbcbc Test Uri paths(), route(), query(), params() 2016-01-18 14:29:50 +01:00
Flavio Copes
90568da797 Fix setting port 2016-01-18 13:30:06 +01:00
Flavio Copes
2035a9a800 More testing 2016-01-18 11:17:17 +01:00
Flavio Copes
d29bc41ae7 Formatting 2016-01-18 11:17:12 +01:00
Flavio Copes
25637defa8 Set default port if not set 2016-01-18 11:17:04 +01:00
Flavio Copes
82616b9891 Return self instance in initializeWithUrl() to allow chaining method calls 2016-01-18 11:16:49 +01:00
Flavio Copes
067f75389b Fix reset after recent merge 2016-01-18 10:09:01 +01:00
Flavio Copes
0e6132800e Merge branch 'develop' into feature/introduce-testing 2016-01-18 09:59:52 +01:00
Flavio Copes
0a76e46d8f Remove ircmaxell/password-compat as it's intended to provide backward compatibility for PHP 5.4
However, it will still be installed in `vendor` as required by
`rockettheme/toolbox`
2016-01-17 20:40:45 +01:00
Andy Miller
77d4925f38 Added shortcode square brackets to grav trait 2016-01-16 17:54:43 -07:00
Flavio Copes
e1f95b54d5 Initial testing on the Uri class. Test the new validateHostname() method and tests initializeWithUrl() with some url examples 2016-01-15 21:47:05 +01:00
Flavio Copes
092989cdd0 Some internal rework of the Uri class
- Reworked constructor in methods
- Aded a Uri::initializeWithUrl() method that takes care of
initializing the internal state based on the passed URL
- Ensure Uri::query() does not crash if the internal variable is not an
array but `null`
2016-01-15 21:46:18 +01:00
Flavio Copes
27ab57eede Drop access to tests folder 2016-01-15 17:34:21 +01:00
Flavio Copes
e80a17540c Merge pull request #605 from getgrav/feature/modular-page-modified-date
The date for the last update of a page that is modular is the update time of the module that was last modified
2016-01-15 13:19:51 +01:00
Flavio Copes
72fb77894e Merge pull request #608 from hacklab01/patch-1
Update hr.yaml
2016-01-15 13:00:11 +01:00
Flavio Copes
70f8707b04 Blueprint for New Folder modal 2016-01-15 12:54:28 +01:00
v3d
0d33a1d479 Update hr.yaml
Update MONTHS_OF_THE_YEAR and DAYS_OF_THE_WEEK
2016-01-15 12:40:58 +01:00
Andy Miller
5d38e60076 Enhanced the bin/gpm info CLI command with CHANGELOG support - #559 2016-01-14 17:21:54 -07:00
Andy Miller
fc08cb8e52 Updated Twig library 2016-01-13 17:43:19 -07:00
Andy Miller
d65ec29408 Moved logic into page recurse where pages are already recursed and use collection() 2016-01-13 17:42:56 -07:00
Andy Miller
758ef2313a Merge branch 'feature/fix-hide-home-in-urls-second-level-childs' into develop 2016-01-13 17:09:03 -07:00
Andy Miller
479e73e950 Some optimizations/cleanup on CLI commands 2016-01-12 10:04:27 -07:00
Matias Griese
af6e352083 Fix stream override ordering 2016-01-12 11:59:45 +01:00
Flavio Copes
7e5b60917b Add ext-* to composer 2016-01-12 11:19:23 +01:00
Andy Miller
3695ff3d03 Some optimizations/cleanup on CLI commands 2016-01-11 18:45:07 -07:00
Andy Miller
be2af197c3 Allow twig_vars to be exposed earlier and merged later 2016-01-11 16:18:57 -07:00
Flavio Copes
acbbc723eb Add explanation on running tests in the readme 2016-01-10 19:22:23 +01:00
Flavio Copes
7c7df2240b Add first UI test example 2016-01-10 19:10:52 +01:00
Flavio Copes
c43f253805 Fix testPathPrefixedByLangCode test 2016-01-10 19:10:32 +01:00
Flavio Copes
756e2cf0c3 Fix spacing 2016-01-10 19:10:21 +01:00
Matias Griese
6087e786f5 Merge remote-tracking branch 'origin/develop' into develop 2016-01-10 17:19:30 +02:00
Matias Griese
9fa5681a4f Split configuration setup into 2 stages 2016-01-10 17:19:18 +02:00
Flavio Copes
182b6977bd The date for the last update of a page that is modular is the update time of the module that was last modified 2016-01-10 15:03:50 +01:00
Flavio Copes
3da7079777 Fix default generator metadata 2016-01-10 13:23:35 +01:00
Flavio Copes
992f99190b Merge pull request #604 from getgrav/feature/avoid-setting-empty-metadata
Avoid setting empty metadata
2016-01-09 23:40:42 +01:00
Flavio Copes
dfee5fdea9 Avoid setting empty metadata 2016-01-09 23:34:31 +01:00
Flavio Copes
aa9b735a50 Return the parent routes in the route options.
Added a Pages::parentsRawRoutes() method, uses the same internal method
as Pages::parents().

Refactored Pages::getList() to accept an optional $rawRoutes bool and
if set, return the raw routes
2016-01-09 20:45:06 +01:00
Andy Miller
9a3005e3c5 Added a reverse_proxy config option and use it to skip setting ports when enabled 2016-01-08 16:35:33 -07:00
Andy Miller
92ea756d91 fixed changelog typo 2016-01-08 16:34:19 -07:00
Andy Miller
b48449d782 Merge branch 'release/1.0.8' 2016-01-08 15:31:33 -07:00
Andy Miller
5e84ca35f2 Merge branch 'release/1.0.8' into develop 2016-01-08 15:31:33 -07:00
Andy Miller
ee20bf70e0 version update 2016-01-08 15:31:23 -07:00
Andy Miller
8cb098c6e0 Removed IP stuff from nonce.. just too many scenarios where it causes problems. going to rely on session_id() for the uniqueness. 2016-01-08 15:28:03 -07:00
Andy Miller
3054a67078 Added rotate, flip and fixOrientation to available image methods 2016-01-07 18:49:09 -07:00
Andy Miller
8ca14c7c65 Merge branch 'release/1.0.7' 2016-01-07 14:21:56 -07:00
Andy Miller
6e2d9ca3cc Merge branch 'release/1.0.7' into develop 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
c772c2d4ad Finish up Utils testing 2016-01-07 17:38:25 +01:00
Flavio Copes
e47ac59860 Add fake HTTP_CLIENT_IP for command line use 2016-01-07 17:38:16 +01:00
Flavio Copes
4f003bb5fa Add missing phpdoc to Utils 2016-01-07 16:47:40 +01:00
Flavio Copes
74c1e7473a Fix docblock 2016-01-07 14:34:21 +01:00
Flavio Copes
51d2724dfd Return false if the string is less than 4 chars, it cannot contain the lang code. Prevents error in the method 2016-01-07 14:34:13 +01:00
Flavio Copes
5fefa85f4a More tests 2016-01-07 14:33:18 +01:00
Flavio Copes
e8a935570b More tests 2016-01-07 13:58:47 +01:00
Flavio Copes
ce71168ed9 Merge branch 'develop' into feature/introduce-testing 2016-01-07 13:03:06 +01: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
Flavio Copes
1951722fdb Add Faker to Fixtures 2016-01-06 17:30:53 +01:00
Flavio Copes
90d2856581 Add a test that uses $grav 2016-01-06 17:30:39 +01:00
Flavio Copes
4fdeb4902e Pass $grav to all tests through the Fixtures utility 2016-01-06 17:30:13 +01:00
Flavio Copes
df3a492d3a Also add Faker to require-dev to be used in tests 2016-01-06 17:29:32 +01:00
Flavio Copes
e180e5a52a Add some more tests 2016-01-06 16:33:58 +01: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
f1ac509032 Structure tests in folders that resemble the Grav system/src folder 2016-01-05 19:50:07 +01:00
Flavio Copes
5d4705b9fa Add codeception to require-dev 2016-01-05 19:39:00 +01:00
Flavio Copes
ac23ab21b8 Merge pull request #587 from jeromegamez/readme-changelog
Update README and CHANGELOG
2016-01-05 11:57:43 +01:00
Flavio Copes
6cb85dc6a5 Drop default db config from config 2016-01-05 11:56:28 +01:00
Flavio Copes
5b8b8e4ebb First sample test, test Utils 2016-01-05 11:52:17 +01:00
Flavio Copes
a6b1c6b222 Setup _bootstrap to setup Grav 2016-01-05 11:52:07 +01:00
Jérôme Gamez
0261df0d48 Update README and CHANGELOG 2016-01-05 11:17:22 +01:00
Flavio Copes
b3d18be643 Add and bootstrap codeception 2016-01-05 11:01:02 +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
17a0590ee4 Merge branch 'release/1.0.4' into develop 2015-12-12 13:03:34 -07:00
Robert Went
05e4f96a6b makes cli commands available on windows machines from site root 2014-11-18 16:45:22 +00:00
197 changed files with 9209 additions and 1864 deletions

6
.gitignore vendored
View File

@@ -35,3 +35,9 @@ Thumbs.db
# phpstorm
.idea/*
user/config/security.yaml
tests/_output/*
tests/_support/_generated/*
tests/cache/*
tests/error.log

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|tests)/(.*) 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
@@ -52,9 +52,9 @@ RewriteRule ^(user)/(.*)\.(txt|md|yaml|php|pl|py|cgi|twig|sh|bat)$ error [F]
# Block all direct access to .md files:
RewriteRule \.md$ error [F]
# Block all direct access to files and folders beginning with a dot
RewriteRule (^\.|/\.) - [F]
RewriteRule (^|/)\.(?!well-known) - [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

@@ -1,7 +1,12 @@
language: php
php: 5.6
php:
- '5.5'
- '5.6'
- '7.0'
- hhvm
branches:
only:
- develop
- master
- build_test
notifications:
@@ -13,8 +18,10 @@ notifications:
rooms:
- secure: "bqO0wM1B7bJnQw2fuhquSXEqI9gw6WmFytIh9sEWXzbYTzTUP5t0PcKOd3FT2BNMRaDxPJLVl+vG/oqmqDUBkEmOGcG504IQjeNzZqnMz0tXQMIcCc22Las9tFfc4Jf6RVi/qGomFtHGE9Wgii+TAN4zqZaufbNjwd8SyjO0+W8="
template:
- '%{repository}#%{build_number} (%{branch}): Grav Core and Skeletons packages have been uploaded. (<a href="%{build_url}">Details</a>)'
- '%{repository}#%{build_number} (%{branch}): Travis Job Finished [%{duration}] (<a href="%{build_url}">Details</a>)'
format: html
slack:
secure: dowksPsxxCxGKT6nis5hUgkp6+ZDAhoqzQHF9rJnx4hx0iEygPhVBs7pKl9yL2jubYJoLs+EXwE7z1dYgDAEJh4BnfrCokCMLpFGcxVxQC/HeAUdSQ2/RtdBYR5PRT75ScaFpqM/SfXXZVtnwVXAw9Z+JC6BjQ9vmn23m51Jw4k=
env:
global:
# Colors!
@@ -35,20 +42,35 @@ env:
# BB_TOKEN value => "user:pass@"
- secure: "einUtSEkUWy2IrqLXyVjwUU+mwaaoiOXRRVdLBpA3Zye6bZx8cm5h/5AplkPWhM/NmCJoW/MwNZHHkFhlr3mDRov5iOxVmTTYfnXB+I5lxYTSgduOLLErS7mU8hfADpVDU8bHNU44fNGD3UEiG1PD4qQBX4DMlqIFmR20mjs81k="
# GH_API_USER [for curl]
- secure: "Xbk/V9aIys0NxccJGR3Zrm2GRxDnA0RuazBs1puIboTYDhbi0Z7JTL+mOx3xp5Kfoniad/xAuijQESTM9MMrKqq/qCzhAMaC1+vcL4pCHZH4NSG6DBxB9BPkKVFq+1llu5FTEf8bkxHzwGR0l1ARW6TVRcgTHr5B58bCEIwEOrI="
- secure: "AQGcX1B2NrI8ajflY4AimZDNcK2kBA3F6mbtEFQ78NkDoWhMipsQHayWXiSTzRc0YJKvQl2Y16MTwQF4VHzjTAiiZFATgA8J88vQUjIPabi/kKjqSmcLFoaAOAxStQbW6e0z2GiQ6KBMcNF1y5iUuI63xVrBvtKrYX/w5y+ako8="
# Latest Release version
- 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)
- TRAVIS_TAG=$(curl --fail -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
- echo $TRAVIS_PHP_VERSION
- echo $TRAVIS_BRANCH
- echo $TRAVIS_PULL_REQUEST
- composer self-update
- go get github.com/aktau/github-release
- git clone --quiet --depth=50 --branch=master https://${BB_TOKEN}bitbucket.org/rockettheme/grav-devtools.git $RT_DEVTOOLS &>/dev/null;
- if [ ! -z "$TRAVIS_TAG" ]; then
cd "${RT_DEVTOOLS}";
./build-grav.sh skeletons.txt;
- if [ $TRAVIS_BRANCH == 'develop' ] || [ $TRAVIS_PULL_REQUEST != 'false' ]; then
composer install --dev --prefer-dist;
fi
- if [ $TRAVIS_BRANCH != 'develop' ] && [ $TRAVIS_PHP_VERSION == "5.6" ] && [ $TRAVIS_PULL_REQUEST == "false" ]; then
go get github.com/aktau/github-release;
git clone --quiet --depth=50 --branch=master https://${BB_TOKEN}bitbucket.org/rockettheme/grav-devtools.git $RT_DEVTOOLS &>/dev/null;
if [ ! -z "$TRAVIS_TAG" ]; then
cd ${RT_DEVTOOLS};
./build-grav.sh skeletons.txt;
fi;
fi
before_script:
- if [ $TRAVIS_PHP_VERSION != 'hhvm' ]; then phpenv config-rm xdebug.ini; fi
script:
- if [ ! -z "$TRAVIS_TAG" ]; then
- if [ $TRAVIS_BRANCH == 'develop' ] || [ $TRAVIS_PULL_REQUEST != 'false' ]; then
vendor/bin/codecept run;
fi
- echo $TRAVIS_TAG
- if [ ! -z "$TRAVIS_TAG" ] && [ $TRAVIS_BRANCH != 'develop' ] && [ $TRAVIS_PHP_VERSION == "5.6" ] && [ $TRAVIS_PULL_REQUEST == "false" ]; then
FILES="$RT_DEVTOOLS/grav-dist/*.zip";
for file in ${FILES[@]}; do
NAME=${file##*/};

View File

@@ -1,3 +1,137 @@
# v1.0.10
## 02/11/2016
1. [](#new)
* Added new `Page::contentMeta()` mechanism to store content-level meta data alongside content
* Added Japanese language translation
1. [](#improved)
* Updated some vendor libraries
1. [](#bugfix)
* Hide `streams` blueprint from Admin plugin
* Fix translations of languages with `---` in YAML files
# v1.0.9
## 02/05/2016
1. [](#new)
* New **Unit Testing** via Codeception http://codeception.com/
* New **page-level SSL** functionality when using `absolute_urls`
* Added `reverse_proxy` config option for issues with non-standard ports
* Added `proxy_url` config option to support GPM behind proxy servers #639
* New `Pages::parentsRawRoutes()` method
* Enhanced `bin/gpm info` CLI command with Changelog support #559
* Ability to add empty *Folder* via admin plugin
* Added latest `jQuery 2.2.0` library to core
* Added translations from Crowdin
1. [](#improved)
* [BC] Metadata now supports only flat arrays. To use open graph metas and the likes (ie, 'og:title'), simply specify it in the key.
* Refactored `Uri::convertUrl()` method to be more reliable + tests created
* Date for last update of a modular sub-page sets modified date of modular page itself
* Split configuration up into two steps
* Moved Grav-based `base_uri` variables into `Uri::init()`
* Refactored init in `URI` to better support testing
* Allow `twig_vars` to be exposed earlier and merged later
* Avoid setting empty metadata
* Accept single group access as a string rather than requiring an array
* Return `$this` in Page constructor and init to allow chaining
* Added `ext-*` PHP requirements to `composer.json`
* Use Whoops 2.0 library while supporting old style
* Removed redundant old default-hash fallback mechanisms
* Commented out default redirects and routes in `site.yaml`
* Added `/tests` folder to deny's of all `webserver-configs/*` files
* Various PS and code style fixes
1. [](#bugfix)
* Fix default generator metadata
* Fix for broken image processing caused by `Uri::convertUrl()` bugs
* Fix loading JS and CSS from collections #623
* Fix stream overriding
* Remove the URL extension for home link
* Fix permissions when the user has no access level set at all
* Fix issue with user with multiple groups getting denied on first group
* Fixed an issue with `Pages()` internal cache lookup not being unique enough
* Fix for bug with `site.redirects` and `site.routes` being an empty list
* [Markdown] Don't process links for **special protocols**
* [Whoops] serve JSON errors when request is JSON
# v1.0.8
## 01/08/2016
1. [](#new)
* Added `rotate`, `flip` and `fixOrientation` image medium methods
1. [](#bugfix)
* Removed IP from Nonce generation. Should be more reliable in a variety of scenarios
# 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
@@ -19,7 +153,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
@@ -32,7 +166,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
@@ -66,7 +200,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

@@ -1,6 +1,6 @@
# ![](https://avatars1.githubusercontent.com/u/8237355?v=2&s=50) Grav
# ![](https://avatars1.githubusercontent.com/u/8237355?v=2&s=50) Grav
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad/mini.png)](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/getgrav/grav?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad/mini.png)](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/getgrav/grav?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/getgrav/grav.svg?branch=develop)](https://travis-ci.org/getgrav/grav)
Grav is a **Fast**, **Simple**, and **Flexible**, file-based Web-platform. There is **Zero** installation required. Just extract the ZIP archive, and you are already up and running. It follows similar principles to other flat-file CMS platforms, but has a different design philosophy than most. Grav comes with a powerful **Package Management System** to allow for simple installation and upgrading of plugins and themes, as well as simple updating of Grav itself.
@@ -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:
@@ -92,11 +100,11 @@ What you mainly want to know is that:
* [What is Grav?](http://learn.getgrav.org/basics/what-is-grav)
* [Install](http://learn.getgrav.org/basics/installation) Grav in few seconds
* Understand the [Configuration](http://learn.getgrav.org/basics/grav-configuration)
* Take a peek at our available free [Skeletons](http://getgrav.org/downloads/skeletons#extras)
* If you have questions, check out `#grav` on irc.freenode.net
* Take a peek at our available free [Skeletons](http://getgrav.org/downloads/skeletons)
* If you have questions, jump on our [Gitter Room](https://gitter.im/getgrav/grav)!
* Have fun!
# Exploring more
# Exploring More
* Have a look at our [Basic Tutorial](http://learn.getgrav.org/basics/basic-tutorial)
* Dive into more [advanced](http://learn.getgrav.org/advanced) functions
@@ -108,3 +116,10 @@ See [LICENSE](LICENSE.txt)
[gitflow-model]: http://nvie.com/posts/a-successful-git-branching-model/
[gitflow-extensions]: https://github.com/nvie/gitflow
# Running Tests
First install the dev dependencies by running `composer update` from the Grav root.
Then `composer test` will run the Unit Tests, which should be always executed successfully on any site.
You can also run a single unit test file, e.g. `composer test tests/unit/Grav/Common/AssetsTest.php`

11
bin/gpm
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');
}
@@ -39,6 +39,7 @@ if (!function_exists('curl_version')) {
$grav = Grav::instance(array('loader' => $autoload));
$grav['config']->init();
$grav['uri']->init();
$grav['streams'];
$app = new Application('Grav Package Manager', GRAV_VERSION);
@@ -51,4 +52,6 @@ $app->addCommands(array(
new \Grav\Console\Gpm\UpdateCommand(),
new \Grav\Console\Gpm\SelfupgradeCommand(),
));
$app->setDefaultCommand('index');
$app->run();

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');
}
@@ -107,10 +107,12 @@ try {
exit;
}
foreach ($commands as $command) {
require_once "plugins://{$name}/cli/{$command}";
$command = 'Grav\Plugin\Console\\' . preg_replace('/.php$/', '', $command);
$app->add(new $command());
foreach ($commands as $command_path) {
require_once "plugins://{$name}/cli/{$command_path}";
$command_class = 'Grav\Plugin\Console\\' . preg_replace('/.php$/', '', $command_path);
$command = new $command_class();
$app->add($command);
}
$app->run($input);

16
codeception.yml Normal file
View File

@@ -0,0 +1,16 @@
actor: Tester
paths:
tests: tests
log: tests/_output
data: tests/_data
support: tests/_support
envs: tests/_envs
settings:
bootstrap: _bootstrap.php
colors: true
memory_limit: 1024M
extensions:
enabled:
- Codeception\Extension\RunFailed
modules:
config:

View File

@@ -1,13 +1,14 @@
{
"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",
"twig/twig": "~1.23",
"php": ">=5.5.9",
"twig/twig": "~1.24",
"erusev/parsedown": "dev-master as 1.6.0",
"erusev/parsedown-extra": "~0.7",
"symfony/yaml": "~2.8",
"symfony/console": "~2.8",
@@ -15,15 +16,21 @@
"symfony/var-dumper": "~2.8",
"symfony/polyfill-iconv": "~1.0",
"doctrine/cache": "~1.5",
"filp/whoops": "1.1.10",
"filp/whoops": "~2.0",
"monolog/monolog": "~1.0",
"gregwar/image": "~2.0",
"ircmaxell/password-compat": "1.0.*",
"mrclay/minify": "~2.2",
"donatj/phpuseragentparser": "~0.3",
"pimple/pimple": "~3.0",
"rockettheme/toolbox": "~1.2",
"maximebf/debugbar": "~1.10"
"maximebf/debugbar": "~1.10",
"ext-mbstring": "*",
"ext-openssl": "*",
"ext-curl": "*"
},
"require-dev": {
"codeception/codeception": "^2.1",
"fzaninotto/faker": "^1.5"
},
"autoload": {
"psr-4": {
@@ -33,5 +40,15 @@
},
"archive": {
"exclude": ["VERSION"]
},
"scripts": {
"post-create-project-cmd": "bin/grav install",
"test": "vendor/bin/codecept run unit",
"test-windows": "vendor\\bin\\codecept run unit"
},
"extra": {
"branch-alias": {
"dev-develop": "1.x-dev"
}
}
}

1689
composer.lock generated

File diff suppressed because it is too large Load Diff

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());

File diff suppressed because one or more lines are too long

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

@@ -2,6 +2,7 @@ title: PLUGIN_ADMIN.FILE_STREAMS
form:
validation: loose
hidden: true
fields:
schemes.xxx:
type: array

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
@@ -800,6 +848,24 @@ form:
underline: true
fields:
proxy_url:
type: text
size: medium
placeholder: "e.g. 127.0.0.1:3128"
label: PLUGIN_ADMIN.PROXY_URL
help: PLUGIN_ADMIN.PROXY_URL_HELP
reverse_proxy_setup:
type: toggle
label: PLUGIN_ADMIN.REVERSE_PROXY
highlight: 0
help: PLUGIN_ADMIN.REVERSE_PROXY_HELP
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
wrapped_site:
type: toggle
label: PLUGIN_ADMIN.WRAPPED_SITE

View File

@@ -139,7 +139,7 @@ form:
type: select
label: PLUGIN_ADMIN.PARENT
classes: fancy
'@data-options': '\Grav\Common\Page\Pages::parents'
'@data-options': '\Grav\Common\Page\Pages::parentsRawRoutes'
'@data-default': '\Grav\Plugin\admin::route'
options:
'/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT

View File

@@ -0,0 +1,35 @@
rules:
slug:
pattern: "[a-z][a-z0-9_\-]+"
min: 2
max: 80
form:
validation: loose
fields:
section:
type: section
title: PLUGIN_ADMIN.ADD_PAGE
folder:
type: text
label: PLUGIN_ADMIN.FOLDER_NAME
help: PLUGIN_ADMIN.FOLDER_NAME_HELP
validate:
type: slug
required: true
route:
type: select
label: PLUGIN_ADMIN.PARENT_PAGE
classes: fancy
'@data-options': '\Grav\Common\Page\Pages::parents'
'@data-default': '\Grav\Plugin\admin::getLastPageRoute'
options:
'/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT
validate:
required: true
blueprint:
type: blueprint

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

@@ -41,4 +41,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

@@ -16,12 +16,12 @@ summary:
delimiter: === # The summary delimiter
redirects:
/redirect-test: / # Redirect test goes to home page
/old/(.*): /new/$1 # Would redirect /old/my-page to /new/my-page
# /redirect-test: / # Redirect test goes to home page
# /old/(.*): /new/$1 # Would redirect /old/my-page to /new/my-page
routes:
/something/else: '/blog/sample-3' # Alias for /blog/sample-3
/new/(.*): '/blog/$1' # Regex any /new/my-page URL to /blog/my-page Route
# /something/else: '/blog/sample-3' # Alias for /blog/sample-3
# /new/(.*): '/blog/$1' # Regex any /new/my-page URL to /blog/my-page Route
blog:
route: '/blog' # Custom value added (accessible via system.blog.route)

View File

@@ -3,6 +3,8 @@ timezone: '' # Valid values: http://php.net/manua
default_locale: # Default locale (defaults to system)
param_sep: ':' # Parameter separator, use ';' for Apache on windows
wrapped_site: false # For themes/plugins to know if Grav is wrapped by another platform
reverse_proxy_setup: false # Running in a reverse proxy scenario with different webserver ports than proxy
proxy_url: # Configure a manual proxy URL for GPM (eg 127.0.0.1:3128)
languages:
supported: [] # List of languages supported. eg: [en, fr, de]
@@ -15,6 +17,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 +34,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
@@ -83,7 +87,7 @@ assets: # Configuration for Assets Manager (
js_minify: true # Minify the JS during pipelining
enable_asset_timestamp: false # Enable asset timestamps
collections:
jquery: system://assets/jquery/jquery-2.1.4.min.js
jquery: system://assets/jquery/jquery-2.x.min.js
errors:
display: false # Display full backtrace-style error page
@@ -110,5 +114,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.4');
define('GRAV_VERSION', '1.0.10');
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

@@ -1,37 +1,79 @@
INFLECTOR_UNCOUNTABLE:
- vybavení
- informace
- rýže
- peníze
- druhy
- série
- ryba
- ovce
INFLECTOR_IRREGULAR:
person: lidé
man: muži
child: děti
sex: pohlaví
move: pohyby
INFLECTOR_ORDINALS:
default: '.'
first: '.'
second: '.'
third: '.'
NICETIME:
NO_DATE_PROVIDED: Datum nebylo vloženo
BAD_DATE: Chybné datum
AGO: zpět
FROM_NOW: od teď
SECOND: sekunda
MINUTE: minuta
HOUR: hodina
DAY: den
WEEK: týden
MONTH: měsíc
YEAR: rok
DECADE: dekáda
SEC: sek
MIN: min
HR: hod
DAY: den
WK: t
MO: m
YR: r
DEC: dek
SECOND_PLURAL: sekundy
MINUTE_PLURAL: minuty
HOUR_PLURAL: hodiny
DAY_PLURAL: dny
WEEK_PLURAL: týdny
MONTH_PLURAL: měsíce
YEAR_PLURAL: roky
DECADE_PLURAL: dekády
SEC_PLURAL: sek
MIN_PLURAL: min
HR_PLURAL: hod
DAY_PLURAL: dny
WK_PLURAL: t
MO_PLURAL: m
YR_PLURAL: r
DEC_PLURAL: dek
NO_DATE_PROVIDED: Datum nebylo vloženo
BAD_DATE: Chybné datum
AGO: zpět
FROM_NOW: od teď
SECOND: sekunda
MINUTE: minuta
HOUR: hodina
DAY: den
WEEK: týden
MONTH: měsíc
YEAR: rok
DECADE: dekáda
SEC: sek
MIN: min
HR: hod
WK: t
MO: m
YR: r
DEC: dek
SECOND_PLURAL: sekundy
MINUTE_PLURAL: minuty
HOUR_PLURAL: hodiny
DAY_PLURAL: dny
WEEK_PLURAL: dny
MONTH_PLURAL: měsíce
YEAR_PLURAL: roky
DECADE_PLURAL: dekády
SEC_PLURAL: sek
MIN_PLURAL: min
HR_PLURAL: hod
WK_PLURAL: t
MO_PLURAL: m
YR_PLURAL: r
DEC_PLURAL: dek
FORM:
VALIDATION_FAIL: '<b>Ověření se nezdařilo:</b>'
MISSING_REQUIRED_FIELD: 'Chybí požadované pole:'
MONTHS_OF_THE_YEAR:
- ledna
- února
- března
- dubna
- května
- června
- července
- srpna
- září
- října
- listopadu
- prosince
DAYS_OF_THE_WEEK:
- Pondělí
- Úterý
- Středa
- Čtvrtek
- Pátek
- Sobota
- Neděle

View File

@@ -1,43 +1,82 @@
FRONTMATTER_ERROR_PAGE: |
---
title: %1$s
---
# Fehler: Frontmatter enthält Fehler
Pfad: `%2$s`
**%3$s **
```
%4$s
```
INFLECTOR_UNCOUNTABLE:
1: Informationen
2: Reis
3: Geld
INFLECTOR_IRREGULAR:
'person': 'Personen'
'man': 'Menschen'
'child': 'Kinder'
'sex': 'Geschlecht'
'move': 'Züge'
person: Personen
man: Menschen
child: Kinder
sex: Geschlecht
move: Züge
NICETIME:
NO_DATE_PROVIDED: Keine Daten vorhanden
BAD_DATE: Falsches Datum
AGO: her
FROM_NOW: ab jetzt
SECOND: Sekunde
MINUTE: Minute
HOUR: Stunde
DAY: Tag
WEEK: Woche
MONTH: Monat
YEAR: Jahr
DECADE: Dekade
SEC: sek
MIN: min
HR: std
DAY: Tag
WK: wo
MO: mo
YR: yh
DEC: dec
SECOND_PLURAL: Sekunden
MINUTE_PLURAL: Minuten
HOUR_PLURAL: Stunden
DAY_PLURAL: Tage
WEEK_PLURAL: Wochen
MONTH_PLURAL: Monate
YEAR_PLURAL: Jahre
DECADE_PLURAL: Dekaden
SEC_PLURAL: Sekunden
MIN_PLURAL: Minuten
HR_PLURAL: Stunden
DAY_PLURAL: Tage
WK_PLURAL: Wochen
MO_PLURAL: Monate
YR_PLURAL: Jahre
DEC_PLURAL: Dekaden
NO_DATE_PROVIDED: Keine Daten vorhanden
BAD_DATE: Falsches Datum
AGO: her
FROM_NOW: ab jetzt
SECOND: Sekunde
MINUTE: Minute
HOUR: Stunde
DAY: Tag
WEEK: Woche
MONTH: Monat
YEAR: Jahr
DECADE: Dekade
SEC: sek
MIN: Min
HR: std
WK: wo
YR: yh
DEC: Jz
SECOND_PLURAL: Sekunden
MINUTE_PLURAL: Minuten
HOUR_PLURAL: Stunden
DAY_PLURAL: Tage
WEEK_PLURAL: Wochen
MONTH_PLURAL: Monate
YEAR_PLURAL: Jahre
DECADE_PLURAL: Dekaden
SEC_PLURAL: Sekunden
MIN_PLURAL: Minuten
HR_PLURAL: Stunden
WK_PLURAL: Wochen
MO_PLURAL: Monate
YR_PLURAL: Jahre
DEC_PLURAL: Dekaden
FORM:
VALIDATION_FAIL: '<b>Überprüfung fehlgeschlagen:</b>'
INVALID_INPUT: Ungültige Eingabe in
MISSING_REQUIRED_FIELD: 'Erforderliches Feld fehlt:'
MONTHS_OF_THE_YEAR:
- Januar
- Februar
- März
- April
- Mai
- Juni
- Juli
- August
- Semptember
- Oktober
- November
- Dezember
DAYS_OF_THE_WEEK:
- Montag
- Dienstag
- Mittwoch
- Donnerstag
- Freitag
- Samstag
- Sonntag

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

@@ -0,0 +1,21 @@
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

@@ -1,42 +1,75 @@
INFLECTOR_UNCOUNTABLE:
0: equipo
1: información
3: dinero
5: series
6: pescado
7: oveja
INFLECTOR_IRREGULAR:
man: hombres
child: niños
sex: sexos
INFLECTOR_ORDINALS:
first: ro
second: do
third: ro
NICETIME:
NO_DATE_PROVIDED: No se proporcionó fecha
BAD_DATE: Fecha erronea
AGO: antes
FROM_NOW: desde ahora
SECOND: segundo
MINUTE: minuto
HOUR: hora
DAY: dia
WEEK: semana
MONTH: mes
YEAR: año
DECADE: decada
SEC: seg
MIN: min
HR: hr
DAY: dia
WK: sem
MO: mes
YR: yr
DEC: dec
SECOND_PLURAL: segundos
MINUTE_PLURAL: minutos
HOUR_PLURAL: horas
DAY_PLURAL: as
WEEK_PLURAL: semanas
MONTH_PLURAL: meses
YEAR_PLURAL: años
DECADE_PLURAL: decadas
SEC_PLURAL: segs
MIN_PLURAL: mins
HR_PLURAL: hrs
DAY_PLURAL: dias
WK_PLURAL: sem
MO_PLURAL: mes
YR_PLURAL: años
DEC_PLURAL: decs
NO_DATE_PROVIDED: No se proporcionó fecha
BAD_DATE: Fecha erronea
AGO: antes
FROM_NOW: desde ahora
SECOND: segundo
MINUTE: minuto
HOUR: hora
DAY: día
WEEK: semana
MONTH: mes
YEAR: año
DECADE: década
SEC: seg
MIN: min
HR: h
WK: sem
MO: mes
YR: año
DEC: dec
SECOND_PLURAL: segundos
MINUTE_PLURAL: minutos
HOUR_PLURAL: horas
DAY_PLURAL: as
WEEK_PLURAL: semanas
MONTH_PLURAL: meses
YEAR_PLURAL: años
DECADE_PLURAL: décadas
SEC_PLURAL: segs
MIN_PLURAL: mins
HR_PLURAL: hs
WK_PLURAL: sem
MO_PLURAL: mes
YR_PLURAL: años
DEC_PLURAL: décadas
FORM:
VALIDATION_FAIL: <b>Falló la validación. </b>
INVALID_INPUT: "Dato inválido en: "
MISSING_REQUIRED_FIELD: "Falta el campo requerido: "
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
- Agosto
- Septiembre
- Octubre
- Noviembre
- Diciembre
DAYS_OF_THE_WEEK:
- Lunes
- Martes
- Miércoles
- Jueves
- Viernes
- Sábado
- Domingo

View File

@@ -1,98 +1,137 @@
FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Erreur : Frontmatter invalide\n\nPath: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
FRONTMATTER_ERROR_PAGE: |
---
title: %1$s
---
# Erreur : Frontmatter invalide
Path: `%2$s`
**%3$s**
```
%4$s
```
INFLECTOR_PLURALS:
'/(quiz)$/i': '\1zes'
'/^(ox)$/i': '\1en'
'/([m|l])ouse$/i': '\1ice'
'/(matr|vert|ind)ix|ex$/i': '\1ices'
'/(x|ch|ss|sh)$/i': '\1es'
'/([^aeiouy]|qu)ies$/i': '\1y'
'/([^aeiouy]|qu)y$/i': '\1ies'
'/(hive)$/i': '\1s'
'/(?:([^f])fe|([lr])f)$/i': '\1\2ves'
'/sis$/i': 'ses'
'/([ti])um$/i': '\1a'
'/(buffal|tomat)o$/i': '\1oes'
'/(bu)s$/i': '\1ses'
'/(alias|status)/i': '\1es'
'/(octop|vir)us$/i': '\1i'
'/(ax|test)is$/i': '\1es'
'/s$/i': 's'
'/$/': 's'
/(quiz)$/i: '\1zes'
/^(ox)$/i: '\1en'
"/([m|l])ouse$/i": '\1ice'
/(matr|vert|ind)ix|ex$/i: '\1ices'
/(x|ch|ss|sh)$/i: '\1es'
"/([^aeiouy]|qu)ies$/i": '\1y'
"/([^aeiouy]|qu)y$/i": '\1ies'
/(hive)$/i: '\1s'
"/(?:([^f])fe|([lr])f)$/i": '\1\2ves'
/sis$/i: ses
"/([ti])um$/i": '\1a'
/(buffal|tomat)o$/i: '\1oes'
/(bu)s$/i: '\1ses'
/(alias|status)/i: '\1es'
/(octop|vir)us$/i: '\1i'
/(ax|test)is$/i: '\1es'
/s$/i: s
/$/: s
INFLECTOR_SINGULAR:
'/(quiz)zes$/i': '\1'
'/(matr)ices$/i': '\1ix'
'/(vert|ind)ices$/i': '\1ex'
'/^(ox)en/i': '\1'
'/(alias|status)es$/i': '\1'
'/([octop|vir])i$/i': '\1us'
'/(cris|ax|test)es$/i': '\1is'
'/(shoe)s$/i': '\1'
'/(o)es$/i': '\1'
'/(bus)es$/i': '\1'
'/([m|l])ice$/i': '\1ouse'
'/(x|ch|ss|sh)es$/i': '\1'
'/(m)ovies$/i': '\1ovie'
'/(s)eries$/i': '\1eries'
'/([^aeiouy]|qu)ies$/i': '\1y'
'/([lr])ves$/i': '\1f'
'/(tive)s$/i': '\1'
'/(hive)s$/i': '\1'
'/([^f])ves$/i': '\1fe'
'/(^analy)ses$/i': '\1sis'
'/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i': '\1\2sis'
'/([ti])a$/i': '\1um'
'/(n)ews$/i': '\1ews'
'/s$/i': ''
INFLECTOR_UNCOUNTABLE: ['équipment', 'information', 'riz', 'argent', 'espèces', 'séries', 'poisson', 'mouton']
/(quiz)zes$/i: '\1'
/(matr)ices$/i: '\1ix'
/(vert|ind)ices$/i: '\1ex'
/^(ox)en/i: '\1'
/(alias|status)es$/i: '\1'
"/([octop|vir])i$/i": '\1us'
/(cris|ax|test)es$/i: '\1is'
/(shoe)s$/i: '\1'
/(o)es$/i: '\1'
/(bus)es$/i: '\1'
"/([m|l])ice$/i": '\1ouse'
/(x|ch|ss|sh)es$/i: '\1'
/(m)ovies$/i: '\1ovie'
/(s)eries$/i: '\1eries'
"/([^aeiouy]|qu)ies$/i": '\1y'
"/([lr])ves$/i": '\1f'
/(tive)s$/i: '\1'
/(hive)s$/i: '\1'
"/([^f])ves$/i": '\1fe'
/(^analy)ses$/i: '\1sis'
/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i: '\1\2sis'
"/([ti])a$/i": '\1um'
/(n)ews$/i: '\1ews'
INFLECTOR_UNCOUNTABLE:
- équipement
- informations
- riz
- argent
- espèces
- séries
- poisson
- mouton
INFLECTOR_IRREGULAR:
'person': 'personnes'
'man': 'Hommes'
'child': 'enfants'
'sex': 'sexes'
'move': 'déplacemements'
person: personnes
man: hommes
child: enfants
sex: sexes
move: déplacements
INFLECTOR_ORDINALS:
'default': 'ème'
'first': 'er'
'second': 'nd'
'third': 'ème'
default: ème
first: er
second: ème
third: ème
NICETIME:
NO_DATE_PROVIDED: Aucune date
BAD_DATE: Date erronée
AGO: plus tôt
FROM_NOW: à partir de maintenant
SECOND: seconde
MINUTE: minute
HOUR: heure
DAY: jour
WEEK: semaine
MONTH: mois
YEAR: an
DECADE: décennie
SEC: s
MIN: m
HR: h
DAY: j
WK: s
MO: m
YR: a
DEC: d
SECOND_PLURAL: secondes
MINUTE_PLURAL: minutes
HOUR_PLURAL: heures
DAY_PLURAL: jours
WEEK_PLURAL: semaines
MONTH_PLURAL: mois
YEAR_PLURAL: années
DECADE_PLURAL: décennies
SEC_PLURAL: s
MIN_PLURAL: m
HR_PLURAL: h
DAY_PLURAL: j
WK_PLURAL: s
MO_PLURAL: m
YR_PLURAL: a
DEC_PLURAL: d
NO_DATE_PROVIDED: Aucune date fournie
BAD_DATE: Date erronée
AGO: plus tôt
FROM_NOW: à partir de maintenant
SECOND: seconde
MINUTE: minute
HOUR: heure
DAY: jour
WEEK: semaine
MONTH: mois
YEAR: année
DECADE: décennie
SEC: s
MIN: m
HR: h
WK: sem
MO: m
YR: an
DEC: déc
SECOND_PLURAL: secondes
MINUTE_PLURAL: minutes
HOUR_PLURAL: heures
DAY_PLURAL: jours
WEEK_PLURAL: semaines
MONTH_PLURAL: mois
YEAR_PLURAL: années
DECADE_PLURAL: décennies
SEC_PLURAL: s
MIN_PLURAL: m
HR_PLURAL: h
WK_PLURAL: sem
MO_PLURAL: mois
YR_PLURAL: a
DEC_PLURAL: décs
FORM:
VALIDATION_FAIL: <b>La validation a échoué :</b>
INVALID_INPUT: Saisie non valide
MISSING_REQUIRED_FIELD: Champ obligatoire manquant :
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

@@ -1,52 +1,74 @@
INFLECTOR_UNCOUNTABLE:
- oprema
- informacije
- riža
- novac
- vrsta
- serija
- riba
- ovca
INFLECTOR_IRREGULAR:
'person': 'Osoba'
'man': 'Čovjek'
'child': 'Dijete'
'sex': 'Spol'
'move': 'Pomakni'
person: osobe
man: ljudi
child: djeca
sex: spolovi
move: Pomakni
NICETIME:
NO_DATE_PROVIDED: Datum nije upisan
BAD_DATE: Pogrešan datum
AGO: prije
FROM_NOW: od sad
SECOND: sekundi
MINUTE: minuta
HOUR: godina
DAY: dan
WEEK: tjedan
MONTH: mjesec
YEAR: godina
DECADE: desetljeće
SEC: sek
MIN: min
HR: sat
DAY: dan
WK: t
MO: m
YR: g
DEC: des
SECOND_PLURAL: sekundi
SECOND_PLURAL_MORE_THAN_TWO: sekunde
MINUTE_PLURAL: minuta
MINUTE_PLURAL_MORE_THAN_TWO: minute
HOUR_PLURAL: sati
HOUR_PLURAL_MORE_THAN_TWO: sata
DAY_PLURAL: dana
WEEK_PLURAL: tjedana
WEEK_PLURAL_MORE_THAN_TWO: tjedna
MONTH_PLURAL: mjeseci
MONTH_PLURAL_MORE_THAN_TWO: mjeseca
YEAR_PLURAL: godina
YEAR_PLURAL_MORE_THAN_TWO: godine
DECADE_PLURAL: desetljeća
SEC_PLURAL: sek
MIN_PLURAL: min
HR_PLURAL: sat
DAY_PLURAL: dan
WK_PLURAL: t
MO_PLURAL: m
YR_PLURAL: g
DEC_PLURAL: des
NO_DATE_PROVIDED: Datum nije upisan
BAD_DATE: Pogrešan datum
AGO: prije
FROM_NOW: od sada
SECOND: sekunda
MINUTE: minuta
HOUR: sat
DAY: dan
WEEK: tjedan
MONTH: mjesec
YEAR: godina
DECADE: desetljeće
SEC: sek
HR: sat
WK: t
MO: m
YR: g
DEC: des
SECOND_PLURAL: sekundi
MINUTE_PLURAL: minuta
HOUR_PLURAL: sati
DAY_PLURAL: dan
WEEK_PLURAL: tjedana
MONTH_PLURAL: mjeseci
YEAR_PLURAL: godina
DECADE_PLURAL: desetljeća
SEC_PLURAL: sek
MIN_PLURAL: min
HR_PLURAL: sat
WK_PLURAL: t
MO_PLURAL: m
YR_PLURAL: g
DEC_PLURAL: des
FORM:
VALIDATION_FAIL: <b>Validacija nije uspjela:</b>
INVALID_INPUT: Unos nije valjan
VALIDATION_FAIL: '<b>Validacija nije uspjela:</b>'
INVALID_INPUT: Pogrešan unos u
MISSING_REQUIRED_FIELD: 'Nedostaje obavezno polje:'
MONTHS_OF_THE_YEAR:
- Siječanj
- Veljača
- Ožujak
- Travanj
- Svibanj
- Lipanj
- Srpanj
- Kolovoz
- Rujan
- Listopad
- Studeni
- Prosinac
DAYS_OF_THE_WEEK:
- Ponedjeljak
- Utorak
- Srijeda
- Četvrtak
- Petak
- Subota
- Nedjelja

View File

@@ -1,53 +1,64 @@
FRONTMATTER_ERROR_PAGE: "---\ncím: %1$s\n---\n\n# Hiba: Érvénytelen Frontmatter\n\nElérési út: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
FRONTMATTER_ERROR_PAGE: |
---
cím: %1$s
---
# Hiba: Érvénytelen Frontmatter
Elérési út: `%2$s`
**%3$s**
```
%4$s
```
INFLECTOR_IRREGULAR:
'person': 'személyek'
'man': 'férfiak'
'child': 'gyerekek'
'sex': 'nemek'
'move': 'lépések'
person: személyek
man: férfiak
child: gyerekek
sex: nemek
move: lépések
INFLECTOR_ORDINALS:
'default': '.'
'first': '.'
'second': '.'
'third': '.'
default: '.'
first: '.'
second: '.'
third: '.'
NICETIME:
NO_DATE_PROVIDED: Nincs dátum megadva
BAD_DATE: Hibás dátum
AGO: elteltével
FROM_NOW: mostantól
SECOND: másodperc
MINUTE: perc
HOUR: óra
DAY: nap
WEEK: hét
MONTH: hónap
YEAR: év
DECADE: évtized
SEC: mp
MIN: p
HR: ó
DAY: nap
WK: hét
MO:
YR: év
DEC: évt
SECOND_PLURAL: másodperc
MINUTE_PLURAL: perc
HOUR_PLURAL: óra
DAY_PLURAL: nap
WEEK_PLURAL: hét
MONTH_PLURAL: hónap
YEAR_PLURAL: év
DECADE_PLURAL: évtized
SEC_PLURAL: mp
MIN_PLURAL: perc
HR_PLURAL: ó
DAY_PLURAL: nap
WK_PLURAL: hét
MO_PLURAL:
YR_PLURAL: év
DEC_PLURAL: évt
NO_DATE_PROVIDED: Nincs dátum megadva
BAD_DATE: Hibás dátum
AGO: elteltével
FROM_NOW: mostantól
SECOND: másodperc
MINUTE: perc
HOUR: óra
DAY: nap
WEEK: hét
MONTH: hónap
YEAR: év
DECADE: évtized
SEC: mp
MIN: p
HR: ó
WK: hét
MO: hó
YR: év
DEC: évt
SECOND_PLURAL: másodperc
MINUTE_PLURAL: perc
HOUR_PLURAL: óra
DAY_PLURAL: nap
WEEK_PLURAL: hét
MONTH_PLURAL: hónap
YEAR_PLURAL: év
DECADE_PLURAL: évtized
SEC_PLURAL: mp
MIN_PLURAL: perc
HR_PLURAL: ó
WK_PLURAL: hét
MO_PLURAL:
YR_PLURAL: év
DEC_PLURAL: évt
FORM:
VALIDATION_FAIL: <b>A validáció hibát talált:</b>
INVALID_INPUT: Az itt megadott érték érvénytelen:
MISSING_REQUIRED_FIELD: Ez a kötelező mező nincs kitöltve:
VALIDATION_FAIL: '<b>A validáció hibát talált:</b>'
INVALID_INPUT: 'Az itt megadott érték érvénytelen:'
MISSING_REQUIRED_FIELD: 'Ez a kötelező mező nincs kitöltve:'

View File

@@ -1,25 +1,45 @@
NICETIME:
NO_DATE_PROVIDED: Nessuna data fornita
BAD_DATE: Data errata
AGO: fa
FROM_NOW: da adesso
SECOND: secondo
MINUTE: minuto
HOUR: ora
DAY: giorno
WEEK: settimana
MONTH: mese
YEAR: anno
DECADE: decade
SECOND_PLURAL: secondi
MINUTE_PLURAL: minuti
HOUR_PLURAL: ore
DAY_PLURAL: giorni
WEEK_PLURAL: settimane
MONTH_PLURAL: mesi
YEAR_PLURAL: anni
DECADE_PLURAL: decadi
NO_DATE_PROVIDED: Nessuna data fornita
BAD_DATE: Data errata
AGO: fa
FROM_NOW: da adesso
SECOND: secondo
MINUTE: minuto
HOUR: ora
DAY: giorno
WEEK: settimana
MONTH: mese
YEAR: anno
SECOND_PLURAL: secondi
MINUTE_PLURAL: minuti
HOUR_PLURAL: ore
DAY_PLURAL: giorni
WEEK_PLURAL: settimane
MONTH_PLURAL: mesi
YEAR_PLURAL: anni
DECADE_PLURAL: decadi
FORM:
VALIDATION_FAIL: <b>Validazione fallita:</b>
INVALID_INPUT: Input invalido in
MISSING_REQUIRED_FIELD: Campo richiesto mancante:
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

59
system/languages/ja.yaml Normal file
View File

@@ -0,0 +1,59 @@
FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Error: Invalid Frontmatter\n\nPath: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
INFLECTOR_PLURALS: []
INFLECTOR_SINGULAR: []
INFLECTOR_UNCOUNTABLE: []
INFLECTOR_IRREGULAR:
'person': 'みんな'
'man': '人'
'child': '子供'
'sex': '性別'
'move': '移動'
INFLECTOR_ORDINALS: []
NICETIME:
NO_DATE_PROVIDED: 日付が設定されていません
BAD_DATE: 不正な日付
AGO:
FROM_NOW: from now
SECOND:
MINUTE:
HOUR:
DAY:
WEEK:
MONTH:
YEAR:
DECADE: 10年
SEC:
MIN:
HR:
DAY:
WK:
MO:
YR:
DEC: dec
SECOND_PLURAL:
MINUTE_PLURAL:
HOUR_PLURAL:
DAY_PLURAL:
WEEK_PLURAL:
MONTH_PLURAL:
YEAR_PLURAL:
DECADE_PLURAL: 10年
SEC_PLURAL:
MIN_PLURAL:
HR_PLURAL:
DAY_PLURAL:
WK_PLURAL:
MO_PLURAL:
YR_PLURAL:
DEC_PLURAL: 10年
FORM:
VALIDATION_FAIL: <b>バリデーション失敗 :</b>
INVALID_INPUT: 不正な入力:
MISSING_REQUIRED_FIELD: 必須項目が入力されていません:
MONTHS_OF_THE_YEAR: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
DAYS_OF_THE_WEEK: ['月', '火', '水', '木', '金', '土', '日']

68
system/languages/lt.yaml Normal file
View File

@@ -0,0 +1,68 @@
INFLECTOR_UNCOUNTABLE:
2: ryžiai
3: pinigai
4: prieskoniai
5: serijos
6: žuvis
7: avis
INFLECTOR_IRREGULAR:
person: žmonės
man: žmogus
child: vaikai
sex: lytys
move: juda
NICETIME:
NO_DATE_PROVIDED: Nenurodyta data
BAD_DATE: Neteisinga data
AGO: prieš
FROM_NOW: nuo dabar
SECOND: sekundė
MINUTE: minutė
HOUR: valanda
DAY: diena
WEEK: savaitė
MONTH: mėnuo
YEAR: metai
DECADE: dešimtmetis
SEC: sek
MIN: min
HR: val
WK: sav
MO: mėn
YR: m
MINUTE_PLURAL: minutės
HOUR_PLURAL: valandos
DAY_PLURAL: dienos
WEEK_PLURAL: savaitės
MONTH_PLURAL: mėnesiai
YEAR_PLURAL: metai
DECADE_PLURAL: dešimtmečiai
SEC_PLURAL: sek
MIN_PLURAL: min
HR_PLURAL: val
WK_PLURAL: sav
MO_PLURAL: mėn
YR_PLURAL: m
FORM:
MISSING_REQUIRED_FIELD: 'Būtina užpildyti laukelį:'
MONTHS_OF_THE_YEAR:
- Sausis
- Vasaris
- Kovas
- Balandis
- Gegužė
- Birželis
- Liepa
- Rugpjūtis
- Rugsėjis
- Spalis
- Lakpritis
- Gruodis
DAYS_OF_THE_WEEK:
- Pirmadienis
- Antradienis
- Trečiadienis
- Ketvirtadienis
- Penktadienis
- Šeštadienis
- Sekmadienis

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

@@ -1,43 +1,50 @@
INFLECTOR_IRREGULAR:
'person': 'personen'
'man': 'mensen'
'child': 'kinderen'
'sex': 'geslacht'
'move': 'verplaatsen'
person: personen
man: mensen
child: kinderen
sex: geslacht
move: verplaatsen
NICETIME:
NO_DATE_PROVIDED: geen datum opgegeven
BAD_DATE: Datumformaat onjuist
AGO: geleden
FROM_NOW: vanaf nu
SECOND: seconde
MINUTE: minuut
HOUR: uur
DAY: dag
WEEK: week
MONTH: maand
YEAR: jaar
DECADE: decenium
SEC: sec
MIN: min
HR: hr
DAY: dag
WK: wk
MO: ma
YR: yr
DEC: dec
SECOND_PLURAL: seconden
MINUTE_PLURAL: minuten
HOUR_PLURAL: uren
DAY_PLURAL: dagen
WEEK_PLURAL: weken
MONTH_PLURAL: maanden
YEAR_PLURAL: jaren
DECADE_PLURAL: decennia
SEC_PLURAL: seconden
MIN_PLURAL: minuten
HR_PLURAL: uren
DAY_PLURAL: dagen
WK_PLURAL: weken
MO_PLURAL: maanden
YR_PLURAL: jaren
DEC_PLURAL: decs
NO_DATE_PROVIDED: geen datum opgegeven
BAD_DATE: Datumformaat onjuist
AGO: geleden
FROM_NOW: vanaf nu
SECOND: seconde
MINUTE: minuut
HOUR: uur
DAY: dag
MONTH: maand
YEAR: jaar
DECADE: decenium
MO: ma
SECOND_PLURAL: seconden
MINUTE_PLURAL: minuten
HOUR_PLURAL: uren
DAY_PLURAL: dagen
WEEK_PLURAL: weken
MONTH_PLURAL: maanden
YEAR_PLURAL: jaren
DECADE_PLURAL: decennia
SEC_PLURAL: seconden
MIN_PLURAL: minuten
HR_PLURAL: uren
WK_PLURAL: weken
MO_PLURAL: maanden
YR_PLURAL: jaren
MONTHS_OF_THE_YEAR:
0: Januari
1: Februari
2: Maart
4: Mei
5: Juni
6: Juli
7: Augustus
9: Oktober
DAYS_OF_THE_WEEK:
- Maandag
- Dinsdag
- Woensdag
- Donderdag
- Vrijdag
- Zaterdag
- Zondag

90
system/languages/no.yaml Normal file
View File

@@ -0,0 +1,90 @@
FRONTMATTER_ERROR_PAGE: |
---
Tittel: %1$s
---
# Feilmelding: Ugyldig Frontmatter
Pane: '%2$s'
**%3$s **
```
%4$s
```
INFLECTOR_PLURALS:
/(quiz)$/i: '\1zes'
/^(ox)$/i: '\1en'
INFLECTOR_UNCOUNTABLE:
- utstyr
- informasjon
- ris
- penger
- arter
- serier
- fisk
- sau
INFLECTOR_IRREGULAR:
person: folk
man: menn
child: barn
sex: kjønn
move: trekk
NICETIME:
NO_DATE_PROVIDED: Ingen dato gitt
BAD_DATE: Dårlig dato
AGO: siden
FROM_NOW: fra nå
SECOND: sekund
MINUTE: minutt
HOUR: time
DAY: dag
WEEK: uke
MONTH: måned
YEAR: år
DECADE: tiår
SEC: sek
MIN: min
HR: t
WK: uke
MO:
YR: år
DEC: des
SECOND_PLURAL: sekunder
MINUTE_PLURAL: minutter
HOUR_PLURAL: timer
DAY_PLURAL: dager
WEEK_PLURAL: uker
MONTH_PLURAL: måneder
YEAR_PLURAL: år
DECADE_PLURAL: tiår
SEC_PLURAL: sek
MIN_PLURAL: min
HR_PLURAL: timer
WK_PLURAL: uker
YR_PLURAL: år
FORM:
VALIDATION_FAIL: '<b>Validering mislyktes:</b>'
INVALID_INPUT: Ugyldig innhold i
MISSING_REQUIRED_FIELD: 'Mangler påkrevd felt:'
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

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

@@ -0,0 +1,74 @@
FRONTMATTER_ERROR_PAGE: |
---
title: %1$s
---
# Error: Nieprawidłowy Frontmatter
Path: `%2$s`
**%3$s**
```
%4$s
```
NICETIME:
NO_DATE_PROVIDED: Nie podano daty
BAD_DATE: Zła data
AGO: temu
FROM_NOW: od teraz
SECOND: sekunda
MINUTE: minuta
HOUR: godzina
DAY: dzień
WEEK: tydzień
MONTH: miesiąc
YEAR: rok
DECADE: dekada
SEC: sek
MIN: min
HR: godz
WK: tydź
MO: mieś
YR: rok
DEC: dekada
SECOND_PLURAL: sekund
MINUTE_PLURAL: minut
HOUR_PLURAL: godzin
DAY_PLURAL: dni
WEEK_PLURAL: tygodnie
MONTH_PLURAL: miesięcy
YEAR_PLURAL: lat
DECADE_PLURAL: dekad
SEC_PLURAL: sekund
MIN_PLURAL: minut
HR_PLURAL: godz
WK_PLURAL: tyg
MO_PLURAL: mieś
YR_PLURAL: lat
DEC_PLURAL: dekad
FORM:
VALIDATION_FAIL: '<b>Weryfikacja nie powiodła się:</b>'
INVALID_INPUT: Nieprawidłowe dane w
MISSING_REQUIRED_FIELD: 'Opuszczono wymagane pole:'
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

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

@@ -0,0 +1,55 @@
INFLECTOR_UNCOUNTABLE:
1: informação
2: arroz
3: dinheiro
INFLECTOR_IRREGULAR:
man: homens
sex: sexos
NICETIME:
SECOND: segundo
MINUTE: minuto
HOUR: hora
DAY: dia
WEEK: semana
MONTH: mês
YEAR: ano
DECADE: década
SEC: seg
MIN: mín
MO: mês
YR: ano
SECOND_PLURAL: segundos
MINUTE_PLURAL: minutos
HOUR_PLURAL: horas
DAY_PLURAL: dias
WEEK_PLURAL: semanas
MONTH_PLURAL: meses
YEAR_PLURAL: anos
DECADE_PLURAL: décadas
SEC_PLURAL: seg
MIN_PLURAL: mins
HR_PLURAL: hrs
YR_PLURAL: anos
FORM:
VALIDATION_FAIL: '<b>Validação falhada: </b>'
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

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

@@ -0,0 +1,20 @@
MONTHS_OF_THE_YEAR:
0: Ianuarie
1: Februarie
2: Martie
3: Aprilue
4: Mai
5: Iunie
6: Iulie
8: Septembrie
9: Octombrie
10: Noiembrie
11: Decembrie
DAYS_OF_THE_WEEK:
- Luni
- Marti
- Miercuri
- Joi
- Vineri
- Sâmbătă
- Duminică

View File

@@ -1,43 +1,66 @@
INFLECTOR_IRREGULAR:
'person': 'люди'
'man': 'человек'
'child': 'ребенок'
'sex': 'пол'
'move': 'движется'
person: люди
man: человек
child: ребенок
sex: пол
move: движется
NICETIME:
NO_DATE_PROVIDED: Дата не указана
BAD_DATE: Неверная дата
AGO: назад
FROM_NOW: теперь
SECOND: секунда
MINUTE: минута
HOUR: час
DAY: день
WEEK: неделя
MONTH: месяц
YEAR: год
DECADE: десятилетие
SEC: с
MIN: мин
HR: ч
DAY: д
WK: нед
MO: мес
YR: г.
DEC: гг.
SECOND_PLURAL: секунды
MINUTE_PLURAL: минуты
HOUR_PLURAL: часы
DAY_PLURAL: дни
WEEK_PLURAL: недели
MONTH_PLURAL: месяцы
YEAR_PLURAL: годы
DECADE_PLURAL: десятилетия
SEC_PLURAL: с
MIN_PLURAL: мин
HR_PLURAL: ч
DAY_PLURAL: д
WK_PLURAL: нед
MO_PLURAL: мес
YR_PLURAL: г.
DEC_PLURAL: гг.
NO_DATE_PROVIDED: Дата не указана
BAD_DATE: Неверная дата
AGO: назад
FROM_NOW: теперь
SECOND: секунда
MINUTE: минута
HOUR: час
DAY: д
WEEK: неделя
MONTH: месяц
YEAR: год
DECADE: десятилетие
SEC: с
MIN: мин
HR: ч
WK: нед
MO: мес
YR: г.
DEC: гг.
SECOND_PLURAL: секунды
MINUTE_PLURAL: минуты
HOUR_PLURAL: часы
DAY_PLURAL: д
WEEK_PLURAL: недели
MONTH_PLURAL: месяцы
YEAR_PLURAL: годы
DECADE_PLURAL: десятилетия
SEC_PLURAL: с
MIN_PLURAL: мин
HR_PLURAL: ч
WK_PLURAL: нед
MO_PLURAL: мес
YR_PLURAL: г.
DEC_PLURAL: гг.
FORM:
VALIDATION_FAIL: '<b>Проверка не удалась:</b>'
INVALID_INPUT: Неверный ввод в
MISSING_REQUIRED_FIELD: 'Отсутствует необходимое поле:'
MONTHS_OF_THE_YEAR:
- Январь
- Февраль
- Март
- Апрель
- Май
- Июнь
- Июль
- Август
- Сентябрь
- Октябрь
- Ноябрь
- Декабрь
DAYS_OF_THE_WEEK:
- Понедельник
- Вторник
- Среда
- Четверг
- Пятница
- Суббота
- Воскресенье

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

@@ -0,0 +1,2 @@
NICETIME:
DAY: dag

View File

@@ -1,37 +1,35 @@
NICETIME:
NO_DATE_PROVIDED: Tarih yok
BAD_DATE: Yanlış tarih
AGO: önce
FROM_NOW: (şimdiden)
SECOND: saniye
MINUTE: dakika
HOUR: saat
DAY: gün
WEEK: hafta
MONTH: ay
YEAR: yıl
DECADE: onyıl
SEC: sn
MIN: dk
HR: sa
DAY: gün
WK: hft
MO: ay
YR: yl
DEC: onyl
SECOND_PLURAL: saniye
MINUTE_PLURAL: dakika
HOUR_PLURAL: saat
DAY_PLURAL: gün
WEEK_PLURAL: hafta
MONTH_PLURAL: ay
YEAR_PLURAL: yıl
DECADE_PLURAL: onyıl
SEC_PLURAL: sn
MIN_PLURAL: dk
HR_PLURAL: sa
DAY_PLURAL: gün
WK_PLURAL: hft
MO_PLURAL: ay
YR_PLURAL: yl
DEC_PLURAL: onyl
NO_DATE_PROVIDED: Tarih yok
BAD_DATE: Yanlış tarih
AGO: önce
FROM_NOW: (şimdiden)
SECOND: saniye
MINUTE: dakika
HOUR: saat
DAY: gün
WEEK: hafta
MONTH: ay
YEAR: yıl
DECADE: onyıl
SEC: sn
MIN: dk
HR: sa
WK: hft
MO: ay
YR: yl
DEC: onyl
SECOND_PLURAL: saniye
MINUTE_PLURAL: dakika
HOUR_PLURAL: saat
DAY_PLURAL: gün
WEEK_PLURAL: hafta
MONTH_PLURAL: ay
YEAR_PLURAL: yıl
DECADE_PLURAL: onyıl
SEC_PLURAL: sn
MIN_PLURAL: dk
HR_PLURAL: sa
WK_PLURAL: hft
MO_PLURAL: ay
YR_PLURAL: yl
DEC_PLURAL: onyl

View File

@@ -8,6 +8,7 @@ use Grav\Common\Config\Config;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use RegexIterator;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
define('CSS_ASSET', true);
define('JS_ASSET', false);
@@ -64,11 +65,12 @@ class Assets
protected $js_pipeline = false;
// The asset holding arrays
protected $collections = array();
protected $css = array();
protected $js = array();
protected $inline_css = array();
protected $inline_js = array();
protected $collections = [];
protected $css = [];
protected $js = [];
protected $inline_css = [];
protected $inline_js = [];
protected $imports = [];
// Some configuration variables
protected $config;
@@ -84,10 +86,15 @@ class Assets
protected $js_minify = true;
// Arrays to hold assets that should NOT be pipelined
protected $css_no_pipeline = array();
protected $js_no_pipeline = array();
protected $css_no_pipeline = [];
protected $js_no_pipeline = [];
public function __construct(array $options = array())
/**
* Assets constructor.
*
* @param array $options
*/
public function __construct(array $options = [])
{
// Forward config options
if ($options) {
@@ -163,7 +170,6 @@ class Assets
$this->timestamp = '?' . self::getGrav()['cache']->getKey();
}
return $this;
}
@@ -177,16 +183,16 @@ class Assets
$base_url = self::getGrav()['base_url'];
$asset_config = (array)$config->get('system.assets');
/** @var Locator $locator */
/** @var UniformResourceLocator $locator */
$locator = self::$grav['locator'];
$this->assets_dir = self::getGrav()['locator']->findResource('asset://') . DS;
$this->assets_url = self::getGrav()['locator']->findResource('asset://', false);
$this->assets_dir = $locator->findResource('asset://') . DS;
$this->assets_url = $locator->findResource('asset://', false);
$this->config($asset_config);
$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);
}
}
@@ -237,9 +243,9 @@ class Assets
* You may add more than one asset passing an array as argument.
*
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @param bool $pipeline false if this should not be pipelined
* @param null $group
* @param int $priority the priority, bigger comes first
* @param bool $pipeline false if this should not be pipelined
* @param null $group
*
* @return $this
*/
@@ -249,9 +255,11 @@ class Assets
foreach ($asset as $a) {
$this->addCss($a, $priority, $pipeline, $group);
}
return $this;
} elseif (isset($this->collections[$asset])) {
$this->add($this->collections[$asset], $priority, $pipeline, $group);
$this->addCss($this->collections[$asset], $priority, $pipeline, $group);
return $this;
}
@@ -268,12 +276,12 @@ class Assets
'asset' => $asset,
'priority' => intval($priority ?: 10),
'order' => count($this->css),
'pipeline' => (bool) $pipeline,
'group' => $group ?: 'head'
'pipeline' => (bool)$pipeline,
'group' => $group ?: 'head'
];
// check for dynamic array and merge with defaults
if (func_num_args() == 2) {
if (func_num_args() > 1) {
$dynamic_arg = func_get_arg(1);
if (is_array($dynamic_arg)) {
$data = array_merge($data, $dynamic_arg);
@@ -294,11 +302,12 @@ class Assets
* It checks for duplicates.
* You may add more than one asset passing an array as argument.
*
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @param bool $pipeline false if this should not be pipelined
* @param string $loading how the asset is loaded (async/defer)
* @param string $group name of the group
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @param bool $pipeline false if this should not be pipelined
* @param string $loading how the asset is loaded (async/defer)
* @param string $group name of the group
*
* @return $this
*/
public function addJs($asset, $priority = null, $pipeline = true, $loading = null, $group = null)
@@ -307,9 +316,11 @@ class Assets
foreach ($asset as $a) {
$this->addJs($a, $priority, $pipeline, $loading, $group);
}
return $this;
} elseif (isset($this->collections[$asset])) {
$this->add($this->collections[$asset], $priority, $pipeline, $loading, $group);
$this->addJs($this->collections[$asset], $priority, $pipeline, $loading, $group);
return $this;
}
@@ -326,16 +337,16 @@ class Assets
'asset' => $asset,
'priority' => intval($priority ?: 10),
'order' => count($this->js),
'pipeline' => (bool) $pipeline,
'pipeline' => (bool)$pipeline,
'loading' => $loading ?: '',
'group' => $group ?: 'head'
'group' => $group ?: 'head'
];
// check for dynamic array and merge with defaults
if (func_num_args() == 2) {
if (func_num_args() > 1) {
$dynamic_arg = func_get_arg(1);
if (is_array($dynamic_arg)) {
$data = array_merge($data, $dynamic_arg);
$data = array_merge($data, $dynamic_arg);
}
}
@@ -350,9 +361,9 @@ class Assets
/**
* Convenience wrapper for async loading of JavaScript
*
* @param $asset
* @param int $priority
* @param bool $pipeline
* @param $asset
* @param int $priority
* @param bool $pipeline
* @param string $group name of the group
*
* @deprecated Please use dynamic method with ['loading' => 'async']
@@ -367,9 +378,9 @@ class Assets
/**
* Convenience wrapper for deferred loading of JavaScript
*
* @param $asset
* @param int $priority
* @param bool $pipeline
* @param $asset
* @param int $priority
* @param bool $pipeline
* @param string $group name of the group
*
* @deprecated Please use dynamic method with ['loading' => 'defer']
@@ -388,8 +399,8 @@ class Assets
* For adding chunks of string-based inline CSS
*
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @param null $group
* @param int $priority the priority, bigger comes first
* @param null $group
*
* @return $this
*/
@@ -398,21 +409,20 @@ class Assets
$asset = trim($asset);
if (is_a($asset, 'Twig_Markup')) {
preg_match(self::HTML_TAG_REGEX, $asset, $matches );
if (isset($matches[3])) {
preg_match(self::HTML_TAG_REGEX, $asset, $matches);
if (isset($matches[3])) {
$asset = $matches[3];
}
}
$data = [
'priority' => intval($priority ?: 10),
'order' => count($this->inline_css),
'asset' => $asset,
'group' => $group ?: 'head'
'priority' => intval($priority ?: 10),
'order' => count($this->inline_css),
'asset' => $asset,
'group' => $group ?: 'head'
];
// check for dynamic array and merge with defaults
$count_args = func_num_args();
if (func_num_args() == 2) {
$dynamic_arg = func_get_arg(1);
if (is_array($dynamic_arg)) {
@@ -436,7 +446,7 @@ class Assets
*
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @param string $group name of the group
* @param string $group name of the group
*
* @return $this
*/
@@ -445,8 +455,8 @@ class Assets
$asset = trim($asset);
if (is_a($asset, 'Twig_Markup')) {
preg_match(self::HTML_TAG_REGEX, $asset, $matches );
if (isset($matches[3])) {
preg_match(self::HTML_TAG_REGEX, $asset, $matches);
if (isset($matches[3])) {
$asset = $matches[3];
}
}
@@ -455,11 +465,10 @@ class Assets
'asset' => $asset,
'priority' => intval($priority ?: 10),
'order' => count($this->js),
'group' => $group ?: 'head'
'group' => $group ?: 'head'
];
// check for dynamic array and merge with defaults
$count_args = func_num_args();
if (func_num_args() == 2) {
$dynamic_arg = func_get_arg(1);
if (is_array($dynamic_arg)) {
@@ -479,29 +488,31 @@ class Assets
* Build the CSS link tags.
*
* @param string $group name of the group
* @param array $attributes
* @param array $attributes
*
* @return string
*/
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'];
}
return $a['priority'] - $b['priority'];
});
}
@@ -552,28 +563,30 @@ class Assets
* Build the JavaScript script tags.
*
* @param string $group name of the group
* @param array $attributes
* @param array $attributes
*
* @return string
*/
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'];
}
return $a['priority'] - $b['priority'];
});
@@ -592,7 +605,7 @@ class Assets
}
foreach ($this->js_no_pipeline as $file) {
if ($group && $file['group'] == $group) {
$output .= '<script src="' . $file['asset'] . $this->timestamp . '"' . $attributes . ' ' . $file['loading']. '></script>' . "\n";
$output .= '<script src="' . $file['asset'] . $this->timestamp . '"' . $attributes . ' ' . $file['loading'] . '></script>' . "\n";
}
}
} else {
@@ -618,9 +631,11 @@ class Assets
}
/**
* Minify and concatenate CSS.
* Minify and concatenate CSS
*
* @return string
* @param string $group
*
* @return bool|string
*/
protected function pipelineCss($group = 'head')
{
@@ -679,6 +694,7 @@ class Assets
// Write file
if (strlen(trim($buffer)) > 0) {
file_put_contents($absolute_path, $buffer);
return $relative_path . $key;
} else {
return false;
@@ -688,6 +704,8 @@ class Assets
/**
* Minify and concatenate JS files.
*
* @param string $group
*
* @return string
*/
protected function pipelineJs($group = 'head')
@@ -737,6 +755,7 @@ class Assets
// Write file
if (strlen(trim($buffer)) > 0) {
file_put_contents($absolute_path, $buffer);
return $relative_path . $key;
} else {
return false;
@@ -782,9 +801,7 @@ class Assets
*/
public function exists($asset)
{
if (isset($this->collections[$asset]) ||
isset($this->css[$asset]) ||
isset($this->js[$asset])) {
if (isset($this->collections[$asset]) || isset($this->css[$asset]) || isset($this->js[$asset])) {
return true;
} else {
return false;
@@ -826,7 +843,8 @@ class Assets
*/
public function resetJs()
{
$this->js = array();
$this->js = [];
$this->inline_js = [];
return $this;
}
@@ -838,15 +856,28 @@ class Assets
*/
public function resetCss()
{
$this->css = array();
$this->css = [];
$this->inline_css = [];
return $this;
}
/**
* Add all CSS assets within $directory (relative to public dir).
* Add all JavaScript assets within $directory
*
* @param string $directory Relative to $this->public_dir
* @param string $directory Relative to the Grav root path, or a stream identifier
*
* @return $this
*/
public function addDirJs($directory)
{
return $this->addDir($directory, self::JS_REGEX);
}
/**
* Add all CSS assets within $directory
*
* @param string $directory Relative to the Grav root path, or a stream identifier
*
* @return $this
*/
@@ -858,7 +889,7 @@ class Assets
/**
* Add all assets matching $pattern within $directory.
*
* @param string $directory Relative to $this->public_dir
* @param string $directory Relative to the Grav root path, or a stream identifier
* @param string $pattern (regex)
*
* @return $this
@@ -866,13 +897,15 @@ class Assets
*/
public function addDir($directory, $pattern = self::DEFAULT_REGEX)
{
// Check if public_dir exists
if (!is_dir($this->assets_dir)) {
throw new Exception('Assets: Public dir not found');
$root_dir = rtrim(ROOT_DIR, '/');
// Check if $directory is a stream.
if (strpos($directory, '://')) {
$directory = self::$grav['locator']->findResource($directory, null);
}
// Get files
$files = $this->rglob($this->assets_dir . DIRECTORY_SEPARATOR . $directory, $pattern, $this->assets_dir);
$files = $this->rglob($root_dir . DIRECTORY_SEPARATOR . $directory, $pattern, $root_dir . '/');
// No luck? Nothing to do
if (!$files) {
@@ -881,27 +914,25 @@ class Assets
// Add CSS files
if ($pattern === self::CSS_REGEX) {
$this->css = array_unique(array_merge($this->css, $files));
foreach ($files as $file) {
$this->addCss($file);
}
return $this;
}
// Add JavaScript files
if ($pattern === self::JS_REGEX) {
$this->js = array_unique(array_merge($this->js, $files));
foreach ($files as $file) {
$this->addJs($file);
}
return $this;
}
// Unknown pattern. We must poll to know the extension :(
// Unknown pattern.
foreach ($files as $asset) {
$info = pathinfo($asset);
if (isset($info['extension'])) {
$ext = strtolower($info['extension']);
if ($ext === 'css' && !in_array($asset, $this->css)) {
$this->css[] = $asset;
} elseif ($ext === 'js' && !in_array($asset, $this->js)) {
$this->js[] = $asset;
}
}
$this->add($asset);
}
return $this;
@@ -918,8 +949,8 @@ class Assets
*/
protected function isRemoteLink($link)
{
return ('http://' === substr($link, 0, 7) || 'https://' === substr($link, 0, 8)
|| '//' === substr($link, 0, 2));
return ('http://' === substr($link, 0, 7) || 'https://' === substr($link, 0, 8) || '//' === substr($link, 0,
2));
}
/**
@@ -972,18 +1003,18 @@ class Assets
* Download and concatenate the content of several links.
*
* @param array $links
* @param bool $css
* @param bool $css
*
* @return string
*/
protected function gatherLinks(array $links, $css = true)
{
$buffer = '';
$local = true;
foreach ($links as $asset) {
$relative_dir = '';
$link = $asset['asset'];
$relative_path = $link;
@@ -1034,8 +1065,8 @@ class Assets
/**
* Finds relative CSS urls() and rewrites the URL with an absolute one
*
* @param $file the css source file
* @param $relative_path relative path to the css file
* @param string $file the css source file
* @param string $relative_path relative path to the css file
*
* @return mixed
*/
@@ -1046,23 +1077,19 @@ class Assets
// Find any css url() elements, grab the URLs and calculate an absolute path
// Then replace the old url with the new one
$file = preg_replace_callback(
self::CSS_URL_REGEX,
function ($matches) use ($relative_path) {
$file = preg_replace_callback(self::CSS_URL_REGEX, function ($matches) use ($relative_path) {
$old_url = $matches[1];
$old_url = $matches[1];
// ensure this is not a data url
if (strpos($old_url, 'data:') === 0) {
return $matches[0];
}
// ensure this is not a data url
if (strpos($old_url, 'data:') === 0) {
return $matches[0];
}
$new_url = $this->base_url . ltrim(Utils::normalizePath($relative_path . '/' . $old_url), '/');
$new_url = $this->base_url . ltrim(Utils::normalizePath($relative_path . '/' . $old_url), '/');
return str_replace($old_url, $new_url, $matches[0]);
},
$file
);
return str_replace($old_url, $new_url, $matches[0]);
}, $file);
return $file;
}
@@ -1076,16 +1103,13 @@ class Assets
*/
protected function moveImports($file)
{
$this->imports = array();
$this->imports = [];
$file = preg_replace_callback(
self::CSS_IMPORT_REGEX,
function ($matches) {
$this->imports[] = $matches[0];
return '';
},
$file
);
$file = preg_replace_callback(self::CSS_IMPORT_REGEX, function ($matches) {
$this->imports[] = $matches[0];
return '';
}, $file);
return implode("\n", $this->imports) . "\n\n" . $file;
}
@@ -1101,17 +1125,10 @@ class Assets
*/
protected function rglob($directory, $pattern, $ltrim = null)
{
$iterator = new RegexIterator(
new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(
$directory,
FilesystemIterator::SKIP_DOTS
)
),
$pattern
);
$iterator = new RegexIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory,
FilesystemIterator::SKIP_DOTS)), $pattern);
$offset = strlen($ltrim);
$files = array();
$files = [];
foreach ($iterator as $file) {
$files[] = substr($file->getPathname(), $offset);
@@ -1120,18 +1137,6 @@ class Assets
return $files;
}
/**
* Add all JavaScript assets within $directory.
*
* @param string $directory Relative to $this->public_dir
*
* @return $this
*/
public function addDirJs($directory)
{
return $this->addDir($directory, self::JS_REGEX);
}
/**
* Sets the state of CSS Pipeline
*
@@ -1139,7 +1144,7 @@ class Assets
*/
public function setCssPipeline($value)
{
$this->css_pipeline = (bool) $value;
$this->css_pipeline = (bool)$value;
}
/**
@@ -1149,7 +1154,7 @@ class Assets
*/
public function setJsPipeline($value)
{
$this->js_pipeline = (bool) $value;
$this->js_pipeline = (bool)$value;
}
/**
@@ -1159,9 +1164,12 @@ class Assets
*/
public function setTimestamp($value)
{
$this->timestamp = '?'.$value;
$this->timestamp = '?' . $value;
}
/**
* @return string
*/
public function __toString()
{
return '';

View File

@@ -29,6 +29,14 @@ class ZipBackup
'.idea'
];
/**
* Backup
*
* @param null $destination
* @param callable|null $messager
*
* @return null|string
*/
public static function backup($destination = null, callable $messager = null)
{
if (!$destination) {
@@ -64,6 +72,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 +95,10 @@ class ZipBackup
$zip->close();
if ($max_execution_time !== false) {
ini_set('max_execution_time', $max_execution_time);
}
return $destination;
}

View File

@@ -2,13 +2,20 @@
namespace Grav\Common;
/**
* Simple wrapper for the very simple parse_user_agent() function
* Handles browser and platform versions
*
* Internally uses the PhpUserAgent package https://github.com/donatj/PhpUserAgent
*
* @author RocketTheme
* @license MIT
*/
class Browser
{
protected $useragent = [];
/**
* Browser constructor.
*/
public function __construct()
{
try {
@@ -18,29 +25,99 @@ class Browser
}
}
/**
* Get the current browser identifier
*
* Currently detected browsers:
*
* Android Browser
* BlackBerry Browser
* Camino
* Kindle / Silk
* Firefox / Iceweasel
* Safari
* Internet Explorer
* IEMobile
* Chrome
* Opera
* Midori
* Vivaldi
* TizenBrowser
* Lynx
* Wget
* Curl
*
* @return string the lowercase browser name
*/
public function getBrowser()
{
return strtolower($this->useragent['browser']);
}
/**
* Get the current platform identifier
*
* Currently detected platforms:
*
* Desktop
* -> Windows
* -> Linux
* -> Macintosh
* -> Chrome OS
* Mobile
* -> Android
* -> iPhone
* -> iPad / iPod Touch
* -> Windows Phone OS
* -> Kindle
* -> Kindle Fire
* -> BlackBerry
* -> Playbook
* -> Tizen
* Console
* -> Nintendo 3DS
* -> New Nintendo 3DS
* -> Nintendo Wii
* -> Nintendo WiiU
* -> PlayStation 3
* -> PlayStation 4
* -> PlayStation Vita
* -> Xbox 360
* -> Xbox One
*
* @return string the lowercase platform name
*/
public function getPlatform()
{
return strtolower($this->useragent['platform']);
}
/**
* Get the current full version identifier
*
* @return string the browser full version identifier
*/
public function getLongVersion()
{
return $this->useragent['version'];
}
/**
* Get the current major version identifier
*
* @return string the browser major version identifier
*/
public function getVersion()
{
$version = explode('.', $this->getLongVersion());
return intval($version[0]);
}
/**
* Determine if the request comes from a human, or from a bot/crawler
*
* @return bool
*/
public function isHuman()
{

View File

@@ -1,7 +1,7 @@
<?php
namespace Grav\Common;
use \Doctrine\Common\Cache\Cache as DoctrineCache;
use \Doctrine\Common\Cache as DoctrineCache;
use Grav\Common\Config\Config;
use Grav\Common\Filesystem\Folder;
@@ -16,7 +16,7 @@ use Grav\Common\Filesystem\Folder;
* MemCacheD
* FileSystem
*
* @author RocketTheme
* @author RocketTheme
* @license MIT
*/
class Cache extends Getters
@@ -31,15 +31,18 @@ class Cache extends Getters
protected $lifetime;
protected $now;
/** @var Config $config */
protected $config;
/**
* @var DoctrineCache
* @var DoctrineCache\CacheProvider
*/
protected $driver;
protected $driver_name;
protected $driver_setting;
/**
* @var bool
*/
@@ -77,7 +80,7 @@ class Cache extends Getters
/**
* Constructor
*
* @params Grav $grav
* @param Grav $grav
*/
public function __construct(Grav $grav)
{
@@ -88,6 +91,7 @@ class Cache extends Getters
* Initialization that sets a base key and the driver based on configuration settings
*
* @param Grav $grav
*
* @return void
*/
public function init(Grav $grav)
@@ -103,10 +107,13 @@ class Cache extends Getters
$prefix = $this->config->get('system.cache.prefix');
$this->enabled = (bool) $this->config->get('system.cache.enabled');
$this->enabled = (bool)$this->config->get('system.cache.enabled');
// 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->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();
@@ -114,7 +121,7 @@ class Cache extends Getters
$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 . ']');
}
@@ -123,15 +130,17 @@ class Cache extends Getters
* If there is no config option for $driver in the config, or it's set to 'auto', it will
* pick the best option based on which cache extensions are installed.
*
* @return DoctrineCacheDriver The cache driver to use
* @return DoctrineCache\CacheProvider The cache driver to use
*/
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';
@@ -146,36 +155,40 @@ class Cache extends Getters
switch ($driver_name) {
case 'apc':
$driver = new \Doctrine\Common\Cache\ApcCache();
$driver = new DoctrineCache\ApcCache();
break;
case 'apcu':
$driver = new DoctrineCache\ApcuCache();
break;
case 'wincache':
$driver = new \Doctrine\Common\Cache\WinCacheCache();
$driver = new DoctrineCache\WinCacheCache();
break;
case 'xcache':
$driver = new \Doctrine\Common\Cache\XcacheCache();
$driver = new DoctrineCache\XcacheCache();
break;
case 'memcache':
$memcache = new \Memcache();
$memcache->connect($this->config->get('system.cache.memcache.server','localhost'),
$this->config->get('system.cache.memcache.port', 11211));
$driver = new \Doctrine\Common\Cache\MemcacheCache();
$memcache->connect($this->config->get('system.cache.memcache.server', 'localhost'),
$this->config->get('system.cache.memcache.port', 11211));
$driver = new DoctrineCache\MemcacheCache();
$driver->setMemcache($memcache);
break;
case 'redis':
$redis = new \Redis();
$redis->connect($this->config->get('system.cache.redis.server','localhost'),
$this->config->get('system.cache.redis.port', 6379));
$redis->connect($this->config->get('system.cache.redis.server', 'localhost'),
$this->config->get('system.cache.redis.port', 6379));
$driver = new \Doctrine\Common\Cache\RedisCache();
$driver = new DoctrineCache\RedisCache();
$driver->setRedis($redis);
break;
default:
$driver = new \Doctrine\Common\Cache\FilesystemCache($this->cache_dir);
$driver = new DoctrineCache\FilesystemCache($this->cache_dir);
break;
}
@@ -186,6 +199,7 @@ class Cache extends Getters
* Gets a cached entry if it exists based on an id. If it does not exist, it returns false
*
* @param string $id the id of the cached entry
*
* @return object returns the cached entry, can be any type, or false if doesn't exist
*/
public function fetch($id)
@@ -200,9 +214,9 @@ class Cache extends Getters
/**
* Stores a new cached entry.
*
* @param string $id the id of the cached entry
* @param string $id the id of the cached entry
* @param array|object $data the data for the cached entry to store
* @param int $lifetime the lifetime to store the entry in seconds
* @param int $lifetime the lifetime to store the entry in seconds
*/
public function save($id, $data, $lifetime = null)
{
@@ -225,7 +239,7 @@ class Cache extends Getters
/**
* Helper method to clear all Grav caches
*
* @param string $remove standard|all|assets-only|images-only|cache-only
* @param string $remove standard|all|assets-only|images-only|cache-only
*
* @return array
*/
@@ -235,7 +249,7 @@ class Cache extends Getters
$output = [];
$user_config = USER_DIR . 'config/system.yaml';
switch($remove) {
switch ($remove) {
case 'all':
$remove_paths = self::$all_remove;
break;
@@ -258,8 +272,9 @@ class Cache extends Getters
// Convert stream to a real path
$path = $locator->findResource($stream, true, true);
// Make sure path exists before proceeding, otherwise we would wipe ROOT_DIR
if (!$path)
if (!$path) {
throw new \RuntimeException("Stream '{$stream}' not found", 500);
}
$anything = false;
$files = glob($path . '/*');

View File

@@ -35,6 +35,11 @@ class Composer
return $path;
}
/**
* Return the composer executable file path
*
* @return string
*/
public static function getComposerExecutor()
{
$executor = PHP_BINARY . ' ';

View File

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

View File

@@ -158,7 +158,7 @@ class Setup extends Data
}
// Update streams.
foreach ($files as $path) {
foreach (array_reverse($files) as $path) {
$file = CompiledYamlFile::instance($path);
$content = $file->content();
if (!empty($content['schemes'])) {

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;
}
/**
@@ -551,6 +559,10 @@ class Validation
$options = isset($field['options']) ? array_keys($field['options']) : array();
$multi = isset($field['multiple']) ? $field['multiple'] : false;
if (count($values) == 1 && isset($values[0]) && $values[0] == '') {
return null;
}
if ($options) {
$useKey = isset($field['use']) && $field['use'] == 'keys';
foreach ($values as $key => $value) {

View File

@@ -1,8 +1,10 @@
<?php
namespace Grav\Common;
use DebugBar\DataCollector\ConfigCollector;
use DebugBar\JavascriptRenderer;
use DebugBar\StandardDebugBar;
use Grav\Common\Config\Config;
/**
* Class Debugger
@@ -10,44 +12,79 @@ use DebugBar\StandardDebugBar;
*/
class Debugger
{
/** @var Grav $grav */
protected $grav;
protected $debugbar;
/** @var Config $config */
protected $config;
/** @var JavascriptRenderer $renderer */
protected $renderer;
/** @var StandardDebugBar $debugbar */
protected $debugbar;
protected $enabled;
protected $timers = [];
/**
* Debugger constructor.
*/
public function __construct()
{
$this->debugbar = new StandardDebugBar();
$this->debugbar['time']->addMeasure('Loading', $this->debugbar['time']->getRequestStartTime(), microtime(true));
}
/**
* Initialize the debugger
*
* @return $this
* @throws \DebugBar\DebugBarException
*/
public function init()
{
$this->grav = Grav::instance();
$this->config = $this->grav['config'];
if ($this->enabled()) {
$this->debugbar->addCollector(new \DebugBar\DataCollector\ConfigCollector((array)$this->grav['config']->get('system')));
$this->debugbar->addCollector(new ConfigCollector((array)$this->config->get('system'), 'Config'));
$this->debugbar->addCollector(new ConfigCollector((array)$this->config->get('plugins'), 'Plugins'));
}
return $this;
}
/**
* Set/get the enabled state of the debugger
*
* @param bool $state If null, the method returns the enabled value. If set, the method sets the enabled state
*
* @return null
*/
public function enabled($state = null)
{
if (isset($state)) {
$this->enabled = $state;
} else {
if (!isset($this->enabled)) {
$this->enabled = $this->grav['config']->get('system.debugger.enabled');
$this->enabled = $this->config->get('system.debugger.enabled');
}
}
return $this->enabled;
}
/**
* Add the debugger assets to the Grav Assets
*
* @return $this
*/
public function addAssets()
{
if ($this->enabled()) {
/** @var Assets $assets */
$assets = $this->grav['assets'];
// Add jquery library
@@ -68,58 +105,113 @@ class Debugger
$assets->addJs($js);
}
}
return $this;
}
/**
* Adds a data collector
*
* @param $collector
*
* @return $this
* @throws \DebugBar\DebugBarException
*/
public function addCollector($collector)
{
$this->debugbar->addCollector($collector);
return $this;
}
/**
* Returns a data collector
*
* @param $collector
*
* @return \DebugBar\DataCollector\DataCollectorInterface
* @throws \DebugBar\DebugBarException
*/
public function getCollector($collector)
{
return $this->debugbar->getCollector($collector);
}
/**
* Displays the debug bar
*
* @return $this
*/
public function render()
{
if ($this->enabled()) {
echo $this->renderer->render();
}
return $this;
}
/**
* Sends the data through the HTTP headers
*
* @return $this
*/
public function sendDataInHeaders()
{
$this->debugbar->sendDataInHeaders();
return $this;
}
/**
* Start a timer with an associated name and description
*
* @param $name
* @param string|null $description
*
* @return $this
*/
public function startTimer($name, $description = null)
{
if ($name[0] == '_' || $this->grav['config']->get('system.debugger.enabled')) {
if ($name[0] == '_' || $this->config->get('system.debugger.enabled')) {
$this->debugbar['time']->startMeasure($name, $description);
$this->timers[] = $name;
}
return $this;
}
/**
* Stop the named timer
*
* @param string $name
*
* @return $this
*/
public function stopTimer($name)
{
if (in_array($name, $this->timers) && ($name[0] == '_' || $this->grav['config']->get('system.debugger.enabled'))) {
if (in_array($name, $this->timers) && ($name[0] == '_' || $this->config->get('system.debugger.enabled'))) {
$this->debugbar['time']->stopMeasure($name);
}
return $this;
}
/**
* Dump variables into the Messages tab of the Debug Bar
*
* @param $message
* @param string $label
* @param bool $isString
*
* @return $this
*/
public function addMessage($message, $label = 'info', $isString = true)
{
if ($this->enabled()) {
$this->debugbar['messages']->addMessage($message, $label, $isString);
}
return $this;
}
}

View File

@@ -2,51 +2,59 @@
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']);
}
}
$jsonRequest = $_SERVER && $_SERVER['HTTP_ACCEPT'] && $_SERVER['HTTP_ACCEPT'] == 'application/json';
// 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 (method_exists('Whoops\Util\Misc', 'isAjaxRequest')) { //Whoops 2.0
if (Whoops\Util\Misc::isAjaxRequest() || $jsonRequest) {
$whoops->pushHandler(new Whoops\Handler\JsonResponseHandler);
}
} elseif (function_exists('Whoops\isAjaxRequest')) { //Whoops 2.0.0-alpha
if (Whoops\isAjaxRequest() || $jsonRequest) {
$whoops->pushHandler(new Whoops\Handler\JsonResponseHandler);
}
} else { //Whoops 1.x
$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

@@ -64,8 +64,9 @@ abstract class Folder
/**
* Get relative path between target and base path. If path isn't relative, return full path.
*
* @param string $path
* @param string $base
* @param string $path
* @param mixed|string $base
*
* @return string
*/
public static function getRelativePath($path, $base = GRAV_ROOT)
@@ -141,7 +142,7 @@ abstract class Folder
* @return array
* @throws \RuntimeException
*/
public static function all($path, array $params = array())
public static function all($path, array $params = [])
{
if ($path === false) {
throw new \RuntimeException("Path to {$path} doesn't exist.");
@@ -166,7 +167,7 @@ abstract class Folder
$iterator = new \FilesystemIterator($path);
}
$results = array();
$results = [];
/** @var \RecursiveDirectoryIterator $file */
foreach ($iterator as $file) {

View File

@@ -3,12 +3,21 @@ namespace Grav\Common\Filesystem;
use Grav\Common\GravTrait;
/**
* Class RecursiveFolderFilterIterator
* @package Grav\Common\Filesystem
*/
class RecursiveFolderFilterIterator extends \RecursiveFilterIterator
{
use GravTrait;
protected static $folder_ignores;
/**
* Create a RecursiveFilterIterator from a RecursiveIterator
*
* @param RecursiveIterator $iterator
*/
public function __construct(\RecursiveIterator $iterator)
{
parent::__construct($iterator);
@@ -17,9 +26,13 @@ class RecursiveFolderFilterIterator extends \RecursiveFilterIterator
}
}
/**
* Check whether the current element of the iterator is acceptable
*
* @return bool true if the current element is acceptable, otherwise false.
*/
public function accept()
{
/** @var $current \SplFileInfo */
$current = $this->current();

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

@@ -121,6 +121,10 @@ class Installer
}
/**
* @param $state
* @param $install_path
*/
protected static function flightProcessing($state, $install_path)
{
$blueprints_path = $install_path . DS . 'blueprints.yaml';
@@ -140,6 +144,13 @@ class Installer
}
}
/**
* @param \ZipArchive $zip
* @param $install_path
* @param $tmp
*
* @return bool
*/
public static function moveInstall(\ZipArchive $zip, $install_path, $tmp)
{
$container = $zip->getNameIndex(0);
@@ -152,6 +163,13 @@ class Installer
return true;
}
/**
* @param \ZipArchive $zip
* @param $install_path
* @param $tmp
*
* @return bool
*/
public static function copyInstall(\ZipArchive $zip, $install_path, $tmp)
{
$firstDir = $zip->getNameIndex(0);
@@ -165,6 +183,13 @@ class Installer
return true;
}
/**
* @param \ZipArchive $zip
* @param $install_path
* @param $tmp
*
* @return bool
*/
public static function sophisticatedInstall(\ZipArchive $zip, $install_path, $tmp)
{
for ($i = 0, $l = $zip->numFiles; $i < $l; $i++) {
@@ -279,7 +304,9 @@ class Installer
*/
public static function lastErrorMsg()
{
$msg = 'Unknown Error';
if (is_string(self::$error)) {
return self::$error;
}
switch (self::$error) {
case 0:
@@ -315,7 +342,7 @@ class Installer
break;
default:
return 'Unknown error';
$msg = 'Unknown Error';
break;
}
@@ -333,7 +360,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

@@ -2,28 +2,38 @@
namespace Grav\Common\GPM;
use Grav\Common\Utils;
use Grav\Common\GravTrait;
/**
* Class Response
* @package Grav\Common\GPM
*/
class Response
{
use GravTrait;
/**
* 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 +61,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 +79,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 +97,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 +107,30 @@ 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
* Accepts a vsariable 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 +151,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 +167,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 +183,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()
@@ -216,6 +198,12 @@ class Response
$options = $args[1];
$callback = $args[2];
// if proxy set add that
$proxy_url = self::getGrav()['config']->get('system.proxy_url');
if ($proxy_url) {
$options['fopen']['proxy'] = $proxy_url;
}
if ($callback) {
$options['fopen']['notification'] = ['self', 'progress'];
}
@@ -229,4 +217,113 @@ 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::curlExecFollow($ch, $options, $callback);
$errno = curl_errno($ch);
if ($errno) {
$error_message = curl_strerror($errno);
throw new \RuntimeException("cURL error ({$errno}):\n {$error_message}");
}
curl_close($ch);
return $response;
}
/**
* @param $ch
* @param $options
* @param $callback
*
* @return bool|mixed
*/
private static function curlExecFollow($ch, $options, $callback)
{
if ($callback) {
curl_setopt_array(
$ch,
[
CURLOPT_NOPROGRESS => false,
CURLOPT_PROGRESSFUNCTION => ['self', 'progress']
]
);
}
// if proxy set add that
$proxy_url = self::getGrav()['config']->get('system.proxy_url');
if ($proxy_url) {
$options['curl'][CURLOPT_PROXY] = $proxy_url;
}
// 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

@@ -5,7 +5,7 @@ namespace Grav\Common;
* Abstract class to implement magic __get(), __set(), __isset() and __unset().
* Also implements ArrayAccess.
*
* @author RocketTheme
* @author RocketTheme
* @license MIT
*/
abstract class Getters implements \ArrayAccess, \Countable
@@ -32,6 +32,7 @@ abstract class Getters implements \ArrayAccess, \Countable
* Magic getter method
*
* @param mixed $offset Medium name value
*
* @return mixed Medium value
*/
public function __get($offset)
@@ -42,7 +43,8 @@ abstract class Getters implements \ArrayAccess, \Countable
/**
* Magic method to determine if the attribute is set
*
* @param mixed $offset Medium name value
* @param mixed $offset Medium name value
*
* @return boolean True if the value is set
*/
public function __isset($offset)
@@ -62,12 +64,14 @@ abstract class Getters implements \ArrayAccess, \Countable
/**
* @param mixed $offset
*
* @return bool
*/
public function offsetExists($offset)
{
if ($this->gettersVariable) {
$var = $this->gettersVariable;
return isset($this->{$var}[$offset]);
} else {
return isset($this->{$offset});
@@ -76,12 +80,14 @@ abstract class Getters implements \ArrayAccess, \Countable
/**
* @param mixed $offset
*
* @return mixed
*/
public function offsetGet($offset)
{
if ($this->gettersVariable) {
$var = $this->gettersVariable;
return isset($this->{$var}[$offset]) ? $this->{$var}[$offset] : null;
} else {
return isset($this->{$offset}) ? $this->{$offset} : null;
@@ -137,13 +143,17 @@ abstract class Getters implements \ArrayAccess, \Countable
{
if ($this->gettersVariable) {
$var = $this->gettersVariable;
return $this->{$var};
} else {
$properties = (array) $this;
$list = array();
$properties = (array)$this;
$list = [];
foreach ($properties as $property => $value) {
if ($property[0] != "\0") $list[$property] = $value;
if ($property[0] != "\0") {
$list[$property] = $value;
}
}
return $list;
}
}

View File

@@ -1,8 +1,11 @@
<?php
namespace Grav\Common;
use Grav\Common\Config\Config;
use Grav\Common\Language\Language;
use Grav\Common\Page\Medium\ImageMedium;
use Grav\Common\Page\Medium\Medium;
use Grav\Common\Page\Page;
use Grav\Common\Page\Pages;
use Grav\Common\Service\ConfigServiceProvider;
use Grav\Common\Service\ErrorServiceProvider;
@@ -16,8 +19,8 @@ use RocketTheme\Toolbox\Event\EventDispatcher;
/**
* Grav
*
* @author Andy Miller
* @link http://www.rockettheme.com
* @author Andy Miller
* @link http://www.rockettheme.com
* @license http://opensource.org/licenses/MIT
*
* Influenced by Pico, Stacey, Kirby, PieCrust and other great platforms...
@@ -34,7 +37,14 @@ class Grav extends Container
*/
protected static $instance;
public static function instance(array $values = array())
/**
* Return the Grav instance. Create it if it's not already instanced
*
* @param array $values
*
* @return Grav
*/
public static function instance(array $values = [])
{
if (!self::$instance) {
self::$instance = static::load($values);
@@ -51,61 +61,77 @@ class Grav extends Container
return self::$instance;
}
/**
* Initialize and return a Grav instance
*
* @param array $values
*
* @return static
*/
protected static function load(array $values)
{
$container = new static($values);
$container['grav'] = $container;
$container['debugger'] = new Debugger();
$container['debugger']->startTimer('_init', 'Initialize');
$container['debugger']->startTimer('_services', 'Services');
$container->register(new LoggerServiceProvider);
$container->register(new ErrorServiceProvider);
$container['uri'] = function ($c) {
/** @var Grav $c */
return new Uri($c);
};
$container['task'] = function ($c) {
/** @var Grav $c */
return !empty($_POST['task']) ? $_POST['task'] : $c['uri']->param('task');
};
$container['events'] = function ($c) {
$container['events'] = function () {
return new EventDispatcher;
};
$container['cache'] = function ($c) {
/** @var Grav $c */
return new Cache($c);
};
$container['session'] = function ($c) {
/** @var Grav $c */
return new Session($c);
};
$container['plugins'] = function ($c) {
$container['plugins'] = function () {
return new Plugins();
};
$container['themes'] = function ($c) {
/** @var Grav $c */
return new Themes($c);
};
$container['twig'] = function ($c) {
/** @var Grav $c */
return new Twig($c);
};
$container['taxonomy'] = function ($c) {
/** @var Grav $c */
return new Taxonomy($c);
};
$container['language'] = function ($c) {
/** @var Grav $c */
return new Language($c);
};
$container['pages'] = function ($c) {
return new Page\Pages($c);
/** @var Grav $c */
return new Pages($c);
};
$container['assets'] = new Assets();
$container['page'] = function ($c) {
/** @var Grav $c */
/** @var Pages $pages */
$pages = $c['pages'];
/** @var Language $language */
@@ -140,7 +166,7 @@ class Grav extends Container
if (!$page || !$page->routable()) {
// Try fallback URL stuff...
$c->fallbackUrl($page, $path);
$c->fallbackUrl($path);
// If no page found, fire event
$event = $c->fireEvent('onPageNotFound');
@@ -151,23 +177,17 @@ class Grav extends Container
throw new \RuntimeException('Page Not Found', 404);
}
}
return $page;
};
$container['output'] = function ($c) {
/** @var Grav $c */
return $c['twig']->processSite($c['uri']->extension());
};
$container['browser'] = function ($c) {
return new Browser();
};
$container['base_url_absolute'] = function ($c) {
return $c['config']->get('system.base_url_absolute') ?: $c['uri']->rootUrl(true);
};
$container['base_url_relative'] = function ($c) {
return $c['config']->get('system.base_url_relative') ?: $c['uri']->rootUrl(false);
};
$container['base_url'] = function ($c) {
return $c['config']->get('system.absolute_urls') ? $c['base_url_absolute'] : $c['base_url_relative'];
$container['browser'] = function () {
return new Browser();
};
$container->register(new StreamsServiceProvider);
@@ -175,53 +195,64 @@ class Grav extends Container
$container['inflector'] = new Inflector();
$container['debugger']->stopTimer('_init');
$container['debugger']->stopTimer('_services');
return $container;
}
/**
* Process a request
*/
public function process()
{
/** @var Debugger $debugger */
$debugger = $this['debugger'];
// Load site setup and initializing streams.
$debugger->startTimer('_setup', 'Site Setup');
$this['setup']->init();
$this['streams'];
$debugger->stopTimer('_setup');
// Initialize configuration.
$debugger->startTimer('_config', 'Configuration');
$this['config']->init();
$this['errors']->resetHandlers();
$this['uri']->init();
$this['session']->init();
$debugger->init();
$this['config']->debug();
$debugger->stopTimer('_config');
// Initialize error handlers.
$this['errors']->resetHandlers();
// Initialize debugger.
$debugger->init();
$debugger->startTimer('init', 'Initialize');
$this['config']->debug();
// Use output buffering to prevent headers from being sent too early.
ob_start();
if ($this['config']->get('system.cache.gzip')) {
// Enable zip/deflate with a fallback in case of if browser does not support compressing.
if(!ob_start("ob_gzhandler")) {
if (!ob_start("ob_gzhandler")) {
ob_start();
}
}
// Initialize the timezone
// Initialize the timezone.
if ($this['config']->get('system.timezone')) {
date_default_timezone_set($this['config']->get('system.timezone'));
}
// Initialize Locale if set and configured
// Initialize uri, session.
$this['uri']->init();
$this['session']->init();
// Initialize Locale if set and configured.
if ($this['language']->enabled() && $this['config']->get('system.languages.override_locale')) {
setlocale(LC_ALL, $this['language']->getLanguage());
} elseif ($this['config']->get('system.default_locale')) {
setlocale(LC_ALL, $this['config']->get('system.default_locale'));
}
$debugger->startTimer('streams', 'Streams');
$this['streams'];
$debugger->stopTimer('streams');
$debugger->stopTimer('init');
$debugger->startTimer('plugins', 'Plugins');
$this['plugins']->init();
@@ -272,7 +303,7 @@ class Grav extends Container
* Redirect browser to another location.
*
* @param string $route Internal route.
* @param int $code Redirection code (30x)
* @param int $code Redirection code (30x)
*/
public function redirect($route, $code = null)
{
@@ -287,7 +318,7 @@ class Grav extends Container
$code = $matches[2];
}
if ($code == null) {
if ($code === null) {
$code = $this['config']->get('system.pages.redirect_default_code', 301);
}
@@ -298,10 +329,13 @@ class Grav extends Container
if ($uri->isExternal($route)) {
$url = $route;
} else {
if ($this['config']->get('system.pages.redirect_trailing_slash', true))
$url = rtrim($uri->rootUrl(), '/') .'/'. trim($route, '/'); // Remove trailing slash
else
$url = rtrim($uri->rootUrl(), '/') .'/'. ltrim($route, '/'); // Support trailing slash default routes
$url = rtrim($uri->rootUrl(), '/') . '/';
if ($this['config']->get('system.pages.redirect_trailing_slash', true)) {
$url .= trim($route, '/'); // Remove trailing slash
} else {
$url .= ltrim($route, '/'); // Support trailing slash default routes
}
}
header("Location: {$url}", true, $code);
@@ -312,7 +346,7 @@ class Grav extends Container
* Redirect browser to another location taking language into account (preferred)
*
* @param string $route Internal route.
* @param int $code Redirection code (30x)
* @param int $code Redirection code (30x)
*/
public function redirectLangSafe($route, $code = null)
{
@@ -320,9 +354,9 @@ class Grav extends Container
$language = $this['language'];
if (!$this['uri']->isExternal($route) && $language->enabled() && $language->isIncludeDefaultLanguage()) {
return $this->redirect($language->getLanguage() . $route, $code);
$this->redirect($language->getLanguage() . $route, $code);
} else {
return $this->redirect($route, $code);
$this->redirect($route, $code);
}
}
@@ -330,6 +364,7 @@ class Grav extends Container
* Returns mime type for the file format.
*
* @param string $format
*
* @return string
*/
public function mime($format)
@@ -346,6 +381,7 @@ class Grav extends Container
case 'xml':
return 'application/xml';
}
return 'text/html';
}
@@ -367,7 +403,7 @@ class Grav extends Container
if ($expires > 0) {
$expires_date = gmdate('D, d M Y H:i:s', time() + $expires) . ' GMT';
header('Cache-Control: max-age=' . $expires);
header('Expires: '. $expires_date);
header('Expires: ' . $expires_date);
}
// Set the last modified time
@@ -402,12 +438,14 @@ class Grav extends Container
*
* @param string $eventName
* @param Event $event
*
* @return Event
*/
public function fireEvent($eventName, Event $event = null)
{
/** @var EventDispatcher $events */
$events = $this['events'];
return $events->dispatch($eventName, $event);
}
@@ -417,50 +455,58 @@ 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');
}
/**
* This attempts to find media, other files, and download them
* @param $page
*
* @param $path
*/
protected function fallbackUrl($page, $path)
protected function fallbackUrl($path)
{
/** @var Uri $uri */
$uri = $this['uri'];
@@ -480,20 +526,22 @@ class Grav extends Container
}
$path_parts = pathinfo($path);
/** @var Page $page */
$page = $this['pages']->dispatch($path_parts['dirname'], true);
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'];
// if this is a media object, try actions first
if (isset($media[$media_file])) {
/** @var Medium $medium */
$medium = $media[$media_file];
foreach ($uri->query(null, true) as $action => $params) {
if (in_array($action, ImageMedium::$magic_actions)) {
call_user_func_array(array(&$medium, $action), explode(',', $params));
call_user_func_array([&$medium, $action], explode(',', $params));
}
}
Utils::download($medium->path(), false);

View File

@@ -1,6 +1,11 @@
<?php
namespace Grav\Common;
/**
* Class GravTrait
*
* @package Grav\Common
*/
trait GravTrait
{
/**
@@ -16,6 +21,7 @@ trait GravTrait
if (!self::$grav) {
self::$grav = Grav::instance();
}
return self::$grav;
}

View File

@@ -118,7 +118,7 @@ class Truncator {
list($txt, $nb, $opts) = static::truncateNode($doc, $childNode, $remaining, $opts);
}
else if ($childNode->nodeType === XML_TEXT_NODE) {
list($txt, $nb, $opts) = static::truncateText($doc, $childNode, $remaining, $opts);
list($txt, $nb, $opts) = static::truncateText($childNode, $remaining, $opts);
} else {
$txt = '';
$nb = 0;
@@ -141,7 +141,7 @@ class Truncator {
return array($inner, $remaining, $opts);
}
protected static function truncateText($doc, $node, $length, $opts)
protected static function truncateText($node, $length, $opts)
{
$string = $node->textContent;
@@ -165,7 +165,7 @@ class Truncator {
$words = $words[0];
$count = count($words);
if ($count <= $length && $length > 0) {
return array($xhtml, $count, $opts);
return array($string, $count, $opts);
}
return array(implode('', array_slice($words, 0, $length)), $count, $opts);
}

View File

@@ -4,20 +4,19 @@ namespace Grav\Common;
/**
* This file was originally part of the Akelos Framework
*/
use Grav\Common\Language\Language;
/**
* Inflector for pluralize and singularize English nouns.
*
* This Inflector is a port of Ruby on Rails Inflector.
*
* It can be really helpful for developers that want to
* create frameworks based on naming conventions rather than
* configurations.
*
* @author RocketTheme
* @license MIT
*/
* Inflector for pluralize and singularize English nouns.
*
* This Inflector is a port of Ruby on Rails Inflector.
*
* It can be really helpful for developers that want to
* create frameworks based on naming conventions rather than
* configurations.
*
* @author RocketTheme
* @license MIT
*/
class Inflector
{
@@ -42,11 +41,13 @@ class Inflector
}
/**
* Pluralizes English nouns.
*
* @param string $word English noun to pluralize
* @return string Plural noun
*/
* Pluralizes English nouns.
*
* @param string $word English noun to pluralize
* @param int $count The count
*
* @return string Plural noun
*/
public function pluralize($word, $count = 2)
{
$this->init();
@@ -58,14 +59,14 @@ class Inflector
$lowercased_word = strtolower($word);
foreach ($this->uncountable as $_uncountable) {
if (substr($lowercased_word, (-1*strlen($_uncountable))) == $_uncountable) {
if (substr($lowercased_word, (-1 * strlen($_uncountable))) == $_uncountable) {
return $word;
}
}
foreach ($this->irregular as $_plural => $_singular) {
if (preg_match('/('.$_plural.')$/i', $word, $arr)) {
return preg_replace('/('.$_plural.')$/i', substr($arr[0], 0, 1).substr($_singular, 1), $word);
if (preg_match('/(' . $_plural . ')$/i', $word, $arr)) {
return preg_replace('/(' . $_plural . ')$/i', substr($arr[0], 0, 1) . substr($_singular, 1), $word);
}
}
@@ -74,17 +75,19 @@ class Inflector
return preg_replace($rule, $replacement, $word);
}
}
return false;
}
/**
* Singularizes English nouns.
*
* @param string $word English noun to singularize
* @param int $count
* @return string Singular noun.
*/
* Singularizes English nouns.
*
* @param string $word English noun to singularize
* @param int $count
*
* @return string Singular noun.
*/
public function singularize($word, $count = 1)
{
$this->init();
@@ -95,14 +98,14 @@ class Inflector
$lowercased_word = strtolower($word);
foreach ($this->uncountable as $_uncountable) {
if (substr($lowercased_word, (-1*strlen($_uncountable))) == $_uncountable) {
if (substr($lowercased_word, (-1 * strlen($_uncountable))) == $_uncountable) {
return $word;
}
}
foreach ($this->irregular as $_plural => $_singular) {
if (preg_match('/('.$_singular.')$/i', $word, $arr)) {
return preg_replace('/('.$_singular.')$/i', substr($arr[0], 0, 1).substr($_plural, 1), $word);
if (preg_match('/(' . $_singular . ')$/i', $word, $arr)) {
return preg_replace('/(' . $_singular . ')$/i', substr($arr[0], 0, 1) . substr($_plural, 1), $word);
}
}
@@ -116,181 +119,206 @@ class Inflector
}
/**
* Converts an underscored or CamelCase word into a English
* sentence.
*
* The titleize public function converts text like "WelcomePage",
* "welcome_page" or "welcome page" to this "Welcome
* Page".
* If second parameter is set to 'first' it will only
* capitalize the first character of the title.
*
* @param string $word Word to format as tile
* @param string $uppercase If set to 'first' it will only uppercase the
* first character. Otherwise it will uppercase all
* the words in the title.
* @return string Text formatted as title
*/
* Converts an underscored or CamelCase word into a English
* sentence.
*
* The titleize public function converts text like "WelcomePage",
* "welcome_page" or "welcome page" to this "Welcome
* Page".
* If second parameter is set to 'first' it will only
* capitalize the first character of the title.
*
* @param string $word Word to format as tile
* @param string $uppercase If set to 'first' it will only uppercase the
* first character. Otherwise it will uppercase all
* the words in the title.
*
* @return string Text formatted as title
*/
public function titleize($word, $uppercase = '')
{
$uppercase = $uppercase == 'first' ? 'ucfirst' : 'ucwords';
return $uppercase($this->humanize($this->underscorize($word)));
}
/**
* Returns given word as CamelCased
*
* Converts a word like "send_email" to "SendEmail". It
* will remove non alphanumeric character from the word, so
* "who's online" will be converted to "WhoSOnline"
*
* @see variablize
* @param string $word Word to convert to camel case
* @return string UpperCamelCasedWord
*/
* Returns given word as CamelCased
*
* Converts a word like "send_email" to "SendEmail". It
* will remove non alphanumeric character from the word, so
* "who's online" will be converted to "WhoSOnline"
*
* @see variablize
*
* @param string $word Word to convert to camel case
*
* @return string UpperCamelCasedWord
*/
public function camelize($word)
{
return str_replace(' ', '', ucwords(preg_replace('/[^A-Z^a-z^0-9]+/', ' ', $word)));
}
/**
* Converts a word "into_it_s_underscored_version"
*
* Convert any "CamelCased" or "ordinary Word" into an
* "underscored_word".
*
* This can be really useful for creating friendly URLs.
*
* @param string $word Word to underscore
* @return string Underscored word
*/
* Converts a word "into_it_s_underscored_version"
*
* Convert any "CamelCased" or "ordinary Word" into an
* "underscored_word".
*
* This can be really useful for creating friendly URLs.
*
* @param string $word Word to underscore
*
* @return string Underscored word
*/
public function underscorize($word)
{
$regex1 = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\1_\2', $word);
$regex2 = preg_replace('/([a-zd])([A-Z])/', '\1_\2', $regex1);
$regex3 = preg_replace('/[^A-Z^a-z^0-9]+/', '_', $regex2);
return strtolower($regex3);
return strtolower($regex3);
}
/**
* Converts a word "into-it-s-hyphenated-version"
*
* Convert any "CamelCased" or "ordinary Word" into an
* "hyphenated-word".
*
* This can be really useful for creating friendly URLs.
*
* @param string $word Word to hyphenate
* @return string hyphenized word
*/
* Converts a word "into-it-s-hyphenated-version"
*
* Convert any "CamelCased" or "ordinary Word" into an
* "hyphenated-word".
*
* This can be really useful for creating friendly URLs.
*
* @param string $word Word to hyphenate
*
* @return string hyphenized word
*/
public function hyphenize($word)
{
$regex1 = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\1-\2', $word);
$regex2 = preg_replace('/([a-zd])([A-Z])/', '\1-\2', $regex1);
$regex3 = preg_replace('/[^A-Z^a-z^0-9]+/', '-', $regex2);
return strtolower($regex3);
return strtolower($regex3);
}
/**
* Returns a human-readable string from $word
*
* Returns a human-readable string from $word, by replacing
* underscores with a space, and by upper-casing the initial
* character by default.
*
* If you need to uppercase all the words you just have to
* pass 'all' as a second parameter.
*
* @param string $word String to "humanize"
* @param string $uppercase If set to 'all' it will uppercase all the words
* instead of just the first one.
* @return string Human-readable word
*/
* Returns a human-readable string from $word
*
* Returns a human-readable string from $word, by replacing
* underscores with a space, and by upper-casing the initial
* character by default.
*
* If you need to uppercase all the words you just have to
* pass 'all' as a second parameter.
*
* @param string $word String to "humanize"
* @param string $uppercase If set to 'all' it will uppercase all the words
* instead of just the first one.
*
* @return string Human-readable word
*/
public function humanize($word, $uppercase = '')
{
$uppercase = $uppercase == 'all' ? 'ucwords' : 'ucfirst';
return $uppercase(str_replace('_', ' ', preg_replace('/_id$/', '', $word)));
}
/**
* Same as camelize but first char is underscored
*
* Converts a word like "send_email" to "sendEmail". It
* will remove non alphanumeric character from the word, so
* "who's online" will be converted to "whoSOnline"
*
* @see camelize
* @param string $word Word to lowerCamelCase
* @return string Returns a lowerCamelCasedWord
*/
* Same as camelize but first char is underscored
*
* Converts a word like "send_email" to "sendEmail". It
* will remove non alphanumeric character from the word, so
* "who's online" will be converted to "whoSOnline"
*
* @see camelize
*
* @param string $word Word to lowerCamelCase
*
* @return string Returns a lowerCamelCasedWord
*/
public function variablize($word)
{
$word = $this->camelize($word);
return strtolower($word[0]).substr($word, 1);
return strtolower($word[0]) . substr($word, 1);
}
/**
* Converts a class name to its table name according to rails
* naming conventions.
*
* Converts "Person" to "people"
*
* @see classify
* @param string $class_name Class name for getting related table_name.
* @return string plural_table_name
*/
* Converts a class name to its table name according to rails
* naming conventions.
*
* Converts "Person" to "people"
*
* @see classify
*
* @param string $class_name Class name for getting related table_name.
*
* @return string plural_table_name
*/
public function tableize($class_name)
{
return $this->pluralize($this->underscore($class_name));
return $this->pluralize($this->underscorize($class_name));
}
/**
* Converts a table name to its class name according to rails
* naming conventions.
*
* Converts "people" to "Person"
*
* @see tableize
* @param string $table_name Table name for getting related ClassName.
* @return string SingularClassName
*/
* Converts a table name to its class name according to rails
* naming conventions.
*
* Converts "people" to "Person"
*
* @see tableize
*
* @param string $table_name Table name for getting related ClassName.
*
* @return string SingularClassName
*/
public function classify($table_name)
{
return $this->camelize($this->singularize($table_name));
}
/**
* Converts number to its ordinal English form.
*
* This method converts 13 to 13th, 2 to 2nd ...
*
* @param integer $number Number to get its ordinal value
* @return string Ordinal representation of given string.
*/
* Converts number to its ordinal English form.
*
* This method converts 13 to 13th, 2 to 2nd ...
*
* @param integer $number Number to get its ordinal value
*
* @return string Ordinal representation of given string.
*/
public function ordinalize($number)
{
$this->init();
if (in_array(($number % 100), range(11, 13))) {
return $number.$this->ordinals['default'];
return $number . $this->ordinals['default'];
} else {
switch (($number % 10)) {
case 1:
return $number.$this->ordinals['first'];
return $number . $this->ordinals['first'];
break;
case 2:
return $number.$this->ordinals['second'];
return $number . $this->ordinals['second'];
break;
case 3:
return $number.$this->ordinals['third'];
return $number . $this->ordinals['third'];
break;
default:
return $number.$this->ordinals['default'];
return $number . $this->ordinals['default'];
break;
}
}
}
/**
* Converts a number of days to a number of months
*
* @param int $days
*
* @return int
*/
public function monthize($days)
{
$now = new \DateTime();
@@ -300,9 +328,9 @@ class Inflector
$diff = $end->add($duration)->diff($now);
// handle years
// handle years
if ($diff->y > 0) {
$diff->m = $diff->m + 12*$diff->y;
$diff->m = $diff->m + 12 * $diff->y;
}
return $diff->m;

View File

@@ -26,6 +26,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
*
* @param string $key
* @param mixed $args
*
* @return mixed
*/
public function __call($key, $args)
@@ -79,11 +80,13 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
* Return nth item.
*
* @param int $key
*
* @return mixed|bool
*/
public function nth($key)
{
$items = array_keys($this->items);
return (isset($items[$key])) ? $this->offsetGet($items[$key]) : false;
}
@@ -95,6 +98,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
public function first()
{
$items = array_keys($this->items);
return $this->offsetGet(array_shift($items));
}
@@ -106,6 +110,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
public function last()
{
$items = array_keys($this->items);
return $this->offsetGet(array_pop($items));
}
@@ -117,11 +122,13 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
public function reverse()
{
$this->items = array_reverse($this->items);
return $this;
}
/**
* @param mixed $needle Searched value.
*
* @return string|bool Key if found, otherwise false.
*/
public function indexOf($needle)
@@ -131,6 +138,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
return $key;
}
}
return false;
}
@@ -144,7 +152,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
$keys = array_keys($this->items);
shuffle($keys);
$new = array();
$new = [];
foreach ($keys as $key) {
$new[$key] = $this->items[$key];
}
@@ -159,6 +167,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
*
* @param int $offset
* @param int $length
*
* @return $this
*/
public function slice($offset, $length = null)
@@ -171,12 +180,13 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
/**
* Pick one or more random entries.
*
* @param int $num Specifies how many entries should be picked.
* @param int $num Specifies how many entries should be picked.
*
* @return $this
*/
public function random($num = 1)
{
$this->items = array_intersect_key($this->items, array_flip((array) array_rand($this->items, $num)));
$this->items = array_intersect_key($this->items, array_flip((array)array_rand($this->items, $num)));
return $this;
}
@@ -184,7 +194,8 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
/**
* Append new elements to the list.
*
* @param array|Iterator $items Items to be appended. Existing keys will be overridden with the new values.
* @param array|Iterator $items Items to be appended. Existing keys will be overridden with the new values.
*
* @return $this
*/
public function append($items)
@@ -192,14 +203,17 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
if ($items instanceof static) {
$items = $items->toArray();
}
$this->items = array_merge($this->items, (array) $items);
$this->items = array_merge($this->items, (array)$items);
return $this;
}
/**
* Filter elements from the list
* @param callable|null $callback A function the receives ($value, $key) and must return a boolean to indicate filter status
*
* @param callable|null $callback A function the receives ($value, $key) and must return a boolean to indicate
* filter status
*
* @return $this
*/
public function filter(callable $callback = null)
@@ -207,7 +221,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
foreach ($this->items as $key => $value) {
if (
($callback && !call_user_func($callback, $value, $key)) ||
(!$callback && !(bool) $value)
(!$callback && !(bool)$value)
) {
unset($this->items[$key]);
}
@@ -230,7 +244,9 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
*/
public function sort(callable $callback = null, $desc = false)
{
if (!$callback || !is_callable($callback)) { return $this; }
if (!$callback || !is_callable($callback)) {
return $this;
}
$items = $this->items;
uasort($items, $callback);

View File

@@ -252,6 +252,8 @@ class Language
/**
* Gets an array of valid extensions with active first, then fallback extensions
*
* @param string|null $file_ext
*
* @return array
*/
public function getFallbackPageExtensions($file_ext = null)
@@ -328,15 +330,15 @@ class Language
/**
* Translate a key and possibly arguments into a string using current lang and fallbacks
*
* @param $args first argument is the lookup key value
* other arguments can be passed and replaced in the translation with sprintf syntax
* @param Array $languages
* @param mixed $args The first argument is the lookup key value
* Other arguments can be passed and replaced in the translation with sprintf syntax
* @param array $languages
* @param bool $array_support
* @param bool $html_out
*
* @return string
*/
public function translate($args, Array $languages = null, $array_support = false, $html_out = false)
public function translate($args, array $languages = null, $array_support = false, $html_out = false)
{
if (is_array($args)) {
$lookup = array_shift($args);
@@ -345,7 +347,6 @@ class Language
$args = [];
}
if ($this->config->get('system.languages.translations', true)) {
if ($this->enabled() && $lookup) {
if (empty($languages)) {
@@ -422,8 +423,8 @@ class Language
/**
* Lookup the translation text for a given lang and key
*
* @param $lang lang code
* @param $key key to lookup with
* @param string $lang lang code
* @param string $key key to lookup with
* @param bool $array_support
*
* @return string
@@ -438,6 +439,13 @@ class Language
return $translation;
}
/**
* Get the browser accepted languages
*
* @param array $accept_langs
*
* @return array
*/
public function getBrowserLanguages($accept_langs = [])
{
if (empty($this->http_accept_language)) {
@@ -451,9 +459,9 @@ class Language
// split $pref again by ';q='
// and decorate the language entries by inverted position
if (false !== ($i = strpos($pref, ';q='))) {
$langs[substr($pref, 0, $i)] = array((float)substr($pref, $i + 3), -$k);
$langs[substr($pref, 0, $i)] = [(float)substr($pref, $i + 3), -$k];
} else {
$langs[$pref] = array(1, -$k);
$langs[$pref] = [1, -$k];
}
}
arsort($langs);

View File

@@ -1,10 +1,20 @@
<?php
namespace Grav\Common\Markdown;
/**
* Class Parsedown
* @package Grav\Common\Markdown
*/
class Parsedown extends \Parsedown
{
use ParsedownGravTrait;
/**
* Parsedown constructor.
*
* @param $page
* @param $defaults
*/
public function __construct($page, $defaults)
{
$this->init($page, $defaults);

View File

@@ -1,10 +1,20 @@
<?php
namespace Grav\Common\Markdown;
/**
* Class ParsedownExtra
* @package Grav\Common\Markdown
*/
class ParsedownExtra extends \ParsedownExtra
{
use ParsedownGravTrait;
/**
* ParsedownExtra constructor.
*
* @param $page
* @param $defaults
*/
public function __construct($page, $defaults)
{
parent::__construct();

View File

@@ -2,7 +2,10 @@
namespace Grav\Common\Markdown;
use Grav\Common\GravTrait;
use Grav\Common\Page\Page;
use Grav\Common\Page\Pages;
use Grav\Common\Uri;
use RocketTheme\Toolbox\Event\Event;
/**
* A trait to add some custom processing to the identifyLink() method in Parsedown and ParsedownExtra
@@ -10,13 +13,23 @@ use Grav\Common\Uri;
trait ParsedownGravTrait
{
use GravTrait;
/** @var Page $page */
protected $page;
/** @var Pages $pages */
protected $pages;
protected $base_url;
/** @var Uri $uri */
protected $uri;
protected $pages_dir;
protected $special_chars;
protected $twig_link_regex = '/\!*\[(?:.*)\]\((\{([\{%#])\s*(.*?)\s*(?:\2|\})\})\)/';
protected $special_protocols = ['xmpp', 'mailto', 'tel', 'sms'];
public $completable_blocks = [];
public $continuable_blocks = [];
/**
* Initialization function to setup key variables needed by the MarkdownGravLinkTrait
@@ -26,12 +39,14 @@ trait ParsedownGravTrait
*/
protected function init($page, $defaults)
{
$grav = self::getGrav();
$this->page = $page;
$this->pages = self::getGrav()['pages'];
$this->pages = $grav['pages'];
$this->uri = $grav['uri'];
$this->BlockTypes['{'] [] = "TwigTag";
$this->base_url = rtrim(self::getGrav()['base_url'] . self::getGrav()['pages']->base(), '/');
$this->pages_dir = self::getGrav()['locator']->findResource('page://');
$this->special_chars = array('>' => 'gt', '<' => 'lt', '"' => 'quot');
$this->special_chars = ['>' => 'gt', '<' => 'lt', '"' => 'quot'];
if ($defaults === null) {
$defaults = self::getGrav()['config']->get('system.pages.markdown');
@@ -41,12 +56,76 @@ 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
*
* @param array $Element
* @param array $Element
*
* @return string markup
*/
public function elementToHtml(array $Element)
@@ -73,28 +152,29 @@ trait ParsedownGravTrait
*/
protected function blockTwigTag($Line)
{
if (preg_match('/[{%|{{|{#].*[#}|}}|%}]/', $Line['body'], $matches)) {
$Block = array(
if (preg_match('/(?:{{|{%|{#)(.*)(?:}}|%}|#})/', $Line['body'], $matches)) {
$Block = [
'markup' => $Line['body'],
);
];
return $Block;
}
}
protected function inlineSpecialCharacter($Excerpt)
{
if ($Excerpt['text'][0] === '&' && ! preg_match('/^&#?\w+;/', $Excerpt['text'])) {
return array(
if ($Excerpt['text'][0] === '&' && !preg_match('/^&#?\w+;/', $Excerpt['text'])) {
return [
'markup' => '&amp;',
'extent' => 1,
);
];
}
if (isset($this->special_chars[$Excerpt['text'][0]])) {
return array(
'markup' => '&'.$this->special_chars[$Excerpt['text'][0]].';',
return [
'markup' => '&' . $this->special_chars[$Excerpt['text'][0]] . ';',
'extent' => 1,
);
];
}
}
@@ -105,6 +185,7 @@ trait ParsedownGravTrait
$excerpt = parent::inlineImage($excerpt);
$excerpt['element']['attributes']['src'] = $matches[1];
$excerpt['extent'] = $excerpt['extent'] + strlen($matches[1]) - 1;
return $excerpt;
} else {
$excerpt['type'] = 'image';
@@ -112,7 +193,7 @@ trait ParsedownGravTrait
}
// Some stuff we will need
$actions = array();
$actions = [];
$media = null;
// if this is an image
@@ -124,37 +205,38 @@ trait ParsedownGravTrait
//get the url and parse it
$url = parse_url(htmlspecialchars_decode($excerpt['element']['attributes']['src']));
$this_host = isset($url['host']) && $url['host'] == $this->uri->host();
// if there is no host set but there is a path, the file is local
if (!isset($url['host']) && isset($url['path'])) {
if ((!isset($url['host']) || $this_host) && isset($url['path'])) {
$path_parts = pathinfo($url['path']);
// get the local path to page media if possible
if ($path_parts['dirname'] == $this->page->url(false, false, false)) {
$url['path'] = urldecode($path_parts['basename']);
// get the media objects for this page
$media = $this->page->media();
} else {
// see if this is an external page to this one
$page_route = str_replace($this->base_url, '', $path_parts['dirname']);
$base_url = rtrim(self::getGrav()['base_url_relative'] . self::getGrav()['pages']->base(), '/');
$page_route = '/' . ltrim(str_replace($base_url, '', $path_parts['dirname']), '/');
$ext_page = $this->pages->dispatch($page_route, true);
if ($ext_page) {
$media = $ext_page->media();
$url['path'] = urldecode($path_parts['basename']);
}
}
// 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'])) {
$actions = array_reduce(explode('&', $url['query']), function ($carry, $item) {
$parts = explode('=', $item, 2);
$value = isset($parts[1]) ? $parts[1] : null;
$carry[] = [ 'method' => $parts[0], 'params' => $value ];
$carry[] = ['method' => $parts[0], 'params' => $value];
return $carry;
}, []);
@@ -162,14 +244,15 @@ trait ParsedownGravTrait
// loop through actions for the image and call them
foreach ($actions as $action) {
$medium = call_user_func_array(array($medium, $action['method']), explode(',', urldecode($action['params'])));
$medium = call_user_func_array([$medium, $action['method']],
explode(',', urldecode($action['params'])));
}
if (isset($url['fragment'])) {
$medium->urlHash($url['fragment']);
}
$excerpt['element'] = $medium->parseDownElement($title, $alt, $class);
$excerpt['element'] = $medium->parseDownElement($title, $alt, $class, true);
} else {
// not a current page media file, see if it needs converting to relative
@@ -195,6 +278,7 @@ trait ParsedownGravTrait
$excerpt = parent::inlineLink($excerpt);
$excerpt['element']['attributes']['href'] = $matches[1];
$excerpt['extent'] = $excerpt['extent'] + strlen($matches[1]) - 1;
return $excerpt;
} else {
$excerpt = parent::inlineLink($excerpt);
@@ -208,7 +292,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,14 +314,13 @@ trait ParsedownGravTrait
if ($attrib == 'classes') {
$attrib = 'class';
}
$excerpt['element']['attributes'][$attrib] = $value;
$excerpt['element']['attributes'][$attrib] = str_replace(',', ' ', $value);
unset($actions[$key]);
}
}
}
$url['query']= http_build_query($actions, null, '&', PHP_QUERY_RFC3986);
$url['query'] = http_build_query($actions, null, '&', PHP_QUERY_RFC3986);
}
// if no query elements left, unset query
@@ -245,14 +328,33 @@ trait ParsedownGravTrait
unset ($url['query']);
}
// if there is no scheme, the file is local
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);
// set path to / if not set
if (empty($url['path'])) {
$url['path'] = '';
}
// if special scheme, just return
if(isset($url['scheme']) && in_array($url['scheme'], $this->special_protocols)) {
return $excerpt;
}
// handle paths and such
$url = Uri::convertUrl($this->page, $url, $type);
// build the URL from the component parts and set it on the element
$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

@@ -8,7 +8,7 @@ use Grav\Common\Utils;
/**
* Collection of Pages.
*
* @author RocketTheme
* @author RocketTheme
* @license MIT
*/
class Collection extends Iterator
@@ -23,7 +23,14 @@ class Collection extends Iterator
*/
protected $params;
public function __construct($items = array(), array $params = array(), Pages $pages = null)
/**
* Collection constructor.
*
* @param array $items
* @param array $params
* @param Pages|null $pages
*/
public function __construct($items = [], array $params = [], Pages $pages = null)
{
parent::__construct($items);
@@ -31,6 +38,11 @@ class Collection extends Iterator
$this->pages = $pages ? $pages : Grav::instance()->offsetGet('pages');
}
/**
* Get the collection params
*
* @return array
*/
public function params()
{
return $this->params;
@@ -40,11 +52,13 @@ class Collection extends Iterator
* Add a single page to a collection
*
* @param Page $page
*
* @return $this
*/
public function addPage(Page $page)
{
$this->items[$page->path()] = ['slug' => $page->slug()];
return $this;
}
@@ -63,11 +77,13 @@ class Collection extends Iterator
* Set parameters to the Collection
*
* @param array $params
*
* @return $this
*/
public function setParams(array $params)
{
$this->params = array_merge($this->params, $params);
return $this;
}
@@ -79,6 +95,7 @@ class Collection extends Iterator
public function current()
{
$current = parent::key();
return $this->pages->get($current);
}
@@ -90,13 +107,15 @@ class Collection extends Iterator
public function key()
{
$current = parent::current();
return $current['slug'];
}
/**
* Returns the value at specified offset.
*
* @param mixed $offset The offset to retrieve.
* @param mixed $offset The offset to retrieve.
*
* @return mixed Can return all value types.
*/
public function offsetGet($offset)
@@ -108,6 +127,7 @@ class Collection extends Iterator
* Remove item from the list.
*
* @param Page|string|null $key
*
* @return $this|void
* @throws \InvalidArgumentException
*/
@@ -123,6 +143,7 @@ class Collection extends Iterator
}
parent::remove($key);
return $this;
}
@@ -132,6 +153,7 @@ class Collection extends Iterator
* @param string $by
* @param string $dir
* @param array $manual
*
* @return $this
*/
public function order($by, $dir = 'asc', $manual = null)
@@ -145,6 +167,7 @@ class Collection extends Iterator
* Check to see if this item is the first in the collection.
*
* @param string $path
*
* @return boolean True if item is first.
*/
public function isFirst($path)
@@ -160,11 +183,12 @@ class Collection extends Iterator
* Check to see if this item is the last in the collection.
*
* @param string $path
*
* @return boolean True if item is last.
*/
public function isLast($path)
{
if ($this->items && $path == array_keys($this->items)[count($this->items)-1]) {
if ($this->items && $path == array_keys($this->items)[count($this->items) - 1]) {
return true;
} else {
return false;
@@ -174,7 +198,8 @@ class Collection extends Iterator
/**
* Gets the previous sibling based on current position.
*
* @param string $path
* @param string $path
*
* @return Page The previous item.
*/
public function prevSibling($path)
@@ -185,7 +210,8 @@ class Collection extends Iterator
/**
* Gets the next sibling based on current position.
*
* @param string $path
* @param string $path
*
* @return Page The next item.
*/
public function nextSibling($path)
@@ -198,6 +224,7 @@ class Collection extends Iterator
*
* @param string $path
* @param integer $direction either -1 or +1
*
* @return Page The sibling item.
*/
public function adjacentSibling($path, $direction = 1)
@@ -210,6 +237,7 @@ class Collection extends Iterator
return isset($values[$index]) ? $this->offsetGet($values[$index]) : $this;
}
return $this;
}
@@ -217,7 +245,8 @@ class Collection extends Iterator
/**
* Returns the item in the current position.
*
* @param string $path the path the item
* @param string $path the path the item
*
* @return Page Item in the array the the current position.
*/
public function currentPosition($path)
@@ -256,6 +285,7 @@ class Collection extends Iterator
}
}
$this->items = $date_range;
return $this;
}
@@ -275,6 +305,7 @@ class Collection extends Iterator
}
}
$this->items = $visible;
return $this;
}
@@ -294,6 +325,7 @@ class Collection extends Iterator
}
}
$this->items = $visible;
return $this;
}
@@ -313,6 +345,7 @@ class Collection extends Iterator
}
}
$this->items = $modular;
return $this;
}
@@ -332,6 +365,7 @@ class Collection extends Iterator
}
}
$this->items = $modular;
return $this;
}
@@ -351,6 +385,7 @@ class Collection extends Iterator
}
}
$this->items = $published;
return $this;
}
@@ -370,6 +405,7 @@ class Collection extends Iterator
}
}
$this->items = $published;
return $this;
}
@@ -391,6 +427,7 @@ class Collection extends Iterator
}
$this->items = $routable;
return $this;
}
@@ -410,12 +447,15 @@ class Collection extends Iterator
}
}
$this->items = $routable;
return $this;
}
/**
* Creates new collection with only pages of the specified type
*
* @param $type
*
* @return Collection The collection
*/
public function ofType($type)
@@ -430,12 +470,15 @@ class Collection extends Iterator
}
$this->items = $items;
return $this;
}
/**
* Creates new collection with only pages of one of the specified types
*
* @param $types
*
* @return Collection The collection
*/
public function ofOneOfTheseTypes($types)
@@ -450,12 +493,15 @@ class Collection extends Iterator
}
$this->items = $items;
return $this;
}
/**
* Creates new collection with only pages of one of the specified access levels
*
* @param $accessLevels
*
* @return Collection The collection
*/
public function ofOneOfTheseAccessLevels($accessLevels)
@@ -472,7 +518,7 @@ class Collection extends Iterator
foreach ($page->header()->access as $index => $accessLevel) {
if (is_array($accessLevel)) {
foreach($accessLevel as $innerIndex => $innerAccessLevel) {
foreach ($accessLevel as $innerIndex => $innerAccessLevel) {
if (in_array($innerAccessLevel, $accessLevels)) {
$valid = true;
}
@@ -497,11 +543,7 @@ class Collection extends Iterator
}
$this->items = $items;
return $this;
}
}

View File

@@ -5,6 +5,10 @@ namespace Grav\Common\Page;
use RocketTheme\Toolbox\ArrayTraits\Constructor;
use RocketTheme\Toolbox\ArrayTraits\NestedArrayAccess;
/**
* Class Header
* @package Grav\Common\Page
*/
class Header implements \ArrayAccess
{
use NestedArrayAccess, Constructor;

View File

@@ -20,11 +20,11 @@ class Media extends Getters
protected $gettersVariable = 'instances';
protected $path;
protected $instances = array();
protected $images = array();
protected $videos = array();
protected $audios = array();
protected $files = array();
protected $instances = [];
protected $images = [];
protected $videos = [];
protected $audios = [];
protected $files = [];
/**
* @param $path

View File

@@ -1,6 +1,7 @@
<?php
namespace Grav\Common\Page\Medium;
use Grav\Common\Utils;
use Grav\Common\Data\Blueprint;
class ImageMedium extends Medium
@@ -41,7 +42,8 @@ class ImageMedium extends Medium
public static $magic_actions = [
'resize', 'forceResize', 'cropResize', 'crop', 'zoomCrop',
'negate', 'brightness', 'contrast', 'grayscale', 'emboss',
'smooth', 'sharp', 'edge', 'colorize', 'sepia', 'enableProgressive'
'smooth', 'sharp', 'edge', 'colorize', 'sepia', 'enableProgressive',
'rotate', 'flip', 'fixOrientation'
];
/**
@@ -135,7 +137,15 @@ class ImageMedium extends Medium
*/
public function url($reset = true)
{
$output = preg_replace('|^' . preg_quote(GRAV_ROOT) . '|', '', $this->saveImage());
$image_path = self::$grav['locator']->findResource('cache://images', true);
$image_dir = self::$grav['locator']->findResource('cache://images', false);
$saved_image_path = $this->saveImage();
$output = preg_replace('|^' . preg_quote(GRAV_ROOT) . '|', '', $saved_image_path);
if (Utils::startsWith($output, $image_path)) {
$output = '/' . $image_dir . preg_replace('|^' . preg_quote($image_path) . '|', '', $output);
}
if ($reset) {
$this->reset();
@@ -154,6 +164,7 @@ class ImageMedium extends Medium
if (!$this->image) {
$this->image();
}
return $this;
}
@@ -260,6 +271,7 @@ class ImageMedium extends Medium
if ($this->image) {
$this->image();
$this->image->clearOperations(); // Clear previously applied operations
$this->querystring('');
$this->filter();
}

View File

@@ -118,7 +118,7 @@ class Medium extends Data implements RenderableInterface
* Return PATH to file.
*
* @param bool $reset
* @return string path to file
* @return string path to file
*/
public function path($reset = true)
{
@@ -155,7 +155,7 @@ class Medium extends Data implements RenderableInterface
*/
public function querystring($querystring = null, $withQuestionmark = true)
{
if ($querystring) {
if (!is_null($querystring)) {
$this->set('querystring', ltrim($querystring, '?&'));
foreach ($this->alternatives as $alt) {

File diff suppressed because it is too large Load Diff

View File

@@ -1,24 +1,24 @@
<?php
namespace Grav\Common\Page;
use Grav\Common\Grav;
use Grav\Common\Config\Config;
use Grav\Common\Utils;
use Grav\Common\Cache;
use Grav\Common\Taxonomy;
use Grav\Common\Language;
use Grav\Common\Config\Config;
use Grav\Common\Data\Blueprint;
use Grav\Common\Data\Blueprints;
use Grav\Common\Filesystem\Folder;
use Grav\Common\Grav;
use Grav\Common\Language\Language;
use Grav\Common\Taxonomy;
use Grav\Common\Utils;
use Grav\Plugin\Admin;
use RocketTheme\Toolbox\Event\Event;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
use Whoops\Exception\ErrorException;
/**
* GravPages is the class that is the entry point into the hierarchy of pages
* Pages is the class that is the entry point into the hierarchy of pages
*
* @author RocketTheme
* @author RocketTheme
* @license MIT
*/
class Pages
@@ -46,7 +46,7 @@ class Pages
/**
* @var array|string[]
*/
protected $routes = array();
protected $routes = [];
/**
* @var array
@@ -63,8 +63,19 @@ class Pages
*/
protected $last_modified;
/**
* @var array|string[]
*/
protected $ignore_files;
/**
* @var array|string[]
*/
protected $ignore_folders;
/**
* @var bool
*/
protected $ignore_hidden;
/**
@@ -72,6 +83,9 @@ class Pages
*/
static protected $types;
/**
* @var string
*/
static protected $home_route;
/**
@@ -89,6 +103,7 @@ class Pages
* Get or set base path for the pages.
*
* @param string $path
*
* @return string
*/
public function base($path = null)
@@ -111,6 +126,10 @@ class Pages
$this->ignore_folders = $config->get('system.pages.ignore_folders');
$this->ignore_hidden = $config->get('system.pages.ignore_hidden');
$this->instances = [];
$this->children = [];
$this->routes = [];
$this->buildPages();
}
@@ -118,6 +137,7 @@ class Pages
* Get or set last modification time.
*
* @param int $modified
*
* @return int|null
*/
public function lastModified($modified = null)
@@ -125,6 +145,7 @@ class Pages
if ($modified && $modified > $this->last_modified) {
$this->last_modified = $modified;
}
return $this->last_modified;
}
@@ -151,8 +172,8 @@ class Pages
/**
* Adds a page and assigns a route to it.
*
* @param Page $page Page to be added.
* @param string $route Optional route (uses route from the object if not set).
* @param Page $page Page to be added.
* @param string $route Optional route (uses route from the object if not set).
*/
public function addPage(Page $page, $route = null)
{
@@ -161,7 +182,7 @@ class Pages
}
$route = $page->route($route);
if ($page->parent()) {
$this->children[$page->parent()->path()][$page->path()] = array('slug' => $page->slug());
$this->children[$page->parent()->path()][$page->path()] = ['slug' => $page->slug()];
}
$this->routes[$route] = $page->path();
}
@@ -169,7 +190,7 @@ class Pages
/**
* Sort sub-pages in a page.
*
* @param Page $page
* @param Page $page
* @param string $order_by
* @param string $order_dir
*
@@ -185,7 +206,7 @@ class Pages
}
$path = $page->path();
$children = isset($this->children[$path]) ? $this->children[$path] : array();
$children = isset($this->children[$path]) ? $this->children[$path] : [];
if (!$children) {
return $children;
@@ -206,9 +227,10 @@ class Pages
/**
* @param Collection $collection
* @param $orderBy
* @param string $orderDir
* @param null $orderManual
* @param $orderBy
* @param string $orderDir
* @param null $orderManual
*
* @return array
* @internal
*/
@@ -219,7 +241,7 @@ class Pages
return [];
}
$lookup = md5(json_encode($items));
$lookup = md5(json_encode($items) . json_encode($orderManual) . $orderBy . $orderDir);
if (!isset($this->sort[$lookup][$orderBy])) {
$this->buildSort($lookup, $items, $orderBy, $orderManual);
}
@@ -237,7 +259,8 @@ class Pages
/**
* Get a page instance.
*
* @param string $path The filesystem full path of the page
* @param string $path The filesystem full path of the page
*
* @return Page
* @throws \Exception
*/
@@ -246,26 +269,30 @@ class Pages
if (!is_null($path) && !is_string($path)) {
throw new \Exception();
}
return isset($this->instances[(string) $path]) ? $this->instances[(string) $path] : null;
return isset($this->instances[(string)$path]) ? $this->instances[(string)$path] : null;
}
/**
* Get children of the path.
*
* @param string $path
*
* @return Collection
*/
public function children($path)
{
$children = isset($this->children[(string) $path]) ? $this->children[(string) $path] : array();
return new Collection($children, array(), $this);
$children = isset($this->children[(string)$path]) ? $this->children[(string)$path] : [];
return new Collection($children, [], $this);
}
/**
* Dispatch URI to a page.
*
* @param string $url The relative URL of the page
* @param bool $all
* @param bool $all
*
* @return Page|null
*/
public function dispatch($url, $all = false)
@@ -297,28 +324,34 @@ class Pages
$page = $this->dispatch($route, $all);
} else {
// Try Regex style redirects
foreach ((array)$config->get("site.redirects") as $pattern => $replace) {
$pattern = '#' . $pattern . '#';
try {
$found = preg_replace($pattern, $replace, $url);
if ($found != $url) {
$this->grav->redirectLangSafe($found);
$site_redirects = $config->get("site.redirects");
if (is_array($site_redirects)) {
foreach ((array)$site_redirects as $pattern => $replace) {
$pattern = '#' . $pattern . '#';
try {
$found = preg_replace($pattern, $replace, $url);
if ($found != $url) {
$this->grav->redirectLangSafe($found);
}
} catch (ErrorException $e) {
$this->grav['log']->error('site.redirects: ' . $pattern . '-> ' . $e->getMessage());
}
} catch (ErrorException $e) {
$this->grav['log']->error('site.redirects: ' . $pattern . '-> ' . $e->getMessage());
}
}
// Try Regex style routes
foreach ((array)$config->get("site.routes") as $pattern => $replace) {
$pattern = '#' . $pattern . '#';
try {
$found = preg_replace($pattern, $replace, $url);
if ($found != $url) {
$page = $this->dispatch($found, $all);
$site_routes = $config->get("site.routes");
if (is_array($site_routes)) {
foreach ((array)$site_routes as $pattern => $replace) {
$pattern = '#' . $pattern . '#';
try {
$found = preg_replace($pattern, $replace, $url);
if ($found != $url) {
$page = $this->dispatch($found, $all);
}
} catch (ErrorException $e) {
$this->grav['log']->error('site.routes: ' . $pattern . '-> ' . $e->getMessage());
}
} catch (ErrorException $e) {
$this->grav['log']->error('site.routes: '. $pattern . '-> ' . $e->getMessage());
}
}
}
@@ -336,14 +369,14 @@ class Pages
{
/** @var UniformResourceLocator $locator */
$locator = $this->grav['locator'];
return $this->instances[rtrim($locator->findResource('page://'), DS)];
}
/**
* Get a blueprint for a page type.
*
* @param string $type
* @param string $type
*
* @return Blueprint
*/
public function blueprints($type)
@@ -370,6 +403,7 @@ class Pages
* Get all pages
*
* @param \Grav\Common\Page\Page $current
*
* @return \Grav\Common\Page\Collection
*/
public function all(Page $current = null)
@@ -380,7 +414,7 @@ class Pages
$current = $current ?: $this->root();
if (!$current->root()) {
$all[$current->path()] = [ 'slug' => $current->slug() ];
$all[$current->path()] = ['slug' => $current->slug()];
}
foreach ($current->children() as $next) {
@@ -394,11 +428,14 @@ class Pages
* Get list of route/title of all pages.
*
* @param Page $current
* @param int $level
* @param int $level
* @param bool $rawRoutes
*
* @return array
*
* @throws \RuntimeException
*/
public function getList(Page $current = null, $level = 0)
public function getList(Page $current = null, $level = 0, $rawRoutes = false)
{
if (!$current) {
if ($level) {
@@ -408,14 +445,19 @@ class Pages
$current = $this->root();
}
$list = array();
$list = [];
if (!$current->root()) {
$list[$current->route()] = str_repeat('&nbsp; ', ($level-1)*2) . $current->title();
if ($rawRoutes) {
$route = $current->rawRoute();
} else {
$route = $current->route();
}
$list[$route] = str_repeat('&nbsp; ', ($level - 1) * 2) . $current->title();
}
foreach ($current->children() as $next) {
$list = array_merge($list, $this->getList($next, $level + 1));
$list = array_merge($list, $this->getList($next, $level + 1, $rawRoutes));
}
return $list;
@@ -494,12 +536,12 @@ class Pages
public function accessLevels()
{
$accessLevels = [];
foreach($this->all() as $page) {
foreach ($this->all() as $page) {
if (isset($page->header()->access)) {
if (is_array($page->header()->access)) {
foreach($page->header()->access as $index => $accessLevel) {
foreach ($page->header()->access as $index => $accessLevel) {
if (is_array($accessLevel)) {
foreach($accessLevel as $innerIndex => $innerAccessLevel) {
foreach ($accessLevel as $innerIndex => $innerAccessLevel) {
array_push($accessLevels, $innerIndex);
}
} else {
@@ -517,18 +559,44 @@ class Pages
}
/**
* Get available parents.
* Get available parents routes
*
* @return array
*/
public static function parents()
{
$rawRoutes = false;
return self::getParents($rawRoutes);
}
/**
* Get available parents raw routes.
*
* @return array
*/
public static function parentsRawRoutes()
{
$rawRoutes = true;
return self::getParents($rawRoutes);
}
/**
* Get available parents routes
*
* @param bool $rawRoutes get the raw route or the normal route
*
* @return array
*/
private static function getParents($rawRoutes)
{
$grav = Grav::instance();
/** @var Pages $pages */
$pages = $grav['pages'];
$parents = $pages->getList();
$parents = $pages->getList(null, 0, $rawRoutes);
/** @var Admin $admin */
$admin = $grav['admin'];
@@ -547,13 +615,13 @@ class Pages
}
/**
* Get's the home route
* Gets the home route
*
* @return string
*/
public static function getHomeRoute()
{
if (empty(self::$home)) {
if (empty(self::$home_route)) {
$grav = Grav::instance();
/** @var Config $config */
@@ -585,9 +653,19 @@ class Pages
self::$home_route = trim($home, '/');
}
return self::$home_route;
}
/**
* Needed for testing where we change the home route via config
*/
public static function resetHomeRoute()
{
self::$home_route = null;
return self::getHomeRoute();
}
/**
* Builds pages.
*
@@ -595,7 +673,7 @@ class Pages
*/
protected function buildPages()
{
$this->sort = array();
$this->sort = [];
/** @var Config $config */
$config = $this->grav['config'];
@@ -626,7 +704,7 @@ class Pages
$last_modified = Folder::lastModifiedFile($pages_dir);
}
$page_cache_id = md5(USER_DIR.$last_modified.$language->getActive().$config->checksum());
$page_cache_id = md5(USER_DIR . $last_modified . $language->getActive() . $config->checksum());
list($this->instances, $this->routes, $this->children, $taxonomy_map, $this->sort) = $cache->fetch($page_cache_id);
if (!$this->instances) {
@@ -659,35 +737,33 @@ class Pages
// cache if needed
if ($this->grav['config']->get('system.cache.enabled')) {
/** @var Cache $cache */
/** @var Cache $cache */
$cache = $this->grav['cache'];
/** @var Taxonomy $taxonomy */
$taxonomy = $this->grav['taxonomy'];
// save pages, routes, taxonomy, and sort to cache
$cache->save(
$page_cache_id,
array($this->instances, $this->routes, $this->children, $taxonomy->taxonomy(), $this->sort)
);
$cache->save($page_cache_id, [$this->instances, $this->routes, $this->children, $taxonomy->taxonomy(), $this->sort]);
}
}
/**
* Recursive function to load & build page relationships.
*
* @param string $directory
* @param string $directory
* @param Page|null $parent
*
* @return Page
* @throws \RuntimeException
* @internal
*/
protected function recurse($directory, Page &$parent = null)
{
$directory = rtrim($directory, DS);
$page = new Page;
$directory = rtrim($directory, DS);
$page = new Page;
/** @var Config $config */
$config = $this->grav['config'];
$config = $this->grav['config'];
/** @var Language $language */
$language = $this->grav['language'];
@@ -713,20 +789,21 @@ class Pages
if (!isset($this->instances[$page->path()])) {
$this->instances[$page->path()] = $page;
if ($parent && $page->path()) {
$this->children[$parent->path()][$page->path()] = array('slug' => $page->slug());
$this->children[$parent->path()][$page->path()] = ['slug' => $page->slug()];
}
} else {
throw new \RuntimeException('Fatal error when creating page instances.');
}
$content_exists = false;
$pages_found = glob($directory.'/*'.CONTENT_EXT);
$page_extensions = $language->getFallbackPageExtensions();
$pages_found = glob($directory . '/*' . CONTENT_EXT);
$page_extension = '';
if ($pages_found) {
$page_extensions = $language->getFallbackPageExtensions();
foreach ($page_extensions as $extension) {
foreach ($pages_found as $found) {
if (preg_match('/^.*\/[0-9A-Za-z\-\_]+('.$extension.')$/', $found)) {
if (preg_match('/^.*\/[0-9A-Za-z\-\_]+(' . $extension . ')$/', $found)) {
$page_found = $found;
$page_extension = $extension;
break 2;
@@ -770,14 +847,14 @@ class Pages
$page->path($file->getPath());
}
$path = $directory.DS.$name;
$path = $directory . DS . $name;
$child = $this->recurse($path, $page);
if (Utils::startsWith($name, '_')) {
$child->routable(false);
}
$this->children[$page->path()][$child->path()] = array('slug' => $child->slug());
$this->children[$page->path()][$child->path()] = ['slug' => $child->slug()];
if ($config->get('system.pages.events.page')) {
$this->grav->fireEvent('onFolderProcessed', new Event(['page' => $page]));
@@ -790,9 +867,20 @@ class Pages
$page->routable(false);
}
// Override the modified time if modular
if ($page->template() == 'modular') {
foreach ($page->collection() as $child) {
$modified = $child->modified();
if ($modified > $last_modified) {
$last_modified = $modified;
}
}
}
// Override the modified and ID so that it takes the latest change into account
$page->modified($last_modified);
$page->id($last_modified.md5($page->filePath()));
$page->id($last_modified . md5($page->filePath()));
// Sort based on Defaults or Page Overridden sort order
$this->children[$page->path()] = $this->sort($page);
@@ -809,7 +897,7 @@ class Pages
$taxonomy = $this->grav['taxonomy'];
// Get the home route
$home = self::getHomeRoute();
$home = self::resetHomeRoute();
// Build routes and taxonomy map.
/** @var $page Page */
@@ -818,7 +906,7 @@ class Pages
// process taxonomy
$taxonomy->addTaxonomy($page);
$route = $page->route();
$route = $page->route();
$raw_route = $page->rawRoute();
$page_path = $page->path();
@@ -855,19 +943,20 @@ class Pages
/**
* @param string $path
* @param array $pages
* @param array $pages
* @param string $order_by
* @param array $manual
* @param array $manual
*
* @throws \RuntimeException
* @internal
*/
protected function buildSort($path, array $pages, $order_by = 'default', $manual = null)
{
$list = array();
$list = [];
$header_default = null;
$header_query = null;
// do this headery query work only once
// do this header query work only once
if (strpos($order_by, 'header.') === 0) {
$header_query = explode('|', str_replace('header.', '', $order_by));
if (isset($header_query[1])) {
@@ -924,7 +1013,7 @@ class Pages
// Move manually ordered items into the beginning of the list. Order of the unlisted items does not change.
if (is_array($manual) && !empty($manual)) {
$new_list = array();
$new_list = [];
$i = count($manual);
foreach ($list as $key => $dummy) {
@@ -933,7 +1022,7 @@ class Pages
if ($order === false) {
$order = $i++;
}
$new_list[$key] = (int) $order;
$new_list[$key] = (int)$order;
}
$list = $new_list;
@@ -948,13 +1037,19 @@ class Pages
}
}
// Shuffles and associative array
/**
* Shuffles an associative array
*
* @param array $list
*
* @return array
*/
protected function arrayShuffle($list)
{
$keys = array_keys($list);
shuffle($keys);
$new = array();
$new = [];
foreach ($keys as $key) {
$new[$key] = $list[$key];
}

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,11 +6,12 @@ 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.
*
* @author RocketTheme
* @author RocketTheme
* @license MIT
*/
class Plugin implements EventSubscriberInterface
@@ -40,7 +41,7 @@ class Plugin implements EventSubscriberInterface
{
$methods = get_class_methods(get_called_class());
$list = array();
$list = [];
foreach ($methods as $method) {
if (strpos($method, 'on') === 0) {
$list[$method] = [$method, 0];
@@ -53,9 +54,9 @@ class Plugin implements EventSubscriberInterface
/**
* Constructor.
*
* @param string $name
* @param Grav $grav
* @param Config $config
* @param string $name
* @param Grav $grav
* @param Config $config
*/
public function __construct($name, Grav $grav, Config $config)
{
@@ -69,6 +70,7 @@ class Plugin implements EventSubscriberInterface
if (isset($this->grav['admin'])) {
return true;
}
return false;
}
@@ -82,12 +84,12 @@ class Plugin implements EventSubscriberInterface
foreach ($events as $eventName => $params) {
if (is_string($params)) {
$dispatcher->addListener($eventName, array($this, $params));
$dispatcher->addListener($eventName, [$this, $params]);
} elseif (is_string($params[0])) {
$dispatcher->addListener($eventName, array($this, $params[0]), isset($params[1]) ? $params[1] : 0);
$dispatcher->addListener($eventName, [$this, $params[0]], isset($params[1]) ? $params[1] : 0);
} else {
foreach ($params as $listener) {
$dispatcher->addListener($eventName, array($this, $listener[0]), isset($listener[1]) ? $listener[1] : 0);
$dispatcher->addListener($eventName, [$this, $listener[0]], isset($listener[1]) ? $listener[1] : 0);
}
}
}
@@ -103,12 +105,12 @@ class Plugin implements EventSubscriberInterface
foreach ($events as $eventName => $params) {
if (is_string($params)) {
$dispatcher->removeListener($eventName, array($this, $params));
$dispatcher->removeListener($eventName, [$this, $params]);
} elseif (is_string($params[0])) {
$dispatcher->removeListener($eventName, array($this, $params[0]));
$dispatcher->removeListener($eventName, [$this, $params[0]]);
} else {
foreach ($params as $listener) {
$dispatcher->removeListener($eventName, array($this, $listener[0]));
$dispatcher->removeListener($eventName, [$this, $listener[0]]);
}
}
}
@@ -121,15 +123,16 @@ class Plugin implements EventSubscriberInterface
*
* format: [plugin:myplugin_name](function_data)
*
* @param $content The string to perform operations upon
* @param $function The anonymous callback function
* @param string $internal_regex Optional internal regex to extra data from
* @param string $content The string to perform operations upon
* @param callable $function The anonymous callback function
* @param string $internal_regex Optional internal regex to extra data from
*
* @return string
*/
protected function parseLinks($content, $function, $internal_regex = '(.*)')
{
$regex = '/\[plugin:(?:'.$this->name.')\]\('.$internal_regex.'\)/i';
$regex = '/\[plugin:(?:' . $this->name . ')\]\(' . $internal_regex . '\)/i';
return preg_replace_callback($regex, $function, $content);
}
@@ -148,7 +151,7 @@ class Plugin implements EventSubscriberInterface
{
$class_name = $this->name;
$class_name_merged = $class_name . '.merged';
$defaults = $this->config->get('plugins.'. $class_name, []);
$defaults = $this->config->get('plugins.' . $class_name, []);
$page_header = $page->header();
$header = [];
if (!isset($page_header->$class_name_merged) && isset($page_header->$class_name)) {
@@ -179,7 +182,31 @@ class Plugin implements EventSubscriberInterface
} else {
$header = array_merge($header, $params);
}
// 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;
}
}

Some files were not shown because too many files have changed in this diff Show More