Compare commits
441 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b6cadbeeb | ||
|
|
bf91d13222 | ||
|
|
0bd60d24b7 | ||
|
|
864f14344e | ||
|
|
81e25e314b | ||
|
|
028554dbf8 | ||
|
|
bda8de3076 | ||
|
|
36be17617d | ||
|
|
bb23f6157f | ||
|
|
39ac423bce | ||
|
|
39b1eed912 | ||
|
|
360286f3d4 | ||
|
|
88c84ed028 | ||
|
|
f03a7ced06 | ||
|
|
5605b69844 | ||
|
|
652c5cd4bd | ||
|
|
bfe3a7750e | ||
|
|
1d23d29485 | ||
|
|
3bec73049b | ||
|
|
cd7366ca8d | ||
|
|
63812cc6b1 | ||
|
|
de9b6df2c7 | ||
|
|
990663cd60 | ||
|
|
9701908aaa | ||
|
|
49facba84a | ||
|
|
7953271265 | ||
|
|
3f3adfc5c6 | ||
|
|
b6c289067f | ||
|
|
71176f52e9 | ||
|
|
0d97710ffb | ||
|
|
1d65344aa5 | ||
|
|
82a5afa732 | ||
|
|
72836982e6 | ||
|
|
d12c8b10a2 | ||
|
|
b208ced437 | ||
|
|
c4e72819a6 | ||
|
|
3541ea8ec8 | ||
|
|
e4cda6383f | ||
|
|
3cc6700845 | ||
|
|
36ec6ad513 | ||
|
|
aec95f3fa6 | ||
|
|
1fe190998c | ||
|
|
aeca73bdd3 | ||
|
|
848497774b | ||
|
|
1d440035a4 | ||
|
|
51104a1d55 | ||
|
|
6222b22e2a | ||
|
|
b332e497ab | ||
|
|
75419120be | ||
|
|
94feeac119 | ||
|
|
cf058bb662 | ||
|
|
1e56e92502 | ||
|
|
2025e7c28a | ||
|
|
1d08090560 | ||
|
|
485df7517d | ||
|
|
2a4030e399 | ||
|
|
5743d7e048 | ||
|
|
3b8da60cf9 | ||
|
|
49a7b11e2b | ||
|
|
e5d255accd | ||
|
|
0e6bf74db1 | ||
|
|
9d67f1ac33 | ||
|
|
8c738d0687 | ||
|
|
7d35475104 | ||
|
|
1f5641069b | ||
|
|
f8eeac70a2 | ||
|
|
1279cb4ef3 | ||
|
|
2934157fb4 | ||
|
|
ddaca8a312 | ||
|
|
57cd5c9e6f | ||
|
|
31940c03b1 | ||
|
|
56f267ec79 | ||
|
|
5f6b09b032 | ||
|
|
7de21b1f52 | ||
|
|
9c0deea6c8 | ||
|
|
62dbf9b02b | ||
|
|
0ddfd4c546 | ||
|
|
5abb4060f3 | ||
|
|
9ba4ced65d | ||
|
|
49c4dd197e | ||
|
|
3d830fb608 | ||
|
|
47b5cd7db7 | ||
|
|
d4aeb8e223 | ||
|
|
c76be3c4dd | ||
|
|
b17a3780ab | ||
|
|
b612347ee7 | ||
|
|
06a76579db | ||
|
|
13db4025b6 | ||
|
|
07fa7da920 | ||
|
|
0be127eda7 | ||
|
|
fe01f29872 | ||
|
|
a1dca420e4 | ||
|
|
2585512946 | ||
|
|
7a1e10ee13 | ||
|
|
99c16d5514 | ||
|
|
ee99cb7990 | ||
|
|
c2fb252a6e | ||
|
|
7d00941876 | ||
|
|
db59caa764 | ||
|
|
4218e3f81b | ||
|
|
11a14aed76 | ||
|
|
ae3ca8aa2d | ||
|
|
0bce4a95b7 | ||
|
|
60ab5cefd0 | ||
|
|
793f14c3e0 | ||
|
|
bb1e49dd8e | ||
|
|
4108c7710b | ||
|
|
3fb684d608 | ||
|
|
e2d00bec41 | ||
|
|
aa4fb96b8b | ||
|
|
c307f63e1f | ||
|
|
1494247c85 | ||
|
|
d6b8ae6297 | ||
|
|
d3202b3210 | ||
|
|
a08b5a1863 | ||
|
|
1f75e014d3 | ||
|
|
19891408db | ||
|
|
57c4f13e53 | ||
|
|
4854c72cbb | ||
|
|
d440739b8b | ||
|
|
2d49054a95 | ||
|
|
2fb22d813f | ||
|
|
6c02bf0c70 | ||
|
|
172600415d | ||
|
|
c55b032928 | ||
|
|
1d79ef60c3 | ||
|
|
e279817839 | ||
|
|
c8983bf7db | ||
|
|
ab5233032d | ||
|
|
535e3c982d | ||
|
|
2d5f721301 | ||
|
|
5c746f869a | ||
|
|
4485aa3109 | ||
|
|
b8437fbd01 | ||
|
|
7e20ef5dd6 | ||
|
|
04116b3a37 | ||
|
|
086f791c9f | ||
|
|
86c22c2e29 | ||
|
|
95241da47c | ||
|
|
683b8a2848 | ||
|
|
8dbe06941c | ||
|
|
af2e416ea1 | ||
|
|
e576b05078 | ||
|
|
78c6d60655 | ||
|
|
cbb1cc2b85 | ||
|
|
8a3636d10f | ||
|
|
2721e681ef | ||
|
|
8a41b2e08d | ||
|
|
dec78b9cbd | ||
|
|
7ab75811ad | ||
|
|
15043e1a11 | ||
|
|
4ef5236a53 | ||
|
|
2a06cfc5e2 | ||
|
|
60876f2f09 | ||
|
|
74fdca79f0 | ||
|
|
c3c7c78e46 | ||
|
|
24a5c2c03c | ||
|
|
9113c86196 | ||
|
|
06b993181c | ||
|
|
a579544130 | ||
|
|
a8bfa88cac | ||
|
|
d1b24d0077 | ||
|
|
8d93df1633 | ||
|
|
ef095d4fc0 | ||
|
|
1df6173041 | ||
|
|
fb50c4a4f0 | ||
|
|
febe3123dd | ||
|
|
23ad20ed13 | ||
|
|
bce084841e | ||
|
|
172236e58d | ||
|
|
b848f98481 | ||
|
|
a69e7ee7cf | ||
|
|
e5493573d5 | ||
|
|
bdbc14b9c1 | ||
|
|
f82b40ef49 | ||
|
|
7958db6a17 | ||
|
|
ed8cd7f30e | ||
|
|
43f11f5d49 | ||
|
|
5a1fa1025d | ||
|
|
879f0815cb | ||
|
|
bff84ae8d5 | ||
|
|
4e0db8e540 | ||
|
|
85ff412768 | ||
|
|
2b695a985d | ||
|
|
a1a75954ae | ||
|
|
c8a5e846c1 | ||
|
|
515f257ee3 | ||
|
|
71795fd775 | ||
|
|
8cda9a08da | ||
|
|
684503245c | ||
|
|
77c8458fbf | ||
|
|
7f7ba5306d | ||
|
|
612e2126ee | ||
|
|
dd43b3b7da | ||
|
|
27af9432e0 | ||
|
|
774cf2d6d0 | ||
|
|
8270edbc78 | ||
|
|
563a990f0d | ||
|
|
b248b39dc7 | ||
|
|
a9ec2af342 | ||
|
|
1fdc34b43c | ||
|
|
11dc04262b | ||
|
|
82a4176816 | ||
|
|
722bc3e74b | ||
|
|
1616fadfe9 | ||
|
|
71e8ba44fc | ||
|
|
e801c8f44e | ||
|
|
4fa04f6eec | ||
|
|
f308587624 | ||
|
|
8406802a05 | ||
|
|
778ae8aced | ||
|
|
49dd8b3c9d | ||
|
|
1ecd4bfd5a | ||
|
|
235b7e5ff3 | ||
|
|
68c582a02a | ||
|
|
d0ef86c9a8 | ||
|
|
9c89f55274 | ||
|
|
26434d26fe | ||
|
|
d237a1e037 | ||
|
|
6c7a1b335b | ||
|
|
ad65816c35 | ||
|
|
ed28a5dc62 | ||
|
|
9fee3d4c59 | ||
|
|
0349169097 | ||
|
|
09e1c844f4 | ||
|
|
9b1b69fcae | ||
|
|
4dd57daec0 | ||
|
|
7813d18b1b | ||
|
|
f35bff4f59 | ||
|
|
fd47620817 | ||
|
|
b949b512e2 | ||
|
|
00aefa50ed | ||
|
|
1a5abcbcbc | ||
|
|
90568da797 | ||
|
|
2035a9a800 | ||
|
|
d29bc41ae7 | ||
|
|
25637defa8 | ||
|
|
82616b9891 | ||
|
|
067f75389b | ||
|
|
0e6132800e | ||
|
|
0a76e46d8f | ||
|
|
77d4925f38 | ||
|
|
e1f95b54d5 | ||
|
|
092989cdd0 | ||
|
|
27ab57eede | ||
|
|
e80a17540c | ||
|
|
72fb77894e | ||
|
|
70f8707b04 | ||
|
|
0d33a1d479 | ||
|
|
5d38e60076 | ||
|
|
fc08cb8e52 | ||
|
|
d65ec29408 | ||
|
|
758ef2313a | ||
|
|
479e73e950 | ||
|
|
af6e352083 | ||
|
|
7e5b60917b | ||
|
|
3695ff3d03 | ||
|
|
be2af197c3 | ||
|
|
acbbc723eb | ||
|
|
7c7df2240b | ||
|
|
c43f253805 | ||
|
|
756e2cf0c3 | ||
|
|
6087e786f5 | ||
|
|
9fa5681a4f | ||
|
|
182b6977bd | ||
|
|
3da7079777 | ||
|
|
992f99190b | ||
|
|
dfee5fdea9 | ||
|
|
aa9b735a50 | ||
|
|
9a3005e3c5 | ||
|
|
92ea756d91 | ||
|
|
b48449d782 | ||
|
|
5e84ca35f2 | ||
|
|
ee20bf70e0 | ||
|
|
8cb098c6e0 | ||
|
|
3054a67078 | ||
|
|
8ca14c7c65 | ||
|
|
6e2d9ca3cc | ||
|
|
eff72b73ab | ||
|
|
eb29d68958 | ||
|
|
e0632dee09 | ||
|
|
4549574908 | ||
|
|
0866a62a1f | ||
|
|
1a7fd382a9 | ||
|
|
c772c2d4ad | ||
|
|
e47ac59860 | ||
|
|
4f003bb5fa | ||
|
|
74c1e7473a | ||
|
|
51d2724dfd | ||
|
|
5fefa85f4a | ||
|
|
e8a935570b | ||
|
|
ce71168ed9 | ||
|
|
cdc96ca574 | ||
|
|
d121aa3415 | ||
|
|
6aaeb9e1f1 | ||
|
|
fa39629104 | ||
|
|
9e13593c11 | ||
|
|
0b3970d7c1 | ||
|
|
95c09f2ce5 | ||
|
|
c78619aad3 | ||
|
|
566da30513 | ||
|
|
f8c8ac4371 | ||
|
|
1951722fdb | ||
|
|
90d2856581 | ||
|
|
4fdeb4902e | ||
|
|
df3a492d3a | ||
|
|
e180e5a52a | ||
|
|
3c4dd26c20 | ||
|
|
f5fc509f14 | ||
|
|
2d00203a1f | ||
|
|
f1ac509032 | ||
|
|
5d4705b9fa | ||
|
|
ac23ab21b8 | ||
|
|
6cb85dc6a5 | ||
|
|
5b8b8e4ebb | ||
|
|
a6b1c6b222 | ||
|
|
0261df0d48 | ||
|
|
b3d18be643 | ||
|
|
2709938f9f | ||
|
|
53e1c790d8 | ||
|
|
f2f9fc4ed6 | ||
|
|
3cbf9c7101 | ||
|
|
c655d9e8fc | ||
|
|
2ef7f7cf36 | ||
|
|
418f0972a9 | ||
|
|
9a777efd52 | ||
|
|
aa8a329c7b | ||
|
|
e4930a144f | ||
|
|
194014007f | ||
|
|
dc8f2c1466 | ||
|
|
6ee48c74f7 | ||
|
|
136a9e8218 | ||
|
|
34045ea62b | ||
|
|
267edbee7d | ||
|
|
da882ebcd2 | ||
|
|
ed0ba1ed98 | ||
|
|
ef9dd3aa28 | ||
|
|
73b9abd38b | ||
|
|
6e399fe0ed | ||
|
|
5f9ed17091 | ||
|
|
1f4b3913b6 | ||
|
|
dc9b9509d7 | ||
|
|
b4f34c8643 | ||
|
|
52544a8b25 | ||
|
|
017500a6b5 | ||
|
|
425ae30e62 | ||
|
|
1aa09d8987 | ||
|
|
a45196dc97 | ||
|
|
8d7ab6fdd3 | ||
|
|
87870bcde7 | ||
|
|
9b85c1b0f7 | ||
|
|
104012228c | ||
|
|
e3deb40f69 | ||
|
|
492b290845 | ||
|
|
3eb2a5664a | ||
|
|
15fd233e56 | ||
|
|
912f697cff | ||
|
|
d827228dc2 | ||
|
|
84073a53cb | ||
|
|
f562573640 | ||
|
|
66aa66954c | ||
|
|
99275dfe59 | ||
|
|
efded08d6e | ||
|
|
d726f15aa3 | ||
|
|
7c6cd30aea | ||
|
|
f0145aa659 | ||
|
|
879b5ef272 | ||
|
|
91a57e1a16 | ||
|
|
3698afb8a6 | ||
|
|
8e1b2bc6e4 | ||
|
|
37dd107281 | ||
|
|
2d3b41c62d | ||
|
|
c9b8fc0e1b | ||
|
|
7eb57b674a | ||
|
|
25b33d0204 | ||
|
|
d47faed870 | ||
|
|
9a8efdf9cd | ||
|
|
593fd20a15 | ||
|
|
ef75582e20 | ||
|
|
7440074491 | ||
|
|
9688ed0f51 | ||
|
|
45d415e547 | ||
|
|
b2c7e22634 | ||
|
|
4581077dcd | ||
|
|
729f83b3d4 | ||
|
|
bf361db5fc | ||
|
|
328e9b20de | ||
|
|
484a34cd92 | ||
|
|
5ab4d916b0 | ||
|
|
f0974e0d24 | ||
|
|
06a5aa6d01 | ||
|
|
a88829bd57 | ||
|
|
c023c74ae5 | ||
|
|
a8ad14222d | ||
|
|
6c6871f607 | ||
|
|
5764e5e686 | ||
|
|
b89044a709 | ||
|
|
5fc4755d3b | ||
|
|
2f2adaaee8 | ||
|
|
e2ae24faa9 | ||
|
|
55bc84c118 | ||
|
|
a47d5d00b3 | ||
|
|
05c2b98929 | ||
|
|
c5d3098b25 | ||
|
|
6805f32a13 | ||
|
|
b8aa250a22 | ||
|
|
bf05a36dfe | ||
|
|
8f9cdad916 | ||
|
|
d2ed424a7c | ||
|
|
08cbd9553f | ||
|
|
369d2cb390 | ||
|
|
dcaa9a35c3 | ||
|
|
4a80691e07 | ||
|
|
215b2cdfa8 | ||
|
|
425831a7ae | ||
|
|
984e0455b1 | ||
|
|
00ecfb30f3 | ||
|
|
c18f20e483 | ||
|
|
71c5ff8c51 | ||
|
|
1996dd7de8 | ||
|
|
e87daa2361 | ||
|
|
987feb1385 | ||
|
|
8d048c689f | ||
|
|
139ef04e0a | ||
|
|
4c01e6c93e | ||
|
|
27744ba747 | ||
|
|
3d3c6f4eba | ||
|
|
fb4abc5f5f | ||
|
|
f29b141d69 | ||
|
|
1cecd09423 | ||
|
|
0142e76270 | ||
|
|
5f8c7f41ec | ||
|
|
451baff26e | ||
|
|
78accfe98b | ||
|
|
0e8e27877e | ||
|
|
d8a993bc86 | ||
|
|
ec7dbbdc8b | ||
|
|
c45652de81 | ||
|
|
e152cfd10f | ||
|
|
17a0590ee4 | ||
|
|
05e4f96a6b |
6
.gitignore
vendored
@@ -35,3 +35,9 @@ Thumbs.db
|
||||
|
||||
# phpstorm
|
||||
.idea/*
|
||||
user/config/security.yaml
|
||||
|
||||
tests/_output/*
|
||||
tests/_support/_generated/*
|
||||
tests/cache/*
|
||||
tests/error.log
|
||||
|
||||
@@ -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>
|
||||
|
||||
42
.travis.yml
@@ -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##*/};
|
||||
|
||||
140
CHANGELOG.md
@@ -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
@@ -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** — [http://learn.getgrav.org/basics/requirements](http://learn.getgrav.org/basics/requirements)
|
||||
|
||||
2. **Check this happens on a clean Grav install** — check if the issue happens on any Grav site, or just with a specific configuration of plugins / theme
|
||||
|
||||
3. **Use the GitHub issue search** — check if the issue has already been
|
||||
reported.
|
||||
|
||||
4. **Check if the issue is already being solved in a PR** — check the open Pull Requests to see if one already solves the problem you're having
|
||||
|
||||
5. **Check if the issue has been fixed** — try to reproduce it using the
|
||||
latest `develop` branch in the repository.
|
||||
|
||||
6. **Isolate the problem** — 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.
|
||||
29
README.md
@@ -1,6 +1,6 @@
|
||||
#  Grav
|
||||
#  Grav
|
||||
|
||||
[](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad) [](https://gitter.im/getgrav/grav?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad) [](https://gitter.im/getgrav/grav?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](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
@@ -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();
|
||||
|
||||
8
bin/grav
@@ -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');
|
||||
}
|
||||
|
||||
18
bin/plugin
@@ -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
@@ -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:
|
||||
@@ -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
@@ -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());
|
||||
|
||||
|
||||
4
system/assets/jquery/jquery-2.x.min.js
vendored
Normal 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;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ title: PLUGIN_ADMIN.FILE_STREAMS
|
||||
|
||||
form:
|
||||
validation: loose
|
||||
hidden: true
|
||||
fields:
|
||||
schemes.xxx:
|
||||
type: array
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
35
system/blueprints/pages/new_folder.yaml
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -41,4 +41,4 @@ form:
|
||||
label: PLUGIN_ADMIN.SITE_ACCESS
|
||||
multiple: false
|
||||
validate:
|
||||
type: array
|
||||
type: array
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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')) {
|
||||
|
||||
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
system/images/media/thumb.png
Normal file
|
After Width: | Height: | Size: 123 B |
@@ -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: tý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
|
||||
|
||||
@@ -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
@@ -0,0 +1,21 @@
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- Ιανουάριος
|
||||
- Φεβρουάριος
|
||||
- Μάρτιος
|
||||
- Απρίλιος
|
||||
- Μάιος
|
||||
- Ιούνιος
|
||||
- Ιούλιος
|
||||
- Αύγουστος
|
||||
- Σεπτέμβριος
|
||||
- Οκτώβριος
|
||||
- Νοέμβριος
|
||||
- Δεκέμβριος
|
||||
DAYS_OF_THE_WEEK:
|
||||
- Δευτέρα
|
||||
- Τρλιτη
|
||||
- Τετάρτη
|
||||
- Πέμπτη
|
||||
- Παρασκευή
|
||||
- Σαββάτο
|
||||
- Κυριακή
|
||||
@@ -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']
|
||||
|
||||
@@ -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: dí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: dí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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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: 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: ó
|
||||
DAY_PLURAL: nap
|
||||
WK_PLURAL: hét
|
||||
MO_PLURAL: hó
|
||||
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: hó
|
||||
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:'
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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']
|
||||
@@ -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
@@ -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: må
|
||||
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
@@ -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
@@ -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
@@ -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ă
|
||||
@@ -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
@@ -0,0 +1,2 @@
|
||||
NICETIME:
|
||||
DAY: dag
|
||||
@@ -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
|
||||
|
||||
@@ -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 '';
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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 . '/*');
|
||||
|
||||
@@ -35,6 +35,11 @@ class Composer
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the composer executable file path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getComposerExecutor()
|
||||
{
|
||||
$executor = PHP_BINARY . ' ';
|
||||
|
||||
@@ -192,7 +192,9 @@ abstract class CompiledBase
|
||||
}
|
||||
|
||||
$this->createObject($cache['data']);
|
||||
|
||||
|
||||
$this->finalizeObject();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -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'])) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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' => '&',
|
||||
'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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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(' ', ($level-1)*2) . $current->title();
|
||||
if ($rawRoutes) {
|
||||
$route = $current->rawRoute();
|
||||
} else {
|
||||
$route = $current->route();
|
||||
}
|
||||
$list[$route] = str_repeat(' ', ($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];
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||