mirror of
https://github.com/getgrav/grav.git
synced 2025-12-05 15:29:57 +01:00
Compare commits
801 Commits
1.6.0-beta
...
1.6.20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e507300134 | ||
|
|
463a55897c | ||
|
|
192cc4eb9b | ||
|
|
a592f6fe0b | ||
|
|
6b887a98cd | ||
|
|
18a26b42e2 | ||
|
|
a47e446b60 | ||
|
|
864a938f8d | ||
|
|
53bd1641bb | ||
|
|
7c0dcd6808 | ||
|
|
ea8b7b7a3a | ||
|
|
8714aa9202 | ||
|
|
3731d61b78 | ||
|
|
7b5d6f7031 | ||
|
|
a269d49392 | ||
|
|
3a8775f545 | ||
|
|
842dc0d49e | ||
|
|
1532de8f20 | ||
|
|
95bd217c3c | ||
|
|
f633c921cc | ||
|
|
e8c79ffd97 | ||
|
|
e842eb9d9e | ||
|
|
3e8572dbe9 | ||
|
|
ad8d0a2ab1 | ||
|
|
4a1e16449d | ||
|
|
41d31cb5ea | ||
|
|
909e2cbf89 | ||
|
|
1290503895 | ||
|
|
a204b24d78 | ||
|
|
86c969998f | ||
|
|
158874039a | ||
|
|
de6c35f4ab | ||
|
|
46816a74e9 | ||
|
|
1111c3d1b1 | ||
|
|
e919685ad3 | ||
|
|
238ba9b9b4 | ||
|
|
1d966a0c92 | ||
|
|
e3a6436031 | ||
|
|
f59441eb55 | ||
|
|
fcc0c5e345 | ||
|
|
c862b0bc26 | ||
|
|
575a1e4603 | ||
|
|
a74ccad282 | ||
|
|
ffeb5648c6 | ||
|
|
86c87929ec | ||
|
|
e0e92b843c | ||
|
|
8678f22f6b | ||
|
|
8322a0cfa3 | ||
|
|
ab6b82eaaa | ||
|
|
b16e8066ca | ||
|
|
bc1dd2a7b4 | ||
|
|
d11772b681 | ||
|
|
feeee9ef86 | ||
|
|
eb1b9567df | ||
|
|
c795ead402 | ||
|
|
91270c9c66 | ||
|
|
342eac1047 | ||
|
|
f72eb1b002 | ||
|
|
25caa5138a | ||
|
|
dffb227df6 | ||
|
|
5c9eb1cdb8 | ||
|
|
e30ab9a043 | ||
|
|
651b354d3e | ||
|
|
dd8b503aa0 | ||
|
|
dab30673e0 | ||
|
|
13689c2065 | ||
|
|
6e23627f26 | ||
|
|
7db85cc79c | ||
|
|
e5cedd074b | ||
|
|
ed87faad92 | ||
|
|
239f34d40c | ||
|
|
20b9ca56fa | ||
|
|
647ae0fda3 | ||
|
|
806dbd9ee5 | ||
|
|
1ab8442630 | ||
|
|
505661404b | ||
|
|
a2ea6faf4d | ||
|
|
ce51491b4d | ||
|
|
d241223aa3 | ||
|
|
d16f83fdd8 | ||
|
|
02e10ff8fe | ||
|
|
6a44d8f286 | ||
|
|
4b614d871f | ||
|
|
3286d70092 | ||
|
|
9fc37e46fa | ||
|
|
f304f429c5 | ||
|
|
65c73f639f | ||
|
|
d2833a1997 | ||
|
|
aa8f764436 | ||
|
|
618a59921a | ||
|
|
039f71dc61 | ||
|
|
27b8db4c10 | ||
|
|
afd53d76c2 | ||
|
|
57c65ad881 | ||
|
|
a372ae90c2 | ||
|
|
c8739c40a5 | ||
|
|
00ff9ac42d | ||
|
|
e13a8304e6 | ||
|
|
3c2b17853c | ||
|
|
288b2a1953 | ||
|
|
86b1f1fbac | ||
|
|
b5e26133a7 | ||
|
|
c97faa0238 | ||
|
|
69b39b4b21 | ||
|
|
02f544f813 | ||
|
|
69b5a779e4 | ||
|
|
fa5c1e495d | ||
|
|
7fdb2c10cb | ||
|
|
e422eebd3c | ||
|
|
3dca7e3539 | ||
|
|
75210b102e | ||
|
|
f0e97a7277 | ||
|
|
e16c81516e | ||
|
|
140c9a941f | ||
|
|
eb58fe9e97 | ||
|
|
5d4ea87402 | ||
|
|
9f1d7240a9 | ||
|
|
84894274f0 | ||
|
|
ea09002012 | ||
|
|
601ec5cb7a | ||
|
|
85ec2ee3a0 | ||
|
|
965f69f680 | ||
|
|
13a56dd4da | ||
|
|
4cf1b8c400 | ||
|
|
9c805a4317 | ||
|
|
b7b1182e14 | ||
|
|
f695aaaea4 | ||
|
|
b398d04d96 | ||
|
|
ac9ef4da76 | ||
|
|
a10893eaad | ||
|
|
0e0d5b23be | ||
|
|
e6c8b30882 | ||
|
|
a222e353ba | ||
|
|
30cfe3bdfa | ||
|
|
d227a82056 | ||
|
|
9825daa79b | ||
|
|
10d405112c | ||
|
|
c4c70d082c | ||
|
|
23a928c5b7 | ||
|
|
8a7f624558 | ||
|
|
92e8dbf4ea | ||
|
|
aca04cee6b | ||
|
|
7bc45bd9e0 | ||
|
|
9e5363b4df | ||
|
|
37f69d89cc | ||
|
|
30e96aa4ff | ||
|
|
7e1d3b260e | ||
|
|
be558ccac9 | ||
|
|
e991056106 | ||
|
|
b795155345 | ||
|
|
99d0c7cb3e | ||
|
|
01b85f19bc | ||
|
|
65ba214494 | ||
|
|
ccff51144e | ||
|
|
c8f6e7b0e1 | ||
|
|
7cccf8e237 | ||
|
|
e1f646c308 | ||
|
|
2a49a2ba7c | ||
|
|
e9bbd1e0b0 | ||
|
|
84e259f0f1 | ||
|
|
b3f4461f34 | ||
|
|
1df6b76e25 | ||
|
|
2153e20bc5 | ||
|
|
0cbc98ab53 | ||
|
|
0915a0413d | ||
|
|
f4d3d302f4 | ||
|
|
5d5e2264c0 | ||
|
|
b39fc72bd2 | ||
|
|
d6d50c4b66 | ||
|
|
791ef8ad88 | ||
|
|
e0861e5505 | ||
|
|
48c9176d90 | ||
|
|
33cb20561e | ||
|
|
0acb38f586 | ||
|
|
1a41e00a4f | ||
|
|
48ef93e495 | ||
|
|
3f7da86711 | ||
|
|
11aa2314d5 | ||
|
|
179c5065ca | ||
|
|
7c60f73942 | ||
|
|
7095c665b7 | ||
|
|
c6d94885e0 | ||
|
|
d9ddab8239 | ||
|
|
a118d45177 | ||
|
|
416c400367 | ||
|
|
e6839530d8 | ||
|
|
fea9e53be3 | ||
|
|
c5b3792a60 | ||
|
|
4f83b5da5b | ||
|
|
504c8faf4c | ||
|
|
4d6db5b334 | ||
|
|
ec1fc1f1e3 | ||
|
|
563cf8900c | ||
|
|
0850c2f362 | ||
|
|
f30334d80f | ||
|
|
9057a804a2 | ||
|
|
4c5c26033a | ||
|
|
a4f679adcf | ||
|
|
e9e12392ac | ||
|
|
6b4663c2ff | ||
|
|
0411c3a98b | ||
|
|
972a758ac9 | ||
|
|
05d72306c6 | ||
|
|
18b7c0955d | ||
|
|
71cbbf4e1e | ||
|
|
0606e12872 | ||
|
|
afc7cac5ab | ||
|
|
471e3d8954 | ||
|
|
89a92cddc7 | ||
|
|
74988f1254 | ||
|
|
f2f2bc1cf8 | ||
|
|
31c5809e4a | ||
|
|
b4b8b63e24 | ||
|
|
9c0de8b0d3 | ||
|
|
f4cca777c2 | ||
|
|
8d7d143d01 | ||
|
|
d9109e9934 | ||
|
|
be8eb63944 | ||
|
|
9342981d8c | ||
|
|
6e9af3bb29 | ||
|
|
7e39755154 | ||
|
|
97af8919fc | ||
|
|
6cdfaeb8fb | ||
|
|
4ea00b0140 | ||
|
|
864c5027c6 | ||
|
|
0bb55faa2d | ||
|
|
f757863e1c | ||
|
|
3ffd2f5f5e | ||
|
|
6aa135e80a | ||
|
|
07f4bd0699 | ||
|
|
c200a55336 | ||
|
|
14fed2bb75 | ||
|
|
44ecd61489 | ||
|
|
882212520f | ||
|
|
9467939f53 | ||
|
|
e3933ebdf6 | ||
|
|
0d99a03c39 | ||
|
|
e9117301d4 | ||
|
|
bf199e9394 | ||
|
|
c070b0afbb | ||
|
|
d54387b281 | ||
|
|
2bc6848464 | ||
|
|
ab7c5d2fc5 | ||
|
|
abefbfc776 | ||
|
|
ad173ca129 | ||
|
|
d69ef0e39c | ||
|
|
436be17881 | ||
|
|
9a5fa7e699 | ||
|
|
d502ff08c1 | ||
|
|
14eb1281f9 | ||
|
|
8fd7a5aebe | ||
|
|
08423df547 | ||
|
|
40563ed2f8 | ||
|
|
b639f09ca7 | ||
|
|
dd134ad551 | ||
|
|
3d93d50cf0 | ||
|
|
f1da7b6063 | ||
|
|
ef7b33f9b6 | ||
|
|
0f0e6ab1c8 | ||
|
|
5362b312d1 | ||
|
|
ca4d6a398f | ||
|
|
ed00d480f2 | ||
|
|
057bdd546b | ||
|
|
7762f0c85e | ||
|
|
1e6c01ea65 | ||
|
|
4b777f508b | ||
|
|
d15f125964 | ||
|
|
32b435b7e6 | ||
|
|
31d301911f | ||
|
|
911eec5e68 | ||
|
|
2e4bb25e2e | ||
|
|
d99c80eae9 | ||
|
|
0e03240d13 | ||
|
|
02064117bc | ||
|
|
a9e0cc7159 | ||
|
|
6b4332db72 | ||
|
|
0f591953a0 | ||
|
|
0a5e78ccc6 | ||
|
|
fbf7c50a12 | ||
|
|
09c1255239 | ||
|
|
75650ceba3 | ||
|
|
e2a65004f3 | ||
|
|
d4e1bcc660 | ||
|
|
b1b1670c77 | ||
|
|
5a3674f6f6 | ||
|
|
e622e204bf | ||
|
|
c378b06a90 | ||
|
|
c6ce6e6c32 | ||
|
|
355f7ee748 | ||
|
|
c19fa22a26 | ||
|
|
5ba4c8ee5b | ||
|
|
306df5837d | ||
|
|
66bba376db | ||
|
|
ec07d37623 | ||
|
|
cab78d36f3 | ||
|
|
449682baea | ||
|
|
6eb11b9717 | ||
|
|
5a1d138d08 | ||
|
|
dfd75efbe5 | ||
|
|
76ed48fc7c | ||
|
|
1043b9a189 | ||
|
|
e401c683f5 | ||
|
|
9d4fe331fa | ||
|
|
fbae3fd194 | ||
|
|
022f1ce758 | ||
|
|
b367c664c7 | ||
|
|
8512968726 | ||
|
|
2ffc110f03 | ||
|
|
36836c516f | ||
|
|
1f288c25de | ||
|
|
a4b62d48b2 | ||
|
|
397f6902f3 | ||
|
|
e97bceed56 | ||
|
|
7efc0f418e | ||
|
|
ac2a4e1c06 | ||
|
|
ef43348020 | ||
|
|
b6e68bb362 | ||
|
|
8d9ceb5d99 | ||
|
|
af47825b76 | ||
|
|
a4c88697af | ||
|
|
45fbfb098a | ||
|
|
9172e442f2 | ||
|
|
3b91f9af8c | ||
|
|
d5e9cc4bfe | ||
|
|
bb719c5d53 | ||
|
|
05a6775b08 | ||
|
|
1accbb8edc | ||
|
|
a04a7f5714 | ||
|
|
f31f7f7499 | ||
|
|
354d6f307c | ||
|
|
90aa4083ca | ||
|
|
5fbd252db9 | ||
|
|
04d3237a89 | ||
|
|
55aaaeed47 | ||
|
|
84d995335e | ||
|
|
f7d3299ebb | ||
|
|
e762c3add9 | ||
|
|
df6bb065d3 | ||
|
|
2fed02affa | ||
|
|
a739ed6825 | ||
|
|
90c708db2b | ||
|
|
fcbd819f48 | ||
|
|
a25d18bca7 | ||
|
|
4480077894 | ||
|
|
e9aa338c1e | ||
|
|
88a3e874aa | ||
|
|
87814039bc | ||
|
|
af72951671 | ||
|
|
5f2dfc8221 | ||
|
|
c706756d19 | ||
|
|
a4801ead6a | ||
|
|
a57cec8404 | ||
|
|
8b171435a7 | ||
|
|
ab23d071a4 | ||
|
|
3e6c4e9c5e | ||
|
|
28db98c95d | ||
|
|
95583dbbcd | ||
|
|
9d8fc4a065 | ||
|
|
b23cd7bb65 | ||
|
|
28d5be982c | ||
|
|
3836e4d38a | ||
|
|
4ebfd51e98 | ||
|
|
25ff1241d4 | ||
|
|
0dc3e5806e | ||
|
|
982b12a239 | ||
|
|
5995515419 | ||
|
|
8c1c813acd | ||
|
|
0e95d7faf6 | ||
|
|
47c3d4bf9b | ||
|
|
33282e043b | ||
|
|
81efef7c60 | ||
|
|
2678f56499 | ||
|
|
cd8f578b39 | ||
|
|
ab535ec8be | ||
|
|
ada6c3f160 | ||
|
|
0917850634 | ||
|
|
c09a8fbbc4 | ||
|
|
2b392055c1 | ||
|
|
45acd237f5 | ||
|
|
cbf79e38c4 | ||
|
|
ed10ce03e2 | ||
|
|
561abc851f | ||
|
|
8789fd91ee | ||
|
|
b835db49f4 | ||
|
|
a5e832b0b0 | ||
|
|
2b16f813ef | ||
|
|
30b013f5b0 | ||
|
|
5eccfaa34b | ||
|
|
fde69ade6b | ||
|
|
af3d5e9683 | ||
|
|
c757e00ac9 | ||
|
|
19d61b4013 | ||
|
|
b4a4b60871 | ||
|
|
9727f30c61 | ||
|
|
db8e5b3cbb | ||
|
|
b0b6c1dd17 | ||
|
|
47bb35e2e9 | ||
|
|
2433e0d2cd | ||
|
|
cdf891478e | ||
|
|
39b1940f94 | ||
|
|
8564524984 | ||
|
|
2f74f0f587 | ||
|
|
6e2e533184 | ||
|
|
ecd39421d6 | ||
|
|
68d43a0c88 | ||
|
|
c80a3f5568 | ||
|
|
b3d84a05f5 | ||
|
|
95495614a8 | ||
|
|
45d7a164b5 | ||
|
|
97b236d117 | ||
|
|
8718c5ef31 | ||
|
|
7d7418df26 | ||
|
|
dd9aa5bf78 | ||
|
|
7f86f8eb6f | ||
|
|
8b4cac7ba6 | ||
|
|
b388e91177 | ||
|
|
a2ac3f4c8b | ||
|
|
1db8b93cfa | ||
|
|
6217ac90e0 | ||
|
|
bb385490bc | ||
|
|
a5e48ba160 | ||
|
|
c7a4e8e4bb | ||
|
|
85d5b6e889 | ||
|
|
1c725c02f0 | ||
|
|
5008672a48 | ||
|
|
4e03f19bac | ||
|
|
a03c328ee3 | ||
|
|
77ac68f2e8 | ||
|
|
02acc34461 | ||
|
|
a402a8ef84 | ||
|
|
60573c1d78 | ||
|
|
56adf40bb4 | ||
|
|
d33c45165d | ||
|
|
032acedafe | ||
|
|
6a48216afb | ||
|
|
85af461eb4 | ||
|
|
4b1a129f38 | ||
|
|
1762ef3d1e | ||
|
|
8ffba2d88d | ||
|
|
f19cb94f89 | ||
|
|
8fb7caa22a | ||
|
|
07646860f2 | ||
|
|
6765c5f594 | ||
|
|
026f9cb3a0 | ||
|
|
516dfd5c26 | ||
|
|
1fbd5e0b38 | ||
|
|
b35a892853 | ||
|
|
578f8e4947 | ||
|
|
a934dd4fff | ||
|
|
18625758e5 | ||
|
|
eb689c417b | ||
|
|
df226a1102 | ||
|
|
8947f5ade9 | ||
|
|
941a5db8de | ||
|
|
2fcaaea6ac | ||
|
|
5887a396c1 | ||
|
|
f934256e06 | ||
|
|
ccb465e998 | ||
|
|
1b0a6e99f7 | ||
|
|
2e647be565 | ||
|
|
863123ac92 | ||
|
|
434620dea0 | ||
|
|
212d7d24ef | ||
|
|
61cf416df4 | ||
|
|
ff23f6b015 | ||
|
|
d59d60647c | ||
|
|
cf088d00ff | ||
|
|
dd5a10d0e2 | ||
|
|
0da39aa397 | ||
|
|
2dff43acba | ||
|
|
c97853e1aa | ||
|
|
c9be74fe39 | ||
|
|
e7df9c1dca | ||
|
|
3c680cd8e8 | ||
|
|
3545761b92 | ||
|
|
72016d7e7c | ||
|
|
6c1701ea5a | ||
|
|
28372be982 | ||
|
|
58f85212db | ||
|
|
c39bdaf7f2 | ||
|
|
16ab2e59f1 | ||
|
|
29c65c74db | ||
|
|
fee77d7301 | ||
|
|
21d9fa1e74 | ||
|
|
b4d973bfd0 | ||
|
|
993db32652 | ||
|
|
a0f4878c12 | ||
|
|
452df10ea1 | ||
|
|
a3bf38b182 | ||
|
|
674ea8ae25 | ||
|
|
94610f4e61 | ||
|
|
b2df60647d | ||
|
|
e8650a55af | ||
|
|
09805f7091 | ||
|
|
a63040aa11 | ||
|
|
3e97ecab68 | ||
|
|
409b4028d0 | ||
|
|
85b4996dbf | ||
|
|
e7041ff48e | ||
|
|
793b56fc8c | ||
|
|
ea91601459 | ||
|
|
6e3edb7dfb | ||
|
|
4e38c1fe25 | ||
|
|
2adb13ac66 | ||
|
|
d565c4af16 | ||
|
|
877529ae5b | ||
|
|
8b89c2c52e | ||
|
|
427ba0e420 | ||
|
|
4be7aa5665 | ||
|
|
9bd66031ab | ||
|
|
48816d9f2e | ||
|
|
031bfdc1e7 | ||
|
|
88121aaab4 | ||
|
|
8f588aca99 | ||
|
|
5b34a9bfc4 | ||
|
|
ef55d2615f | ||
|
|
1391dd38a4 | ||
|
|
f8f1d5854c | ||
|
|
a1c8cb9f78 | ||
|
|
54ce1b570a | ||
|
|
f2d66c810a | ||
|
|
26de0340ec | ||
|
|
333fbd0db1 | ||
|
|
4cf4c09339 | ||
|
|
34bf8fb5bb | ||
|
|
06eee1e711 | ||
|
|
b6ab086bf7 | ||
|
|
b1d43d292d | ||
|
|
19b92f17dd | ||
|
|
c713625a38 | ||
|
|
24e6b6c8f1 | ||
|
|
cebe28e591 | ||
|
|
b111a2c29d | ||
|
|
8743a8080c | ||
|
|
f2155aa04f | ||
|
|
45346b72f2 | ||
|
|
632a2d79b6 | ||
|
|
2fa5021a0c | ||
|
|
e4b1d2ed9e | ||
|
|
a3fea3d0fc | ||
|
|
d50e5d954d | ||
|
|
970af3870e | ||
|
|
9ba572d788 | ||
|
|
ba2c37c216 | ||
|
|
0e14a325f8 | ||
|
|
1141dabbd8 | ||
|
|
7a044c7397 | ||
|
|
d0b3dd1d99 | ||
|
|
4f80a1567d | ||
|
|
23098a6b02 | ||
|
|
5c8a37be64 | ||
|
|
7b8944e8f2 | ||
|
|
37fcb12ad1 | ||
|
|
f312c44a46 | ||
|
|
999e439d47 | ||
|
|
0566185c4f | ||
|
|
b91574e5c2 | ||
|
|
604361045b | ||
|
|
d45efb484c | ||
|
|
610c6c341c | ||
|
|
6daf480bfc | ||
|
|
bbdac0fd6d | ||
|
|
5f5bfdaa42 | ||
|
|
ad7fdd5c2b | ||
|
|
1321e582d5 | ||
|
|
6d6689b431 | ||
|
|
f78658738a | ||
|
|
7c99ece0e1 | ||
|
|
9058e1166d | ||
|
|
ebd94a532c | ||
|
|
95a4ecb0f1 | ||
|
|
ff8cc83b3a | ||
|
|
fbd3bbdbf9 | ||
|
|
f0e58adfbc | ||
|
|
5ad4ffd3cf | ||
|
|
0700e4bfdb | ||
|
|
82e5df960d | ||
|
|
3ace15d01a | ||
|
|
d367e6a1fb | ||
|
|
a09940ef6a | ||
|
|
6d89108cc4 | ||
|
|
bd01b07b4b | ||
|
|
4e31a114ef | ||
|
|
18d53079dd | ||
|
|
57de7cc03d | ||
|
|
2d7eeb611d | ||
|
|
e6b6e218f8 | ||
|
|
243055289b | ||
|
|
52c7d8dfb7 | ||
|
|
5b0e2e401e | ||
|
|
8381261b7c | ||
|
|
2ada99d314 | ||
|
|
bd27d6fe8c | ||
|
|
b94631533d | ||
|
|
fb9baaed8a | ||
|
|
254fe990ba | ||
|
|
0afe9d4f93 | ||
|
|
ccca3170d3 | ||
|
|
00b1f12dda | ||
|
|
9ca411aa24 | ||
|
|
e976aa0f5f | ||
|
|
02c979bdf6 | ||
|
|
88625c6362 | ||
|
|
76ff68a594 | ||
|
|
d27a2171ea | ||
|
|
075498d03b | ||
|
|
f04ae315e4 | ||
|
|
2e277f3cb3 | ||
|
|
29098aa8db | ||
|
|
659cd1bb92 | ||
|
|
3bf7c6943a | ||
|
|
189e29b5c6 | ||
|
|
0ede252fa3 | ||
|
|
d7d69b2be8 | ||
|
|
d79729f596 | ||
|
|
988d4ab047 | ||
|
|
437866dfcd | ||
|
|
c40dcf020c | ||
|
|
e520bd0eb8 | ||
|
|
3a9e57e228 | ||
|
|
22ed1286e8 | ||
|
|
1a37c54316 | ||
|
|
b6328944a3 | ||
|
|
751d1da704 | ||
|
|
5cf4eea09e | ||
|
|
f0cf4ed8ff | ||
|
|
fa61ed17b1 | ||
|
|
f1363877d8 | ||
|
|
e8825beae5 | ||
|
|
830a83e3d1 | ||
|
|
7d249c61c2 | ||
|
|
a224c8b348 | ||
|
|
c04208d5dd | ||
|
|
394dfad566 | ||
|
|
2c55fe01ac | ||
|
|
680bfef2c3 | ||
|
|
a23cbd0257 | ||
|
|
f5b77e8082 | ||
|
|
10378ac5af | ||
|
|
4a290e6194 | ||
|
|
c2c0fb242b | ||
|
|
9b37e50492 | ||
|
|
6c6e8d2605 | ||
|
|
5a6e6dceda | ||
|
|
e8631da9f3 | ||
|
|
5d57713f95 | ||
|
|
28bd4027cd | ||
|
|
108541e0d0 | ||
|
|
54a177279f | ||
|
|
b3e9974e95 | ||
|
|
2ad66102d2 | ||
|
|
6828114e86 | ||
|
|
f53b43de14 | ||
|
|
d53dbdf5ba | ||
|
|
8ba00f5967 | ||
|
|
56c7b8ca5f | ||
|
|
d6115007ab | ||
|
|
ba53d876bc | ||
|
|
2d593995ee | ||
|
|
3808776ddb | ||
|
|
9a118d0a71 | ||
|
|
684d6d3389 | ||
|
|
89a0e960e2 | ||
|
|
1b21e01938 | ||
|
|
3b692a27b4 | ||
|
|
3c83f379ee | ||
|
|
0c344df07a | ||
|
|
2a20959660 | ||
|
|
94a843429d | ||
|
|
34e6b6652a | ||
|
|
1ba785f28e | ||
|
|
bac24cf520 | ||
|
|
40b7d53349 | ||
|
|
96d44b4322 | ||
|
|
bf127fb0bd | ||
|
|
501bc0133f | ||
|
|
787bf8beeb | ||
|
|
257396aa06 | ||
|
|
7eb469f0ae | ||
|
|
156e544ab9 | ||
|
|
b38a143c66 | ||
|
|
cd21d65400 | ||
|
|
b19cb1215b | ||
|
|
48acad3e47 | ||
|
|
009db01ab9 | ||
|
|
7d8fff9571 | ||
|
|
9d048f5f36 | ||
|
|
cb4ea86310 | ||
|
|
2b099c2ed5 | ||
|
|
6afb55cc30 | ||
|
|
0937e0ff91 | ||
|
|
d602cb6e9e | ||
|
|
e02fa1a4e7 | ||
|
|
9e1661eb8c | ||
|
|
00c6313102 | ||
|
|
f01792ae81 | ||
|
|
bc18b9408b | ||
|
|
fa948c04ab | ||
|
|
8fdd34c245 | ||
|
|
cd5bda3f9e | ||
|
|
e14129d278 | ||
|
|
decb19b92e | ||
|
|
eb770e95d5 | ||
|
|
77f035eb2d | ||
|
|
db2738978e | ||
|
|
180f3c2eca | ||
|
|
e84fbc425f | ||
|
|
c5e2ed9f22 | ||
|
|
a92f0898d8 | ||
|
|
d968901d98 | ||
|
|
c38b761871 | ||
|
|
b49741f8aa | ||
|
|
6866c2a39a | ||
|
|
9598cd13fe | ||
|
|
49c8fef5f5 | ||
|
|
13341f8aa8 | ||
|
|
251cb3f9fa | ||
|
|
51767a8f36 | ||
|
|
c653fe6e4a | ||
|
|
70688f3e00 | ||
|
|
e9c52046fa | ||
|
|
a01b94f80b | ||
|
|
708c79cef8 | ||
|
|
f1ce69d4bf | ||
|
|
5bd417aa39 | ||
|
|
2bf448c587 | ||
|
|
b6c582ad3a | ||
|
|
c35c285580 | ||
|
|
890a61358a | ||
|
|
7de66cdc53 | ||
|
|
b353ec12e1 | ||
|
|
48489ae291 | ||
|
|
85a3d98d4c | ||
|
|
c9eea7e019 | ||
|
|
da483d63f6 | ||
|
|
3f89b39b60 | ||
|
|
e89b5ce870 | ||
|
|
88f6d02c03 | ||
|
|
cc78fcf31c | ||
|
|
37e880b64a | ||
|
|
75b2307d30 | ||
|
|
9e8f700119 | ||
|
|
4bcba0e4f9 | ||
|
|
11b661cad5 | ||
|
|
5e1980d770 | ||
|
|
5e7eb6b2f4 | ||
|
|
994a1f89cd | ||
|
|
4daa07fd14 | ||
|
|
d39165f506 | ||
|
|
468db9566b | ||
|
|
33309105d3 | ||
|
|
8cfe6e772d | ||
|
|
bad6e32e18 | ||
|
|
02d48693dd | ||
|
|
7975ec8d09 | ||
|
|
de898b610d | ||
|
|
0743816822 | ||
|
|
bb4958115b | ||
|
|
b64404a924 | ||
|
|
9a8b47872e | ||
|
|
76070ddd43 | ||
|
|
22066e11b3 | ||
|
|
ef157c7d2b | ||
|
|
e42e9fdd54 | ||
|
|
e2594dc72c | ||
|
|
f4e2153291 | ||
|
|
44db0245a7 | ||
|
|
ff5aa8a0ac | ||
|
|
8c0dd6a8d1 | ||
|
|
1ba21afd30 | ||
|
|
e73537f488 | ||
|
|
9405418572 | ||
|
|
59ccd662c7 | ||
|
|
377751416b | ||
|
|
116c279f01 | ||
|
|
1d8ef45e9c | ||
|
|
380b3be928 | ||
|
|
c151043c70 | ||
|
|
64e13c5f87 | ||
|
|
b55d29dfb7 | ||
|
|
bf86b5a924 | ||
|
|
9f2da67d48 | ||
|
|
d0b34d114d | ||
|
|
d0c9e56aeb | ||
|
|
74cd3ac1e0 | ||
|
|
ecbc401584 | ||
|
|
0c81568df6 | ||
|
|
b9dc2baef1 | ||
|
|
9b43f20159 | ||
|
|
82d3d5edda | ||
|
|
005f626b88 | ||
|
|
63005a8280 | ||
|
|
2943294d08 | ||
|
|
ed03b02e52 | ||
|
|
f43f992125 | ||
|
|
0b646875d0 | ||
|
|
b1b4469d18 | ||
|
|
72cc5b9d07 | ||
|
|
b9c28c5a7c | ||
|
|
c56d7ac793 | ||
|
|
000bac8cfc |
@@ -13,6 +13,5 @@ indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
# 2 space indentation
|
||||
[*.yaml, *.yml]
|
||||
indent_style = space
|
||||
[*.{yaml,.yml}]
|
||||
indent_size = 2
|
||||
|
||||
8
.github/FUNDING.yml
vendored
Normal file
8
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: grav
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
custom: # Replace with a single custom sponsorship URL
|
||||
@@ -2,6 +2,7 @@ language: php
|
||||
php:
|
||||
- '7.1'
|
||||
- '7.2'
|
||||
- '7.3'
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
@@ -11,13 +12,6 @@ notifications:
|
||||
email:
|
||||
on_success: never
|
||||
on_failure: always
|
||||
hipchat:
|
||||
# hipchat_api@grav
|
||||
rooms:
|
||||
- secure: "bqO0wM1B7bJnQw2fuhquSXEqI9gw6WmFytIh9sEWXzbYTzTUP5t0PcKOd3FT2BNMRaDxPJLVl+vG/oqmqDUBkEmOGcG504IQjeNzZqnMz0tXQMIcCc22Las9tFfc4Jf6RVi/qGomFtHGE9Wgii+TAN4zqZaufbNjwd8SyjO0+W8="
|
||||
template:
|
||||
- '%{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:
|
||||
|
||||
479
CHANGELOG.md
479
CHANGELOG.md
@@ -1,12 +1,354 @@
|
||||
# v1.6.0-beta.5
|
||||
## 11/05/2018
|
||||
# v1.6.20
|
||||
## 03/02/2020
|
||||
|
||||
1. [](#bugfix)
|
||||
* Fixed incorrect routing caused by `str_replace()` in `Uri::init()` [#2754](https://github.com/getgrav/grav/issues/2754)
|
||||
* Fixed session cookie is being set twice in the HTTP header [#2745](https://github.com/getgrav/grav/issues/2745)
|
||||
* Fixed session not restarting if user was invalid (downgrading from Grav 1.7)
|
||||
* Fixed filesystem iterator calls with non-existing folders
|
||||
* Fixed `checkbox` field not being saved, requires also Form v4.0.2 [#1225](https://github.com/getgrav/grav/issues/1225)
|
||||
* Fixed `validation: strict` not working in blueprints [#1273](https://github.com/getgrav/grav/issues/1273)
|
||||
* Fixed `Data::filter()` removing empty fields (such as empty list) by default [#2805](https://github.com/getgrav/grav/issues/2805)
|
||||
* Fixed fatal error with non-integer page param value [#2803](https://github.com/getgrav/grav/issues/2803)
|
||||
* Fixed `Assets::addInlineJs()` parameter type mismatch between v1.5 and v1.6 [#2659](https://github.com/getgrav/grav/issues/2659)
|
||||
* Fixed `site.metadata` saving issues [#2615](https://github.com/getgrav/grav/issues/2615)
|
||||
|
||||
# v1.6.19
|
||||
## 12/04/2019
|
||||
|
||||
1. [](#new)
|
||||
* Catch PHP 7.4 deprecation messages and report them in debugbar instead of throwing fatal error
|
||||
1. [](#bugfix)
|
||||
* Fixed fatal error when calling `{{ grav.undefined }}`
|
||||
* Fixed multiple issues when there are no pages in the site
|
||||
* PHP 7.4 fix for [#2750](https://github.com/getgrav/grav/issues/2750)
|
||||
|
||||
# v1.6.18
|
||||
## 12/02/2019
|
||||
|
||||
1. [](#bugfix)
|
||||
* PHP 7.4 fix in `Pages::buildSort()`
|
||||
* Updated vendor libraries for PHP 7.4 fixes in Twig and other libraries
|
||||
* Fixed fatal error when `$page->id()` is null [#2731](https://github.com/getgrav/grav/pull/2731)
|
||||
* Fixed cache conflicts on pages with no set id
|
||||
* Fix rewrite rule for for `lighttpd` default config [#721](https://github.com/getgrav/grav/pull/2721)
|
||||
|
||||
# v1.6.17
|
||||
## 11/06/2019
|
||||
|
||||
1. [](#new)
|
||||
* Added working ETag (304 Not Modified) support based on the final rendered HTML
|
||||
1. [](#improved)
|
||||
* Safer file handling + customizable null char replacement in `CsvFormatter::decode()`
|
||||
* Change of Behavior: `Inflector::hyphenize` will now automatically trim dashes at beginning and end of a string.
|
||||
* Change in Behavior for `Folder::all()` so no longer fails if trying to copy non-existent dot file [#2581](https://github.com/getgrav/grav/pull/2581)
|
||||
* renamed composer `test-plugins` script to `phpstan-plugins` to be more explicit [#2637](https://github.com/getgrav/grav/pull/2637)
|
||||
1. [](#bugfix)
|
||||
* Fixed PHP 7.1 bug in FlexMedia
|
||||
* Fix cache image generation when using cropResize [#2639](https://github.com/getgrav/grav/pull/2639)
|
||||
* Fix `array_merge()` exception with non-array page header metadata [#2701](https://github.com/getgrav/grav/pull/2701)
|
||||
|
||||
# v1.6.16
|
||||
## 09/19/2019
|
||||
|
||||
1. [](#bugfix)
|
||||
* Fixed Flex user creation if file storage is being used [#2444](https://github.com/getgrav/grav/issues/2444)
|
||||
* Fixed `Badly encoded JSON data` warning when uploading files [#2663](https://github.com/getgrav/grav/issues/2663)
|
||||
|
||||
# v1.6.15
|
||||
## 08/20/2019
|
||||
|
||||
1. [](#improved)
|
||||
* Improved robots.txt [#2632](https://github.com/getgrav/grav/issues/2632)
|
||||
1. [](#bugfix)
|
||||
* Fixed broken markdown Twig tag [#2635](https://github.com/getgrav/grav/issues/2635)
|
||||
* Force Symfony 4.2 in Grav 1.6 to remove a bunch of deprecated messages
|
||||
|
||||
# v1.6.14
|
||||
## 08/18/2019
|
||||
|
||||
1. [](#bugfix)
|
||||
* Actually include fix for `system\router.php` [#2627](https://github.com/getgrav/grav/issues/2627)
|
||||
|
||||
# v1.6.13
|
||||
## 08/16/2019
|
||||
|
||||
1. [](#bugfix)
|
||||
* Regression fix for `system\router.php` [#2627](https://github.com/getgrav/grav/issues/2627)
|
||||
|
||||
# v1.6.12
|
||||
## 08/14/2019
|
||||
|
||||
1. [](#new)
|
||||
* Added support for custom `FormFlash` save locations
|
||||
* Added a new `Utils::arrayLower()` method for lowercasing arrays
|
||||
* Support new GRAV_BASEDIR environment variable [#2541](https://github.com/getgrav/grav/pull/2541)
|
||||
* Allow users to override plugin handler priorities [#2165](https://github.com/getgrav/grav/pull/2165)
|
||||
1. [](#improved)
|
||||
* Use new `Utils::getSupportedPageTypes()` to enforce `html,htm` at the front of the list [#2531](https://github.com/getgrav/grav/issues/2531)
|
||||
* Updated vendor libraries
|
||||
* Markdown filter is now page-aware so that it works with modular references [admin#1731](https://github.com/getgrav/grav-plugin-admin/issues/1731)
|
||||
* Check of `GRAV_USER_INSTANCE` constant is already defined [#2621](https://github.com/getgrav/grav/pull/2621)
|
||||
1. [](#bugfix)
|
||||
* Fixed some potential issues when `$grav['user']` is not set
|
||||
* Fixed error when calling `Media::add($name, null)`
|
||||
* Fixed `url()` returning wrong path if using stream with grav root path in it, eg: `user-data://shop` when Grav is in `/shop`
|
||||
* Fixed `url()` not returning a path to non-existing file (`user-data://shop` => `/user/data/shop`) if it is set to fail gracefully
|
||||
* Fixed `url()` returning false on unknown streams, such as `ftp://domain.com`, they should be treated as external URL
|
||||
* Fixed Flex User to have permissions to save and delete his own user
|
||||
* Fixed new Flex User creation not being possible because of username could not be given
|
||||
* Fixed fatal error 'Expiration date must be an integer, a DateInterval or null, "double" given' [#2529](https://github.com/getgrav/grav/issues/2529)
|
||||
* Fixed non-existing Flex object having a bad media folder
|
||||
* Fixed collections using `page@.self:` should allow modular pages if requested
|
||||
* Fixed an error when trying to delete a file from non-existing Flex Object
|
||||
* Fixed `FlexObject::exists()` failing sometimes just after the object has been saved
|
||||
* Fixed CSV formatter not encoding strings with `"` and `,` properly
|
||||
* Fixed var order in `Validation.php` [#2610](https://github.com/getgrav/grav/issues/2610)
|
||||
|
||||
# v1.6.11
|
||||
## 06/21/2019
|
||||
|
||||
1. [](#new)
|
||||
* Added `FormTrait::getAllFlashes()` method to get all the available form flash objects for the form
|
||||
* Added creation and update timestamps to `FormFlash` objects
|
||||
1. [](#improved)
|
||||
* Added `FormFlashInterface`, changed constructor to take `$config` array
|
||||
1. [](#bugfix)
|
||||
* Fixed error in `ImageMedium::url()` if the image cache folder does not exist
|
||||
* Fixed empty form flash name after file upload or form state update
|
||||
* Fixed a bug in `Route::withParam()` method
|
||||
* Fixed issue with `FormFlash` objects when there is no session initialized
|
||||
|
||||
# v1.6.10
|
||||
## 06/14/2019
|
||||
|
||||
1. [](#improved)
|
||||
* Added **page blueprints** to `YamlLinter` CLI and Admin reports
|
||||
* Removed `Gitter` and `Slack` [#2502](https://github.com/getgrav/grav/issues/2502)
|
||||
* Optimizations for Plugin/Theme loading
|
||||
* Generalized markdown classes so they can be used outside of `Page` scope with a custom `Excerpts` class instance
|
||||
* Change minimal port number to 0 (unix socket) [#2452](https://github.com/getgrav/grav/issues/2452)
|
||||
1. [](#bugfix)
|
||||
* Force question to install demo content in theme update [#2493](https://github.com/getgrav/grav/issues/2493)
|
||||
* Fixed GPM errors from blueprints not being logged [#2505](https://github.com/getgrav/grav/issues/2505)
|
||||
* Don't error when IP is invalid [#2507](https://github.com/getgrav/grav/issues/2507)
|
||||
* Fixed regression with `bin/plugin` not listing the plugins available (1c725c0)
|
||||
* Fixed bitwise operator in `TwigExtension::exifFunc()` [#2518](https://github.com/getgrav/grav/issues/2518)
|
||||
* Fixed issue with lang prefix incorrectly identifying as admin [#2511](https://github.com/getgrav/grav/issues/2511)
|
||||
* Fixed issue with `U0ils::pathPrefixedBYLanguageCode()` and trailing slash [#2510](https://github.com/getgrav/grav/issues/2511)
|
||||
* Fixed regresssion issue of `Utils::Url()` not returning `false` on failure. Added new optional `fail_gracefully` 3rd attribute to return string that caused failure [#2524](https://github.com/getgrav/grav/issues/2524)
|
||||
|
||||
# v1.6.9
|
||||
## 05/09/2019
|
||||
|
||||
1. [](#new)
|
||||
* Added `Route::withoutParams()` methods
|
||||
* Added `Pages::setCheckMethod()` method to override page configuration in Admin Plugin
|
||||
* Added `Cache::clearCache('invalidate')` parameter for just invalidating the cache without deleting any cached files
|
||||
* Made `UserCollectionInderface` to extend `Countable` to get the count of existing users
|
||||
1. [](#improved)
|
||||
* Flex admin: added default search options for flex objects
|
||||
* Flex collection and object now fall back to the default template if template file doesn't exist
|
||||
* Updated Vendor libraries including Twig 1.40.1
|
||||
* Updated language files from `https://crowdin.com/project/grav-core`
|
||||
1. [](#bugfix)
|
||||
* Fixed `$grav['route']` from being modified when the route instance gets modified
|
||||
* Fixed Assets options array mixed with standalone priority [#2477](https://github.com/getgrav/grav/issues/2477)
|
||||
* Fix for `avatar_url` provided by 3rd party providers
|
||||
* Fixed non standard `lang` code lengths in `Utils` and `Session` detection
|
||||
* Fixed saving a new object in Flex `SimpleStorage`
|
||||
* Fixed exception in `Flex::getDirectories()` if the first parameter is set
|
||||
* Output correct "Last Updated" in `bin/gpm info` command
|
||||
* Checkbox getting interpreted as string, so created new `Validation::filterCheckbox()`
|
||||
* Fixed backwards compatibility to `select` field with `selectize.create` set to true [git-sync#141](https://github.com/trilbymedia/grav-plugin-git-sync/issues/141)
|
||||
* Fixed `YamlFormatter::decode()` to always return array [#2494](https://github.com/getgrav/grav/pull/2494)
|
||||
* Fixed empty `$grav['request']->getAttribute('route')->getExtension()`
|
||||
|
||||
# v1.6.8
|
||||
## 04/23/2019
|
||||
|
||||
1. [](#new)
|
||||
* Added `FlexCollection::filterBy()` method
|
||||
1. [](#bugfix)
|
||||
* Revert `Use Null Coalesce Operator` [#2466](https://github.com/getgrav/grav/pull/2466)
|
||||
* Fixed `FormTrait::render()` not providing config variable
|
||||
* Updated `bin/grav clean` to clear `cache/compiled` and `user/config/security.yaml`
|
||||
|
||||
# v1.6.7
|
||||
## 04/22/2019
|
||||
|
||||
1. [](#new)
|
||||
* Added a new `bin/grav yamllinter` CLI command to find YAML Linting issues [#2468](https://github.com/getgrav/grav/issues/2468#issuecomment-485151681)
|
||||
1. [](#improved)
|
||||
* Improve `FormTrait` backwards compatibility with existing forms
|
||||
* Added a new `Utils::getSubnet()` function for IPv4/IPv6 parsing [#2465](https://github.com/getgrav/grav/pull/2465)
|
||||
1. [](#bugfix)
|
||||
* Remove disabled fields from the form schema
|
||||
* Fix issue when excluding `inlineJs` and `inlineCss` from Assets pipeline [#2468](https://github.com/getgrav/grav/issues/2468)
|
||||
* Fix for manually set position on external URLs [#2470](https://github.com/getgrav/grav/issues/2470)
|
||||
|
||||
# v1.6.6
|
||||
## 04/17/2019
|
||||
|
||||
1. [](#new)
|
||||
* `FormInterface` now implements `RenderInterface`
|
||||
* Added new `FormInterface::getTask()` method which reads the task from `form.task` in the blueprint
|
||||
1. [](#improved)
|
||||
* Updated vendor libraries to latest
|
||||
1. [](#bugfix)
|
||||
* Rollback `redirect_default_route` logic as it has issues with multi-lang [#2459](https://github.com/getgrav/grav/issues/2459)
|
||||
* Fix potential issue with `|contains` Twig filter on PHP 7.3
|
||||
* Fixed bug in text field filtering: return empty string if value isn't a string or number [#2460](https://github.com/getgrav/grav/issues/2460)
|
||||
* Force Asset `priority` to be an integer and not throw error if invalid string passed [#2461](https://github.com/getgrav/grav/issues/2461)
|
||||
* Fixed bug in text field filtering: return empty string if value isn't a string or number
|
||||
* Fixed `FlexForm` missing getter methods for defining form variables
|
||||
|
||||
# v1.6.5
|
||||
## 04/15/2019
|
||||
|
||||
1. [](#bugfix)
|
||||
* Backwards compatiblity with old `Uri::__toString()` output
|
||||
|
||||
# v1.6.4
|
||||
## 04/15/2019
|
||||
|
||||
1. [](#bugfix)
|
||||
* Improved `redirect_default_route` logic as well as `Uri::toArray()` to take into account `root_path` and `extension`
|
||||
* Rework logic to pull out excluded files from pipeline more reliably [#2445](https://github.com/getgrav/grav/issues/2445)
|
||||
* Better logic in `Utils::normalizePath` to handle externals properly [#2216](https://github.com/getgrav/grav/issues/2216)
|
||||
* Fixed to force all `Page::taxonomy` to be treated as strings [#2446](https://github.com/getgrav/grav/issues/2446)
|
||||
* Fixed issue with `Grav['user']` not being available [form#332](https://github.com/getgrav/grav-plugin-form/issues/332)
|
||||
* Updated rounding logic for `Utils::parseSize()` [#2394](https://github.com/getgrav/grav/issues/2394)
|
||||
* Fixed Flex simple storage not being properly initialized if used with caching
|
||||
|
||||
# v1.6.3
|
||||
## 04/12/2019
|
||||
|
||||
1. [](#new)
|
||||
* Added `Blueprint::addDynamicHandler()` method to allow custom dynamic handlers, for example `custom-options@: getCustomOptions`
|
||||
1. [](#bugfix)
|
||||
* Missed a `CacheCommand` reference in `bin/grav` [#2442](https://github.com/getgrav/grav/issues/2442)
|
||||
* Fixed issue with `Utils::normalizePath` messing with external URLs [#2216](https://github.com/getgrav/grav/issues/2216)
|
||||
* Fix for `vUndefined` versions when upgrading
|
||||
|
||||
# v1.6.2
|
||||
## 04/11/2019
|
||||
|
||||
1. [](#bugfix)
|
||||
* Revert renaming of `ClearCacheCommand` to ensure CLI GPM upgrades go smoothly
|
||||
|
||||
# v1.6.1
|
||||
## 04/11/2019
|
||||
|
||||
1. [](#improved)
|
||||
* Improved CSS for the bottom filter bar of DebugBar
|
||||
1. [](#bugfix)
|
||||
* Fixed issue with `@import` not being added to top of pipelined css [#2440](https://github.com/getgrav/grav/issues/2440)
|
||||
|
||||
# v1.6.0
|
||||
## 04/11/2019
|
||||
|
||||
1. [](#new)
|
||||
* Set minimum requirements to [PHP 7.1.3](https://getgrav.org/blog/raising-php-requirements-2018)
|
||||
* New `Scheduler` functionality for periodic jobs
|
||||
* New `Backup` functionality with multiple backup profiles and scheduler integration
|
||||
* Refactored `Assets Manager` to be more powerful and flexible
|
||||
* Updated Doctrine Collections to 1.6
|
||||
* Updated Doctrine Cache to 1.8
|
||||
* Updated Symfony Components to 4.2
|
||||
* Added new Cache purge functionality old cache manually via CLI/Admin as well as scheduler integration
|
||||
* Added new `{% throw 404 'Not Found' %}` twig tag (with custom code/message)
|
||||
* Added `Grav\Framework\File` classes for handling YAML, Markdown, JSON, INI and PHP serialized files
|
||||
* Added `Grav\Framework\Collection\AbstractIndexCollection` class
|
||||
* Added `Grav\Framework\Object\ObjectIndex` class
|
||||
* Added `Grav\Framework\Flex` classes
|
||||
* Added support for hiding form fields in blueprints by using dynamic property like `security@: admin.foobar`, `scope@: object` or `scope-ignore@: object` to any field
|
||||
* New experimental **FlexObjects** powered `Users` for increased performance and capability (**disabled** by default)
|
||||
* Added PSR-7 and PSR-15 classes
|
||||
* Added `Grav\Framework\DI\Container` class
|
||||
* Added `Grav\Framework\RequestHandler\RequestHandler` class
|
||||
* Added `Page::httpResponseCode()` and `Page::httpHeaders()` methods
|
||||
* Added `Grav\Framework\Form\Interfaces\FormInterface`
|
||||
* Added `Grav\Framework\Form\Interfaces\FormFactoryInterface`
|
||||
* Added `Grav\Framework\Form\FormTrait`
|
||||
* Added `Page::forms()` method to get normalized list of all form headers defined in the page
|
||||
* Added `onPageAction`, `onPageTask`, `onPageAction.{$action}` and `onPageTask.{$task}` events
|
||||
* Added `Blueprint::processForm()` method to filter form inputs
|
||||
* Move `processMarkdown()` method from `TwigExtension` to more general `Utils` class
|
||||
* Added support to include extra files into `Media` (such as uploaded files)
|
||||
* Added form preview support for `FlexObject`, including a way to render newly uploaded files before saving them
|
||||
* Added `FlexObject::getChanges()` to determine what fields change during an update
|
||||
* Added `arrayDiffMultidimensional`, `arrayIsAssociative`, `arrayCombine` Util functions
|
||||
* New `$grav['users']` service to allow custom user classes implementing `UserInterface`
|
||||
* Added `LogViewer` helper class and CLI command: `bin/grav logviewer`
|
||||
* Added `select()` and `unselect()` methods to `CollectionInterface` and its base classes
|
||||
* Added `orderBy()` and `limit()` methods to `ObjectCollectionInterface` and its base classes
|
||||
* Added `user-data://` which is a writable stream (`user://data` is not and should be avoided)
|
||||
* Added support for `/action:{$action}` (like task but used without nonce when only receiving data)
|
||||
* Added `onAction.{$action}` event
|
||||
* Added `Grav\Framework\Form\FormFlash` class to contain AJAX uploaded files in more reliable way
|
||||
* Added `Grav\Framework\Form\FormFlashFile` class which implements `UploadedFileInterface` from PSR-7
|
||||
* Added `Grav\Framework\Filesystem\Filesystem` class with methods to manipulate stream URLs
|
||||
* Added new `$grav['filesystem']` service using an instance of the new `Filesystem` object
|
||||
* Added `{% render object layout: 'default' with { variable: true } %}` for Flex objects and collections
|
||||
* Added `$grav->setup()` to simplify CLI and custom access points
|
||||
* Added `CsvFormatter` and `CsvFile` classes
|
||||
* Added new system config option to `pages.hide_empty_folders` if a folder has no valid `.md` file available. Default behavior is `false` for compatibility.
|
||||
* Added new system config option for `languages.pages_fallback_only` forcing only 'fallback' to find page content through supported languages, default behavior is to display any language found if active language is missing
|
||||
* Added `Utils::arrayFlattenDotNotation()` and `Utils::arrayUnflattenDotNotation()` helper methods
|
||||
1. [](#improved)
|
||||
* Add the page to onMarkdownInitialized event [#2412](https://github.com/getgrav/grav/issues/2412)
|
||||
* Doctrine filecache is now namespaced with prefix to support purging
|
||||
* Register all page types into `blueprint://pages` stream
|
||||
* Removed `apc` and `xcache` support, made `apc` alias of `apcu`
|
||||
* Support admin and regular translations via the `|t` twig filter and `t()` twig function
|
||||
* Improved Grav Core installer/updater to run installer script
|
||||
* Updated vendor libraries including Symfony `4.2.3`
|
||||
* Renamed old `User` class to `Grav\Common\User\DataUser\User` with multiple improvements and small fixes
|
||||
* `User` class now acts as a compatibility layer to older versions of Grav
|
||||
* Deprecated `new User()`, `User::load()`, `User::find()` and `User::delete()` in favor of `$grav['users']` service
|
||||
* `Media` constructor has now support to not to initialize the media objects
|
||||
* Cleanly handle session corruption due to changing Flex object types
|
||||
* Added `FlexObjectInterface::getDefaultValue()` and `FormInterface::getDefaultValue()`
|
||||
* Added new `onPageContent()` event for every call to `Page::content()`
|
||||
* Added phpstan: PHP Static Analysis Tool [#2393](https://github.com/getgrav/grav/pull/2393)
|
||||
* Added `composer test-plugins` to test plugin issues with the current version of Grav
|
||||
* Added `Flex::getObjects()` and `Flex::getMixedCollection()` methods for co-mingled collections
|
||||
* Added support to use single Flex key parameter in `Flex::getObject()` method
|
||||
* Added `FlexObjectInterface::search()` and `FlexCollectionInterface::search()` methods
|
||||
* Override `system.media.upload_limit` with PHP's `post_max_size` or `upload_max_filesize`
|
||||
* Class `Grav\Common\Page\Medium\AbstractMedia` now use array traits instead of extending `Grav\Common\Getters`
|
||||
* Implemented `Grav\Framework\Psr7` classes as `Nyholm/psr7` decorators
|
||||
* Added a new `cache-clear` scheduled job to go along with `cache-purge`
|
||||
* Renamed `Grav\Framework\File\Formatter\FormatterInterface` to `Grav\Framework\File\Interfaces\FileFormatterInterface`
|
||||
* Improved `File::save()` to use a temporary file if file isn't locked
|
||||
* Improved `|t` filter to better support admin `|tu` style filter if in admin
|
||||
* Update all classes to rely on `PageInterface` instead of `Page` class
|
||||
* Better error checking in `bin/plugin` for existence and enabled
|
||||
* Removed `media.upload_limit` references
|
||||
* Twig `nicenumber`: do not use 0 + string casting hack
|
||||
* Converted Twig tags to use namespaced Twig classes
|
||||
* Site shows error on page rather than hard-crash when page has invalid frontmatter [#2343](https://github.com/getgrav/grav/issues/2343)
|
||||
* Added `languages.default_lang` option to override the default lang (usually first supported language)
|
||||
* Added `Content-Type: application/json` body support for PSR-7 `ServerRequest`
|
||||
* Remove PHP time limit in `ZipArchive`
|
||||
* DebugBar: Resolve twig templates in deprecated backtraces in order to help locating Twig issues
|
||||
* Added `$grav['cache']->getSimpleCache()` method for getting PSR-16 compatible cache
|
||||
* MediaTrait: Use PSR-16 cache
|
||||
* Improved `Utils::normalizePath()` to support non-protocol URLs
|
||||
* Added ability to reset `Page::metadata` to allow rebuilding from automatically generated values
|
||||
* Added back missing `page.types` field in system content configuration [admin#1612](https://github.com/getgrav/grav-plugin-admin/issues/1612)
|
||||
* Console commands: add method for invalidating cache
|
||||
* Updated languages
|
||||
* Improved `$page->forms()` call, added `$page->addForms()`
|
||||
* Updated languages from crowdin
|
||||
* Fixed `ImageMedium` constructor warning when file does not exist
|
||||
* Improved `Grav\Common\User` class; added `$user->update()` method
|
||||
* Added trim support for text input fields `validate: trim: true`
|
||||
* Improved `Grav\Framework\File\Formatter` classes to have abstract parent class and some useful methods
|
||||
* Support negotiated content types set via the Request `Accept:` header
|
||||
* Support negotiated language types set via the Request `Accept-Language:` header
|
||||
* Cleaned up and sorted the Service `idMap`
|
||||
* Updated `Grav` container object to implement PSR-11 `ContainerInterface`
|
||||
* Updated Grav `Processor` classes to implement PSR-15 `MiddlewareInterface`
|
||||
* Make `Data` class to extend `JsonSerializable`
|
||||
@@ -15,67 +357,104 @@
|
||||
* Set session name based on `security.salt` rather than `GRAV_ROOT` [#2242](https://github.com/getgrav/grav/issues/2242)
|
||||
* Added option to configure list of `xss_invalid_protocols` in `Security` config [#2250](https://github.com/getgrav/grav/issues/2250)
|
||||
* Smarter `security.salt` checking now we use `security.yaml` for other options
|
||||
* Merged Grav 1.5.4 fixes in
|
||||
|
||||
# v1.6.0-beta.4
|
||||
## 10/24/2018
|
||||
|
||||
1. [](#new)
|
||||
* Added new system config option to `pages.hide_empty_folders` if a folder has no valid `.md` file available. Default behavior is `false` for compatibility.
|
||||
* Added new system config option for `languages.pages_fallback_only` forcing only 'fallback' to find page content through supported languages, default behavior is to display any language found if active language is missing
|
||||
* Added `Utils::arrayFlattenDotNotation()` and `Utils::arrayUnflattenDotNotation()` helper methods
|
||||
1. [](#improved)
|
||||
* Added apcu autoloader optimization
|
||||
* Additional helper methods in `Language`, `Languages`, and `LanguageCodes` classes
|
||||
1. [](#bugfix)
|
||||
* Use login provider User avatar if set
|
||||
* Fixed `Folder::doDelete($folder, false)` removing symlink when it should not
|
||||
|
||||
# v1.6.0-beta.3
|
||||
## 10/15/2018
|
||||
|
||||
1. [](#improved)
|
||||
* Call `onFatalException` event also on internal PHP errors
|
||||
* Built-in PHP Webserver: log requests before handling them
|
||||
1. [](#bugfix)
|
||||
* Grav 1.6: Scheduler Fallback for never runs and Windows support [#2202](https://github.com/getgrav/grav/pull/2202)
|
||||
|
||||
# v1.6.0-beta.2
|
||||
## 10/09/2018
|
||||
|
||||
1. [](#new)
|
||||
* Added Flex support for custom media tasks
|
||||
1. [](#improved)
|
||||
* Added support for syslog and syslog facility logging (default: 'file')
|
||||
* Improved usability of `System` configuration blueprint with side-tabs
|
||||
1. [](#bugfix)
|
||||
1. [](#bugfix)
|
||||
* Fixed issue with `Truncator::truncateWords` and `Truncator::truncateLetters` when string not wrapped in tags [#2432](https://github.com/getgrav/grav/issues/2432)
|
||||
* Fixed `Undefined method closure::fields()` when getting avatar for user, thanks @Romarain [#2422](https://github.com/getgrav/grav/issues/2422)
|
||||
* Fixed cached images not being updated when source image is modified
|
||||
* Fixed deleting last list item in the form
|
||||
* Fixed issue with `Utils::url()` method would append extra `base_url` if URL already included it
|
||||
* Fixed `mkdir(...)` race condition
|
||||
* Fixed `Obtaining write lock failed on file...`
|
||||
* Fixed potential undefined property in `onPageNotFound` event handling
|
||||
* Fixed some potential issues/bugs found by phpstan
|
||||
* Fixed regression in GPM packages casted to Array (ref, getgrav/grav-plugin-admin@e3fc4ce)
|
||||
* Fixed session_start(): Setting option 'session.name' failed [#2408](https://github.com/getgrav/grav/issues/2408)
|
||||
* Fixed validation for select field type with selectize
|
||||
* Fixed validation for boolean toggles
|
||||
* Fixed non-namespaced exceptions in scheduler
|
||||
* Fixed trailing slash redirect in multlang environment [#2350](https://github.com/getgrav/grav/issues/2350)
|
||||
* Fixed some issues related to Medium objects losing query string attributes
|
||||
* Broke out Medium timestamp so it's not cleared on `reset()`s
|
||||
* Fixed issue with `redirect_trailing_slash` losing query string [#2269](https://github.com/getgrav/grav/issues/2269)
|
||||
* Fixed failed login if user attempts to log in with upper case non-english letters
|
||||
* Removed extra authenticated/authorized fields when saving existing user from a form
|
||||
* Fixed `Grav\Framework\Route::__toString()` returning relative URL, not relative route
|
||||
* Fixed handling of `append_url_extension` inside of `Page::templateFormat()` [#2264](https://github.com/getgrav/grav/issues/2264)
|
||||
* Fixed a broken language string [#2261](https://github.com/getgrav/grav/issues/2261)
|
||||
* Fixed clearing cache having no effect on Doctrine cache
|
||||
* Fixed `Medium::relativePath()` for streams
|
||||
* Fixed `Object` serialization breaking if overriding `jsonSerialize()` method
|
||||
* Fixed `YamlFormatter::decode()` when calling `init_set()` with integer
|
||||
* Fixed session throwing error in CLI if initialized
|
||||
* Fixed `Uri::hasStandardPort()` to support reverse proxy configurations [#1786](https://github.com/getgrav/grav/issues/1786)
|
||||
* Use `append_url_extension` from page header to set template format if set [#2604](https://github.com/getgrav/grav/pull/2064)
|
||||
* Fixed some bugs in Grav environment selection logic
|
||||
* Use login provider User avatar if set
|
||||
* Fixed `Folder::doDelete($folder, false)` removing symlink when it should not
|
||||
* Fixed asset manager to not add empty assets when they don't exist in the filesystem
|
||||
* Regression: Fixed asset manager methods with default legacy attributes
|
||||
* Update `script` and `style` Twig tags to use the new `Assets` classes
|
||||
* Fixed asset pipeline to rewrite remote URLs as well as local [#2216](https://github.com/getgrav/grav/issues/2216)
|
||||
|
||||
# v1.6.0-beta.1
|
||||
## 10/01/2018
|
||||
# v1.5.10
|
||||
## 03/21/2019
|
||||
|
||||
1. [](#new)
|
||||
* Set minimum requirements to [PHP 7.1.3](https://getgrav.org/blog/raising-php-requirements-2018)
|
||||
* New `Scheduler` functionality for periodic jobs
|
||||
* New `Backup` functionality with multiple backup profiles and scheduler integration
|
||||
* Refactored `Assets Manager` to be more powerful and flexible
|
||||
* Updated Doctrine Collections to 1.5
|
||||
* Updated Doctrine Cache to 1.8
|
||||
* Updated Symfony Components to 4.1
|
||||
* Added a new Deferred Twig extension to allow adding content to Twig blocks after render
|
||||
* Added new Cache purge functionality old cache manually via CLI/Admin as well as scheduler integration
|
||||
* Added new `{% throw 404 'Not Found' %}` twig tag (with custom code/message)
|
||||
* Added `Grav\Framework\File` classes for handling YAML, Markdown, JSON, INI and PHP serialized files
|
||||
* Added `Grav\Framework\Collection\AbstractIndexCollection` class
|
||||
* Added `Grav\Framework\Object\ObjectIndex` class
|
||||
* Added `Grav\Framework\Flex` classes
|
||||
* Added support for hiding form fields in blueprints by using dynamic property like `security@: admin.foobar`, `scope@: object` or `scope-ignore@: object` to any field
|
||||
* Added new `deferred` Twig extension
|
||||
|
||||
# v1.5.9
|
||||
## 03/20/2019
|
||||
|
||||
1. [](#new)
|
||||
* Added new `onPageContent()` event for every call to `Page::content()`
|
||||
1. [](#improved)
|
||||
* Doctrine filecache is now namespaced with prefix to support purging
|
||||
* Register all page types into `blueprint://pages` stream
|
||||
* Fixed phpdoc generation
|
||||
* Updated vendor libraries
|
||||
* Force Toolbox v1.4.2
|
||||
1. [](#bugfix)
|
||||
* EXIF fix for streams
|
||||
* Fix for User avatar not working due to uppercase or spaces in email [#2403](https://github.com/getgrav/grav/pull/2403)
|
||||
|
||||
# v1.5.8
|
||||
## 02/07/2019
|
||||
|
||||
1. [](#improved)
|
||||
* Improved `User` unserialize to not to break the object if serialized data is not what expected
|
||||
* Removed unused parameter [#2357](https://github.com/getgrav/grav/pull/2357)
|
||||
|
||||
# v1.5.7
|
||||
## 01/25/2019
|
||||
|
||||
1. [](#new)
|
||||
* Support for AWS Cloudfront forwarded scheme header [#2297](https://github.com/getgrav/grav/pull/2297)
|
||||
1. [](#improved)
|
||||
* Set homepage with `https://` protocol [#2299](https://github.com/getgrav/grav/pull/2299)
|
||||
* Preserve accents in fields containing Twig expr. using unicode [#2279](https://github.com/getgrav/grav/pull/2279)
|
||||
* Updated vendor libraries
|
||||
1. [](#bugfix)
|
||||
* Support spaces with filenames in responsive images [#2300](https://github.com/getgrav/grav/pull/2300)
|
||||
|
||||
# v1.5.6
|
||||
## 12/14/2018
|
||||
|
||||
1. [](#improved)
|
||||
* Updated InitializeProcessor.php to use lang-safe redirect [#2268](https://github.com/getgrav/grav/pull/2268)
|
||||
* Improved user serialization to use less memory in the session
|
||||
|
||||
# v1.5.5
|
||||
## 11/12/2018
|
||||
|
||||
1. [](#new)
|
||||
* Register theme prefixes as namespaces in Twig [#2210](https://github.com/getgrav/grav/pull/2210)
|
||||
1. [](#improved)
|
||||
* Propogate error code between 400 and 600 for production sites [#2181](https://github.com/getgrav/grav/pull/2181)
|
||||
1. [](#bugfix)
|
||||
* Remove hardcoded `302` when redirecting trailing slash [#2155](https://github.com/getgrav/grav/pull/2155)
|
||||
|
||||
# v1.5.4
|
||||
## 11/05/2018
|
||||
|
||||
@@ -29,7 +29,7 @@ The issue tracker is the preferred channel for [bug reports](#bugs),
|
||||
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).
|
||||
[the Forum](http://getgrav.org/forum) or [the Chat](https://chat.getgrav.org/).
|
||||
|
||||
|
||||
<a name="bugs"></a>
|
||||
@@ -110,7 +110,8 @@ 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 [Slack](https://getgrav.org/slack) or in the Forum before embarking on any significant pull request (e.g.
|
||||
**Please ask first** in [the Forum](http://getgrav.org/forum) or [the Chat](https://chat.getgrav.org/)
|
||||
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.
|
||||
|
||||
95
README.md
95
README.md
@@ -1,21 +1,22 @@
|
||||
#  Grav
|
||||
|
||||
[](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad)
|
||||
[](https://chat.getgrav.org)
|
||||
[](https://chat.getgrav.org) [](https://travis-ci.org/getgrav/grav) [](#backers) [](#sponsors)
|
||||
[](https://github.com/phpstan/phpstan)
|
||||
[](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad)
|
||||
[](https://chat.getgrav.org)
|
||||
[](https://travis-ci.org/getgrav/grav) [](#backers) [](#sponsors)
|
||||
|
||||
Grav is a **Fast**, **Simple**, and **Flexible**, file-based Web-platform. There is **Zero** installation required. Just extract the ZIP archive, and you are already up and running. It follows similar principles to other flat-file CMS platforms, but has a different design philosophy than most. Grav comes with a powerful **Package Management System** to allow for simple installation and upgrading of plugins and themes, as well as simple updating of Grav itself.
|
||||
|
||||
The underlying architecture of Grav is designed to use well-established and _best-in-class_ technologies to ensure that Grav is simple to use and easy to extend. Some of these key technologies include:
|
||||
|
||||
* [Twig Templating](http://twig.sensiolabs.org/): for powerful control of the user interface
|
||||
* [Markdown](http://en.wikipedia.org/wiki/Markdown): for easy content creation
|
||||
* [YAML](http://yaml.org): for simple configuration
|
||||
* [Parsedown](http://parsedown.org/): for fast Markdown and Markdown Extra support
|
||||
* [Doctrine Cache](http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/caching.html): layer for performance
|
||||
* [Pimple Dependency Injection Container](http://pimple.sensiolabs.org/): for extensibility and maintainability
|
||||
* [Symfony Event Dispatcher](http://symfony.com/doc/current/components/event_dispatcher/introduction.html): for plugin event handling
|
||||
* [Symfony Console](http://symfony.com/doc/current/components/console/introduction.html): for CLI interface
|
||||
* [Twig Templating](https://twig.sensiolabs.org/): for powerful control of the user interface
|
||||
* [Markdown](https://en.wikipedia.org/wiki/Markdown): for easy content creation
|
||||
* [YAML](https://yaml.org): for simple configuration
|
||||
* [Parsedown](https://parsedown.org/): for fast Markdown and Markdown Extra support
|
||||
* [Doctrine Cache](https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/caching.html): layer for performance
|
||||
* [Pimple Dependency Injection Container](https://pimple.sensiolabs.org/): for extensibility and maintainability
|
||||
* [Symfony Event Dispatcher](https://symfony.com/doc/current/components/event_dispatcher/introduction.html): for plugin event handling
|
||||
* [Symfony Console](https://symfony.com/doc/current/components/console/introduction.html): for CLI interface
|
||||
* [Gregwar Image Library](https://github.com/Gregwar/Image): for dynamic image manipulation
|
||||
|
||||
# Requirements
|
||||
@@ -96,7 +97,7 @@ If you discover a possible security issue related to Grav or one of its plugins,
|
||||
* [Install](https://learn.getgrav.org/basics/installation) Grav in few seconds
|
||||
* Understand the [Configuration](https://learn.getgrav.org/basics/grav-configuration)
|
||||
* Take a peek at our available free [Skeletons](https://getgrav.org/downloads/skeletons)
|
||||
* If you have questions, jump on our [Slack Room](https://getgrav.org/slack)!
|
||||
* If you have questions, jump on our [Discord Chat Server](https://chat.getgrav.org)!
|
||||
* Have fun!
|
||||
|
||||
# Exploring More
|
||||
@@ -105,75 +106,17 @@ If you discover a possible security issue related to Grav or one of its plugins,
|
||||
* Dive into more [advanced](https://learn.getgrav.org/advanced) functions
|
||||
* Learn about the [Grav CLI](https://learn.getgrav.org/cli-console/grav-cli)
|
||||
* Review examples in the [Grav Cookbook](https://learn.getgrav.org/cookbook)
|
||||
* More [Awesome Grav Stuff](https://github.com/getgrav/awesome-grav)
|
||||
|
||||
# Backers
|
||||
Support Grav with a monthly donation to help us continue development. [[Become a backer](https://opencollective.com/grav#backer)]
|
||||
|
||||
<a href="https://opencollective.com/grav/backer/0/website" target="_blank"><img src="https://opencollective.com/grav/backer/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/1/website" target="_blank"><img src="https://opencollective.com/grav/backer/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/2/website" target="_blank"><img src="https://opencollective.com/grav/backer/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/3/website" target="_blank"><img src="https://opencollective.com/grav/backer/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/4/website" target="_blank"><img src="https://opencollective.com/grav/backer/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/5/website" target="_blank"><img src="https://opencollective.com/grav/backer/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/6/website" target="_blank"><img src="https://opencollective.com/grav/backer/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/7/website" target="_blank"><img src="https://opencollective.com/grav/backer/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/8/website" target="_blank"><img src="https://opencollective.com/grav/backer/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/9/website" target="_blank"><img src="https://opencollective.com/grav/backer/9/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/10/website" target="_blank"><img src="https://opencollective.com/grav/backer/10/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/11/website" target="_blank"><img src="https://opencollective.com/grav/backer/11/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/12/website" target="_blank"><img src="https://opencollective.com/grav/backer/12/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/13/website" target="_blank"><img src="https://opencollective.com/grav/backer/13/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/14/website" target="_blank"><img src="https://opencollective.com/grav/backer/14/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/15/website" target="_blank"><img src="https://opencollective.com/grav/backer/15/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/16/website" target="_blank"><img src="https://opencollective.com/grav/backer/16/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/17/website" target="_blank"><img src="https://opencollective.com/grav/backer/17/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/18/website" target="_blank"><img src="https://opencollective.com/grav/backer/18/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/19/website" target="_blank"><img src="https://opencollective.com/grav/backer/19/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/20/website" target="_blank"><img src="https://opencollective.com/grav/backer/20/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/21/website" target="_blank"><img src="https://opencollective.com/grav/backer/21/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/22/website" target="_blank"><img src="https://opencollective.com/grav/backer/22/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/23/website" target="_blank"><img src="https://opencollective.com/grav/backer/23/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/24/website" target="_blank"><img src="https://opencollective.com/grav/backer/24/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/25/website" target="_blank"><img src="https://opencollective.com/grav/backer/25/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/26/website" target="_blank"><img src="https://opencollective.com/grav/backer/26/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/27/website" target="_blank"><img src="https://opencollective.com/grav/backer/27/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/28/website" target="_blank"><img src="https://opencollective.com/grav/backer/28/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/backer/29/website" target="_blank"><img src="https://opencollective.com/grav/backer/29/avatar.svg"></a>
|
||||
|
||||
<img src="https://opencollective.com/grav/tiers/backers.svg?avatarHeight=36&width=600" />
|
||||
|
||||
# Sponsors
|
||||
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/grav#sponsor)]
|
||||
|
||||
<a href="https://opencollective.com/grav/sponsor/0/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/1/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/2/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/3/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/4/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/5/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/6/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/7/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/8/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/9/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/9/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/10/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/10/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/11/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/11/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/12/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/12/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/13/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/13/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/14/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/14/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/15/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/15/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/16/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/16/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/17/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/17/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/18/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/18/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/19/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/19/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/20/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/20/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/21/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/21/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/22/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/22/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/23/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/23/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/24/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/24/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/25/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/25/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/26/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/26/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/27/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/27/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/28/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/28/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/grav/sponsor/29/website" target="_blank"><img src="https://opencollective.com/grav/sponsor/29/avatar.svg"></a>
|
||||
<img src="https://opencollective.com/grav/tiers/sponsors.svg?avatarHeight=36&width=600" />
|
||||
|
||||
# License
|
||||
|
||||
@@ -185,7 +128,7 @@ See [LICENSE](LICENSE.txt)
|
||||
|
||||
# Running Tests
|
||||
|
||||
First install the dev dependencies by running `composer update` from the Grav root.
|
||||
Then `composer test` will run the Unit Tests, which should be always executed successfully on any site.
|
||||
Windows users should use the `composer test-windows` command.
|
||||
First install the dev dependencies by running `composer update` from the Grav root.
|
||||
Then `composer test` will run the Unit Tests, which should be always executed successfully on any site.
|
||||
Windows users should use the `composer test-windows` command.
|
||||
You can also run a single unit test file, e.g. `composer test tests/unit/Grav/Common/AssetsTest.php`
|
||||
|
||||
Binary file not shown.
30
bin/gpm
30
bin/gpm
@@ -1,26 +1,23 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
use Grav\Common\Composer;
|
||||
use Symfony\Component\Console\Application;
|
||||
use Grav\Common\Grav;
|
||||
|
||||
\define('GRAV_CLI', true);
|
||||
\define('GRAV_REQUEST_TIME', microtime(true));
|
||||
|
||||
if (!file_exists(__DIR__ . '/../vendor')){
|
||||
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
|
||||
}
|
||||
|
||||
use Grav\Common\Composer;
|
||||
use Grav\Common\Config\Setup;
|
||||
|
||||
if (!file_exists(__DIR__ . '/../vendor')){
|
||||
if (!file_exists(__DIR__ . '/../vendor/autoload.php')){
|
||||
// Before we can even start, we need to run composer first
|
||||
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
|
||||
|
||||
$composer = Composer::getComposerExecutor();
|
||||
echo "Preparing to install vendor dependencies...\n\n";
|
||||
echo system($composer.' --working-dir="'.__DIR__.'/../" --no-interaction --no-dev --prefer-dist -o install');
|
||||
echo "\n\n";
|
||||
}
|
||||
|
||||
use Symfony\Component\Console\Application;
|
||||
use Grav\Common\Grav;
|
||||
|
||||
$autoload = require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) {
|
||||
@@ -31,7 +28,7 @@ if (!ini_get('date.timezone')) {
|
||||
date_default_timezone_set('UTC');
|
||||
}
|
||||
|
||||
if (!file_exists(ROOT_DIR . 'index.php')) {
|
||||
if (!file_exists(GRAV_ROOT . '/index.php')) {
|
||||
exit('FATAL: Must be run from ROOT directory of Grav!');
|
||||
}
|
||||
|
||||
@@ -49,15 +46,16 @@ $climate->arguments->add([
|
||||
]
|
||||
]);
|
||||
$climate->arguments->parse();
|
||||
$environment = $climate->arguments->get('environment');
|
||||
|
||||
// Set up environment based on params.
|
||||
Setup::$environment = $environment;
|
||||
$environment = $climate->arguments->get('environment');
|
||||
|
||||
$grav = Grav::instance(array('loader' => $autoload));
|
||||
$grav['uri']->init();
|
||||
$grav->setup($environment);
|
||||
|
||||
$grav['config']->init();
|
||||
$grav['streams'];
|
||||
$grav['uri']->init();
|
||||
$grav['users'];
|
||||
|
||||
$app = new Application('Grav Package Manager', GRAV_VERSION);
|
||||
$app->addCommands(array(
|
||||
|
||||
42
bin/grav
42
bin/grav
@@ -1,18 +1,18 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
use Grav\Common\Composer;
|
||||
use Grav\Common\Grav;
|
||||
use League\CLImate\CLImate;
|
||||
use Symfony\Component\Console\Application;
|
||||
|
||||
\define('GRAV_CLI', true);
|
||||
\define('GRAV_REQUEST_TIME', microtime(true));
|
||||
|
||||
if (!file_exists(__DIR__ . '/../vendor')){
|
||||
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
|
||||
}
|
||||
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Composer;
|
||||
use Symfony\Component\Console\Application;
|
||||
|
||||
if (!file_exists(__DIR__ . '/../vendor')){
|
||||
if (!file_exists(__DIR__ . '/../vendor/autoload.php')){
|
||||
// Before we can even start, we need to run composer first
|
||||
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
|
||||
|
||||
$composer = Composer::getComposerExecutor();
|
||||
echo "Preparing to install vendor dependencies...\n\n";
|
||||
echo system($composer.' --working-dir="'.__DIR__.'/../" --no-interaction --no-dev --prefer-dist -o install');
|
||||
@@ -20,17 +20,33 @@ if (!file_exists(__DIR__ . '/../vendor')){
|
||||
}
|
||||
|
||||
$autoload = require __DIR__ . '/../vendor/autoload.php';
|
||||
Grav::instance(array('loader' => $autoload));
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
$climate = new League\CLImate\CLImate;
|
||||
$climate->arguments->add([
|
||||
'environment' => [
|
||||
'prefix' => 'e',
|
||||
'longPrefix' => 'env',
|
||||
'description' => 'Configuration Environment',
|
||||
'defaultValue' => 'localhost'
|
||||
]
|
||||
]);
|
||||
$climate->arguments->parse();
|
||||
|
||||
// Set up environment based on params.
|
||||
$environment = $climate->arguments->get('environment');
|
||||
|
||||
$grav = Grav::instance(array('loader' => $autoload));
|
||||
$grav->setup($environment);
|
||||
|
||||
if (!ini_get('date.timezone')) {
|
||||
date_default_timezone_set('UTC');
|
||||
}
|
||||
|
||||
if (!file_exists(ROOT_DIR . 'index.php')) {
|
||||
if (!file_exists(GRAV_ROOT . '/index.php')) {
|
||||
exit('FATAL: Must be run from ROOT directory of Grav!');
|
||||
}
|
||||
|
||||
@@ -40,10 +56,12 @@ $app->addCommands(array(
|
||||
new \Grav\Console\Cli\ComposerCommand(),
|
||||
new \Grav\Console\Cli\SandboxCommand(),
|
||||
new \Grav\Console\Cli\CleanCommand(),
|
||||
new \Grav\Console\Cli\CacheCommand(),
|
||||
new \Grav\Console\Cli\ClearCacheCommand(),
|
||||
new \Grav\Console\Cli\BackupCommand(),
|
||||
new \Grav\Console\Cli\NewProjectCommand(),
|
||||
new \Grav\Console\Cli\SchedulerCommand(),
|
||||
new \Grav\Console\Cli\SecurityCommand(),
|
||||
new \Grav\Console\Cli\LogViewerCommand(),
|
||||
new \Grav\Console\Cli\YamlLinterCommand(),
|
||||
));
|
||||
$app->run();
|
||||
|
||||
61
bin/plugin
61
bin/plugin
@@ -1,30 +1,27 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
\define('GRAV_CLI', true);
|
||||
\define('GRAV_REQUEST_TIME', microtime(true));
|
||||
|
||||
if (!file_exists(__DIR__ . '/../vendor')) {
|
||||
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
|
||||
}
|
||||
|
||||
use Grav\Common\Composer;
|
||||
|
||||
if (!file_exists(__DIR__ . '/../vendor')) {
|
||||
// Before we can even start, we need to run composer first
|
||||
$composer = Composer::getComposerExecutor();
|
||||
echo "Preparing to install vendor dependencies...\n\n";
|
||||
echo system($composer . ' --working-dir="' . __DIR__ . '/../" --no-interaction --no-dev --prefer-dist -o install');
|
||||
echo "\n\n";
|
||||
}
|
||||
|
||||
use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
use Symfony\Component\Console\Output\ConsoleOutput;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Config\Setup;
|
||||
use Grav\Common\Filesystem\Folder;
|
||||
|
||||
\define('GRAV_CLI', true);
|
||||
\define('GRAV_REQUEST_TIME', microtime(true));
|
||||
|
||||
if (!file_exists(__DIR__ . '/../vendor/autoload.php')){
|
||||
// Before we can even start, we need to run composer first
|
||||
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
|
||||
|
||||
$composer = Composer::getComposerExecutor();
|
||||
echo "Preparing to install vendor dependencies...\n\n";
|
||||
echo system($composer.' --working-dir="'.__DIR__.'/../" --no-interaction --no-dev --prefer-dist -o install');
|
||||
echo "\n\n";
|
||||
}
|
||||
|
||||
$autoload = require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) {
|
||||
@@ -35,7 +32,7 @@ if (!ini_get('date.timezone')) {
|
||||
date_default_timezone_set('UTC');
|
||||
}
|
||||
|
||||
if (!file_exists(ROOT_DIR . 'index.php')) {
|
||||
if (!file_exists(GRAV_ROOT . '/index.php')) {
|
||||
exit('FATAL: Must be run from ROOT directory of Grav!');
|
||||
}
|
||||
|
||||
@@ -49,19 +46,18 @@ $climate->arguments->add([
|
||||
]
|
||||
]);
|
||||
$climate->arguments->parse();
|
||||
|
||||
$environment = $climate->arguments->get('environment');
|
||||
|
||||
// Set up environment based on params.
|
||||
Setup::$environment = $environment;
|
||||
|
||||
$grav = Grav::instance(array('loader' => $autoload));
|
||||
$grav['uri']->init();
|
||||
$grav->setup($environment);
|
||||
|
||||
$grav['config']->init();
|
||||
$grav['streams'];
|
||||
$grav['uri']->init();
|
||||
$grav['users'];
|
||||
$grav['plugins']->init();
|
||||
$grav['themes']->init();
|
||||
|
||||
|
||||
$app = new Application('Grav Plugins Commands', GRAV_VERSION);
|
||||
$pattern = '([A-Z]\w+Command\.php)';
|
||||
|
||||
@@ -76,6 +72,7 @@ $argv = array_merge([$bin], $argv);
|
||||
|
||||
$input = new ArgvInput($argv);
|
||||
|
||||
/** @var \Grav\Common\Data\Data $plugin */
|
||||
$plugin = $grav['plugins']->get($name);
|
||||
|
||||
$output = new ConsoleOutput();
|
||||
@@ -101,18 +98,30 @@ if (!$name) {
|
||||
$entry = array_shift($split);
|
||||
$index = str_pad($index++ + 1, 2, '0', STR_PAD_LEFT);
|
||||
$total = str_pad($total++ + 1, 2, '0', STR_PAD_LEFT);
|
||||
if (in_array($entry, $available)) {
|
||||
$total -= 1;
|
||||
if (\in_array($entry, $available, true)) {
|
||||
$total--;
|
||||
continue;
|
||||
}
|
||||
|
||||
$available[] = $entry;
|
||||
$commands_count = $index - $total + 1;
|
||||
$output->writeln(' ' . $total . '. <red>' . str_pad($entry, 15) . "</red> <white>${bla} ${bin} ${entry} list</white>");
|
||||
$output->writeln(' ' . $total . '. <red>' . str_pad($entry, 15) . "</red> <white>{$bin} {$entry} list</white>");
|
||||
}
|
||||
}
|
||||
|
||||
exit;
|
||||
} else {
|
||||
if (is_null($plugin)) {
|
||||
$output->writeln('');
|
||||
$output->writeln("<red>$name plugin not found</red>");
|
||||
die;
|
||||
}
|
||||
|
||||
if (!$plugin->enabled) {
|
||||
$output->writeln('');
|
||||
$output->writeln("<red>$name not enabled</red>");
|
||||
die;
|
||||
}
|
||||
}
|
||||
|
||||
if ($plugin === null) {
|
||||
|
||||
@@ -2,8 +2,14 @@
|
||||
"name": "getgrav/grav",
|
||||
"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",
|
||||
"keywords": [
|
||||
"cms",
|
||||
"flat-file cms",
|
||||
"flat cms",
|
||||
"flatfile cms",
|
||||
"php"
|
||||
],
|
||||
"homepage": "https://getgrav.org",
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": ">=7.1.3",
|
||||
@@ -12,50 +18,57 @@
|
||||
"ext-openssl": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-zip": "*",
|
||||
"ext-dom": "*",
|
||||
"symfony/polyfill-iconv": "^1.9",
|
||||
"symfony/polyfill-php72": "^1.9",
|
||||
"symfony/polyfill-php73": "^1.9",
|
||||
|
||||
"psr/simple-cache": "^1.0",
|
||||
"psr/http-message": "^1.0",
|
||||
"psr/http-server-middleware": "^1.0",
|
||||
|
||||
"nyholm/psr7-server": "^0.2.1",
|
||||
"kodus/psr7-server": "*",
|
||||
"nyholm/psr7": "^1.0",
|
||||
|
||||
"twig/twig": "~1.35",
|
||||
"twig/twig": "~1.40",
|
||||
"erusev/parsedown": "1.6.4",
|
||||
"erusev/parsedown-extra": "~0.7",
|
||||
"symfony/yaml": "~4.1",
|
||||
"symfony/console": "~4.1",
|
||||
"symfony/event-dispatcher": "~4.1",
|
||||
"symfony/var-dumper": "~4.1",
|
||||
"symfony/process": "~4.1",
|
||||
"symfony/yaml": "~4.2.0",
|
||||
"symfony/console": "~4.2.0",
|
||||
"symfony/event-dispatcher": "~4.2.0",
|
||||
"symfony/var-dumper": "~4.2.0",
|
||||
"symfony/process": "~4.2.0",
|
||||
"doctrine/cache": "^1.8",
|
||||
"doctrine/collections": "^1.5",
|
||||
"guzzlehttp/psr7": "^1.4",
|
||||
"filp/whoops": "~2.2",
|
||||
|
||||
"matthiasmullie/minify": "^1.3",
|
||||
"monolog/monolog": "~1.0",
|
||||
"gregwar/image": "2.*",
|
||||
"donatj/phpuseragentparser": "~0.10",
|
||||
"pimple/pimple": "~3.2",
|
||||
"rockettheme/toolbox": "~1.4",
|
||||
"rockettheme/toolbox": "~1.4.0",
|
||||
"maximebf/debugbar": "~1.15",
|
||||
"league/climate": "^3.4",
|
||||
"antoligy/dom-string-iterators": "^1.0",
|
||||
"miljar/php-exif": "^0.6.4",
|
||||
"composer/ca-bundle": "^1.0",
|
||||
"dragonmantank/cron-expression": "^1.2",
|
||||
"phive/twig-extensions-deferred": "^1.0"
|
||||
"phive/twig-extensions-deferred": "^1.0",
|
||||
"willdurand/negotiation": "^2.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"codeception/codeception": "^2.4",
|
||||
"phpstan/phpstan": "^0.11",
|
||||
"phpstan/phpstan-deprecation-rules": "^0.11.0",
|
||||
"phpunit/php-code-coverage": "~6.0",
|
||||
"fzaninotto/faker": "^1.8",
|
||||
"victorjonsson/markdowndocs": "dev-master"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-zend-opcache": "Recommended for better performance",
|
||||
"ext-intl": "Recommended for multi-language sites",
|
||||
"ext-memcache": "Needed to support Memcache servers",
|
||||
"ext-memcached": "Needed to support Memcached servers",
|
||||
"ext-redis": "Needed to support Redis servers"
|
||||
},
|
||||
"config": {
|
||||
"apcu-autoloader": true,
|
||||
"platform": {
|
||||
@@ -72,13 +85,22 @@
|
||||
"psr-4": {
|
||||
"Grav\\": "system/src/Grav"
|
||||
},
|
||||
"files": ["system/defines.php"]
|
||||
"files": [
|
||||
"system/defines.php"
|
||||
]
|
||||
},
|
||||
"archive": {
|
||||
"exclude": ["VERSION"]
|
||||
"exclude": [
|
||||
"VERSION"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"api-16": "vendor/bin/phpdoc-md generate system/src > user/pages/14.api/default.16.md",
|
||||
"api-15": "vendor/bin/phpdoc-md generate system/src > user/pages/14.api/default.md",
|
||||
"post-create-project-cmd": "bin/grav install",
|
||||
"phpstan": "vendor/bin/phpstan analyse -l 2 -c ./tests/phpstan/phpstan.neon system/src --memory-limit=256M",
|
||||
"phpstan-framework": "vendor/bin/phpstan analyse -l 5 -c ./tests/phpstan/phpstan.neon system/src/Grav/Framework --memory-limit=256M",
|
||||
"phpstan-plugins": "vendor/bin/phpstan analyse -l 0 -c ./tests/phpstan/plugins.neon user/plugins --memory-limit=256M",
|
||||
"test": "vendor/bin/codecept run unit",
|
||||
"test-windows": "vendor\\bin\\codecept run unit"
|
||||
},
|
||||
|
||||
2146
composer.lock
generated
2146
composer.lock
generated
File diff suppressed because it is too large
Load Diff
4
now.json
Normal file
4
now.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [{ "src": "*.php", "use": "@now/php" }]
|
||||
}
|
||||
@@ -10,3 +10,4 @@ Disallow: /user/
|
||||
Allow: /user/pages/
|
||||
Allow: /user/themes/
|
||||
Allow: /user/images/
|
||||
Allow: /
|
||||
|
||||
@@ -30,9 +30,25 @@ div.phpdebugbar {
|
||||
}
|
||||
|
||||
.phpdebugbar .phpdebugbar-widgets-toolbar {
|
||||
border-top: 1px solid #ddd;
|
||||
padding-left: 5px;
|
||||
padding-right: 2px;
|
||||
padding-top: 2px;
|
||||
background-color: #fafafa !important;
|
||||
width: auto !important;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.phpdebugbar .phpdebugbar-widgets-toolbar input {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.phpdebugbar .phpdebugbar-widgets-toolbar .phpdebugbar-widgets-filter {
|
||||
|
||||
}
|
||||
|
||||
|
||||
.phpdebugbar input[type=text] {
|
||||
padding: 0;
|
||||
display: inline;
|
||||
|
||||
@@ -19,22 +19,22 @@ form:
|
||||
|
||||
purge.trigger:
|
||||
type: select
|
||||
label: Backup Storage Purge Trigger
|
||||
label: PLUGIN_ADMIN.BACKUPS_STORAGE_PURGE_TRIGGER
|
||||
size: medium
|
||||
default: space
|
||||
options:
|
||||
space: Maximum Backup Space
|
||||
number: Maximum Number of Backups
|
||||
time: maximum Rention Time
|
||||
time: maximum Retention Time
|
||||
validate:
|
||||
required: true
|
||||
|
||||
purge.max_backups_count:
|
||||
type: number
|
||||
label: Maximum Number of Backups
|
||||
label: PLUGIN_ADMIN.BACKUPS_MAX_COUNT
|
||||
default: 25
|
||||
size: x-small
|
||||
help: "0 is unlimited"
|
||||
help: PLUGIN_ADMIN.BACKUPS_MAX_COUNT
|
||||
validate:
|
||||
min: 0
|
||||
type: number
|
||||
@@ -43,7 +43,7 @@ form:
|
||||
|
||||
purge.max_backups_space:
|
||||
type: number
|
||||
label: Maximum Backups Space
|
||||
label: PLUGIN_ADMIN.BACKUPS_MAX_SPACE
|
||||
append: in GB
|
||||
size: x-small
|
||||
default: 5
|
||||
@@ -55,8 +55,8 @@ form:
|
||||
|
||||
purge.max_backups_time:
|
||||
type: number
|
||||
label: Maximum Rention Time
|
||||
append: in Days
|
||||
label: PLUGIN_ADMIN.BACKUPS_MAX_RETENTION_TIME
|
||||
append: PLUGIN_ADMIN.BACKUPS_MAX_RETENTION_TIME_APPEND
|
||||
size: x-small
|
||||
default: 365
|
||||
validate:
|
||||
@@ -80,35 +80,35 @@ form:
|
||||
fields:
|
||||
.name:
|
||||
type: text
|
||||
label: Name
|
||||
placeholder: 'Clear Backup Name'
|
||||
label: PLUGIN_ADMIN.NAME
|
||||
placeholder: PLUGIN_ADMIN.BACKUPS_PROFILE_NAME
|
||||
validate:
|
||||
max: 20
|
||||
message: 'Name must be less than 20 characters'
|
||||
required: true
|
||||
.root:
|
||||
type: text
|
||||
label: Root Folder
|
||||
help: Can be an absolute path or a stream
|
||||
label: PLUGIN_ADMIN.BACKUPS_PROFILE_ROOT_FOLDER
|
||||
help: PLUGIN_ADMIN.BACKUPS_PROFILE_ROOT_FOLDER_HELP
|
||||
placeholder: '/'
|
||||
default: '/'
|
||||
validate:
|
||||
required: true
|
||||
.exclude_paths:
|
||||
type: textarea
|
||||
label: Exclude Paths
|
||||
label: PLUGIN_ADMIN.BACKUPS_PROFILE_EXCLUDE_PATHS
|
||||
rows: 5
|
||||
placeholder: "/backup\r/cache\r/images\r/logs\r/tmp"
|
||||
help: Absolute paths to exclude, one per line
|
||||
help: PLUGIN_ADMIN.BACKUPS_PROFILE_EXCLUDE_PATHS_HELP
|
||||
.exclude_files:
|
||||
type: textarea
|
||||
label: Exclude Files
|
||||
label: PLUGIN_ADMIN.BACKUPS_PROFILE_EXCLUDE_FILES
|
||||
rows: 5
|
||||
placeholder: ".DS_Store\r.git\r.svn\r.hg\r.idea\r.vscode\rnode_modules"
|
||||
help: Specfic Files or Folders to exclude, one per line
|
||||
help: PLUGIN_ADMIN.BACKUPS_PROFILE_EXCLUDE_FILES_HELP
|
||||
.schedule:
|
||||
type: toggle
|
||||
label: Enable Scheduled Job
|
||||
label: PLUGIN_ADMIN.BACKUPS_PROFILE_SCHEDULE
|
||||
highlight: 1
|
||||
default: 1
|
||||
options:
|
||||
@@ -118,7 +118,7 @@ form:
|
||||
type: bool
|
||||
.schedule_at:
|
||||
type: cron
|
||||
label: Run Scheduled Job
|
||||
label: PLUGIN_ADMIN.BACKUPS_PROFILE_SCHEDULE_AT
|
||||
default: '* 3 * * *'
|
||||
validate:
|
||||
required: true
|
||||
|
||||
@@ -38,37 +38,37 @@ form:
|
||||
message: 'ID must be lowercase with dashes/underscores only and less than 20 characters'
|
||||
.command:
|
||||
type: text
|
||||
label: Command
|
||||
label: PLUGIN_ADMIN.COMMAND
|
||||
placeholder: 'cd ~;ls -lah;'
|
||||
validate:
|
||||
required: true
|
||||
.args:
|
||||
type: text
|
||||
label: Extra Arguments
|
||||
label: PLUGIN_ADMIN.EXTRA_ARGUMENTS
|
||||
.at:
|
||||
type: cron
|
||||
label: Run At
|
||||
help: 'Cron formatted "at" syntax'
|
||||
label: PLUGIN_ADMIN.SCHEDULER_RUNAT
|
||||
help: PLUGIN_ADMIN.SCHEDULER_RUNAT_HELP
|
||||
placeholder: '* * * * *'
|
||||
validate:
|
||||
required: true
|
||||
.output:
|
||||
type: text
|
||||
label: Output File
|
||||
help: 'The path/filename of the output file (from the root of the Grav installation)'
|
||||
label: PLUGIN_ADMIN.SCHEDULER_OUTPUT
|
||||
help: PLUGIN_ADMIN.SCHEDULER_OUTPUT_HELP
|
||||
placeholder: 'logs/ls-cron.out'
|
||||
.output_mode:
|
||||
type: select
|
||||
label: Output Type
|
||||
help: 'Either append to the same file each run, or overwrite the file with each run'
|
||||
label: PLUGIN_ADMIN.SCHEDULER_OUTPUT_TYPE
|
||||
help: PLUGIN_ADMIN.SCHEDULER_OUTPUT_TYPE_HELP
|
||||
default: append
|
||||
options:
|
||||
append: Append
|
||||
overwrite: Overwrite
|
||||
.email:
|
||||
type: text
|
||||
label: Email
|
||||
help: 'Email to send output to. NOTE: requires output file to be set'
|
||||
label: PLUGIN_ADMIN.SCHEDULER_EMAIL
|
||||
help: PLUGIN_ADMIN.SCHEDULER_EMAIL_HELP
|
||||
placeholder: 'notifications@yoursite.com'
|
||||
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ form:
|
||||
|
||||
summary.size:
|
||||
type: text
|
||||
size: x-small
|
||||
size: small
|
||||
append: PLUGIN_ADMIN.CHARACTERS
|
||||
label: PLUGIN_ADMIN.SUMMARY_SIZE
|
||||
help: PLUGIN_ADMIN.SUMMARY_SIZE_HELP
|
||||
|
||||
@@ -41,7 +41,6 @@ form:
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
|
||||
pages.theme:
|
||||
type: themeselect
|
||||
classes: fancy
|
||||
@@ -60,6 +59,14 @@ form:
|
||||
twig: Twig
|
||||
use: keys
|
||||
|
||||
pages.types:
|
||||
type: array
|
||||
label: PLUGIN_ADMIN.PAGE_TYPES
|
||||
help: PLUGIN_ADMIN.PAGE_TYPES_HELP
|
||||
size: small
|
||||
default: ['html','htm','json','xml','txt','rss','atom']
|
||||
value_only: true
|
||||
|
||||
timezone:
|
||||
type: select
|
||||
label: PLUGIN_ADMIN.TIMEZONE
|
||||
@@ -316,6 +323,12 @@ form:
|
||||
validate:
|
||||
type: commalist
|
||||
|
||||
languages.default_lang:
|
||||
type: text
|
||||
size: x-small
|
||||
label: PLUGIN_ADMIN.DEFAULT_LANG
|
||||
help: PLUGIN_ADMIN.DEFAULT_LANG_HELP
|
||||
|
||||
languages.include_default_lang:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.INCLUDE_DEFAULT_LANG
|
||||
@@ -406,7 +419,7 @@ form:
|
||||
pages.expires:
|
||||
type: text
|
||||
size: small
|
||||
append: NICETIME.SECOND_PLURAL
|
||||
append: GRAV.NICETIME.SECOND_PLURAL
|
||||
label: PLUGIN_ADMIN.EXPIRES
|
||||
help: PLUGIN_ADMIN.EXPIRES_HELP
|
||||
validate:
|
||||
@@ -561,8 +574,23 @@ form:
|
||||
type: cron
|
||||
label: PLUGIN_ADMIN.CACHE_PURGE_JOB
|
||||
help: PLUGIN_ADMIN.CACHE_PURGE_JOB_HELP
|
||||
default: '* 4 * * *'
|
||||
|
||||
cache.clear_at:
|
||||
type: cron
|
||||
label: PLUGIN_ADMIN.CACHE_CLEAR_JOB
|
||||
help: PLUGIN_ADMIN.CACHE_CLEAR_JOB_HELP
|
||||
default: '* 3 * * *'
|
||||
|
||||
cache.clear_job_type:
|
||||
type: select
|
||||
size: medium
|
||||
label: PLUGIN_ADMIN.CACHE_JOB_TYPE
|
||||
help: PLUGIN_ADMIN.CACHE_JOB_TYPE_HELP
|
||||
options:
|
||||
standard: Standard Cache Folders
|
||||
all: All Cache Folders
|
||||
|
||||
cache.clear_images_by_default:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.CLEAR_IMAGES_BY_DEFAULT
|
||||
@@ -588,7 +616,7 @@ form:
|
||||
cache.lifetime:
|
||||
type: text
|
||||
size: small
|
||||
append: NICETIME.SECOND_PLURAL
|
||||
append: GRAV.NICETIME.SECOND_PLURAL
|
||||
label: PLUGIN_ADMIN.LIFETIME
|
||||
help: PLUGIN_ADMIN.LIFETIME_HELP
|
||||
validate:
|
||||
@@ -1040,6 +1068,17 @@ form:
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
images.seofriendly:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.IMAGES_SEOFRIENDLY
|
||||
help: PLUGIN_ADMIN.IMAGES_SEOFRIENDLY_HELP
|
||||
highlight: 0
|
||||
options:
|
||||
1: PLUGIN_ADMIN.YES
|
||||
0: PLUGIN_ADMIN.NO
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
media.enable_media_timestamp:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.ENABLE_MEDIA_TIMESTAMP
|
||||
@@ -1063,7 +1102,6 @@ form:
|
||||
type: bool
|
||||
|
||||
|
||||
|
||||
media.allowed_fallback_types:
|
||||
type: selectize
|
||||
size: large
|
||||
@@ -1119,7 +1157,7 @@ form:
|
||||
session.timeout:
|
||||
type: text
|
||||
size: small
|
||||
append: NICETIME.SECOND_PLURAL
|
||||
append: GRAV.NICETIME.SECOND_PLURAL
|
||||
label: PLUGIN_ADMIN.TIMEOUT
|
||||
help: PLUGIN_ADMIN.TIMEOUT_HELP
|
||||
validate:
|
||||
@@ -1224,9 +1262,8 @@ form:
|
||||
gpm.official_gpm_only:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.GPM_OFFICIAL_ONLY
|
||||
highlight: auto
|
||||
help: PLUGIN_ADMIN.GPM_OFFICIAL_ONLY_HELP
|
||||
highlight: 1
|
||||
help: PLUGIN_ADMIN.GPM_OFFICIAL_ONLY_HELP
|
||||
options:
|
||||
1: PLUGIN_ADMIN.YES
|
||||
0: PLUGIN_ADMIN.NO
|
||||
@@ -1342,6 +1379,12 @@ form:
|
||||
label: PLUGIN_ADMIN.CUSTOM_BASE_URL
|
||||
help: PLUGIN_ADMIN.CUSTOM_BASE_URL_HELP
|
||||
|
||||
accounts.type:
|
||||
type: hidden
|
||||
|
||||
accounts.storage:
|
||||
type: hidden
|
||||
|
||||
strict_mode.yaml_compat:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.STRICT_YAML_COMPAT
|
||||
|
||||
@@ -4,122 +4,124 @@ form:
|
||||
|
||||
fields:
|
||||
|
||||
info:
|
||||
type: userinfo
|
||||
size: large
|
||||
info:
|
||||
type: userinfo
|
||||
size: large
|
||||
|
||||
avatar:
|
||||
type: file
|
||||
size: large
|
||||
destination: 'user://accounts/avatars'
|
||||
multiple: false
|
||||
random_name: true
|
||||
avatar:
|
||||
type: file
|
||||
size: large
|
||||
destination: 'user://accounts/avatars'
|
||||
multiple: false
|
||||
random_name: true
|
||||
|
||||
content:
|
||||
type: section
|
||||
title: PLUGIN_ADMIN.ACCOUNT
|
||||
underline: true
|
||||
content:
|
||||
type: section
|
||||
title: PLUGIN_ADMIN.ACCOUNT
|
||||
underline: true
|
||||
|
||||
username:
|
||||
type: text
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.USERNAME
|
||||
disabled: true
|
||||
readonly: true
|
||||
username:
|
||||
type: text
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.USERNAME
|
||||
disabled: true
|
||||
readonly: true
|
||||
|
||||
email:
|
||||
type: email
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.EMAIL
|
||||
validate:
|
||||
type: email
|
||||
message: PLUGIN_ADMIN.EMAIL_VALIDATION_MESSAGE
|
||||
required: true
|
||||
email:
|
||||
type: email
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.EMAIL
|
||||
validate:
|
||||
type: email
|
||||
message: PLUGIN_ADMIN.EMAIL_VALIDATION_MESSAGE
|
||||
required: true
|
||||
|
||||
password:
|
||||
type: password
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.PASSWORD
|
||||
autocomplete: new-password
|
||||
validate:
|
||||
required: false
|
||||
message: PLUGIN_ADMIN.PASSWORD_VALIDATION_MESSAGE
|
||||
config-pattern@: system.pwd_regex
|
||||
password:
|
||||
type: password
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.PASSWORD
|
||||
autocomplete: new-password
|
||||
validate:
|
||||
required: false
|
||||
message: PLUGIN_ADMIN.PASSWORD_VALIDATION_MESSAGE
|
||||
config-pattern@: system.pwd_regex
|
||||
|
||||
fullname:
|
||||
type: text
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.FULL_NAME
|
||||
validate:
|
||||
required: true
|
||||
fullname:
|
||||
type: text
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.FULL_NAME
|
||||
validate:
|
||||
required: true
|
||||
|
||||
title:
|
||||
type: text
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.TITLE
|
||||
title:
|
||||
type: text
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.TITLE
|
||||
|
||||
language:
|
||||
type: select
|
||||
label: PLUGIN_ADMIN.LANGUAGE
|
||||
size: medium
|
||||
classes: fancy
|
||||
data-options@: '\Grav\Plugin\Admin\Admin::adminLanguages'
|
||||
default: 'en'
|
||||
help: PLUGIN_ADMIN.LANGUAGE_HELP
|
||||
language:
|
||||
type: select
|
||||
label: PLUGIN_ADMIN.LANGUAGE
|
||||
size: medium
|
||||
classes: fancy
|
||||
data-options@: '\Grav\Plugin\Admin\Admin::adminLanguages'
|
||||
default: 'en'
|
||||
help: PLUGIN_ADMIN.LANGUAGE_HELP
|
||||
|
||||
twofa_check:
|
||||
type: conditional
|
||||
condition: config.plugins.admin.twofa_enabled
|
||||
twofa_check:
|
||||
type: conditional
|
||||
condition: config.plugins.admin.twofa_enabled
|
||||
|
||||
fields:
|
||||
fields:
|
||||
|
||||
twofa:
|
||||
title: PLUGIN_ADMIN.2FA_TITLE
|
||||
type: section
|
||||
underline: true
|
||||
twofa:
|
||||
title: PLUGIN_ADMIN.2FA_TITLE
|
||||
type: section
|
||||
underline: true
|
||||
|
||||
twofa_enabled:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.2FA_ENABLED
|
||||
classes: twofa-toggle
|
||||
highlight: 1
|
||||
default: 0
|
||||
options:
|
||||
1: PLUGIN_ADMIN.YES
|
||||
0: PLUGIN_ADMIN.NO
|
||||
validate:
|
||||
type: bool
|
||||
twofa_enabled:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.2FA_ENABLED
|
||||
classes: twofa-toggle
|
||||
highlight: 1
|
||||
default: 0
|
||||
options:
|
||||
1: PLUGIN_ADMIN.YES
|
||||
0: PLUGIN_ADMIN.NO
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
|
||||
twofa_secret:
|
||||
type: 2fa_secret
|
||||
outerclasses: 'twofa-secret'
|
||||
markdown: true
|
||||
label: PLUGIN_ADMIN.2FA_SECRET
|
||||
sublabel: PLUGIN_ADMIN.2FA_SECRET_HELP
|
||||
twofa_secret:
|
||||
type: 2fa_secret
|
||||
outerclasses: 'twofa-secret'
|
||||
markdown: true
|
||||
label: PLUGIN_ADMIN.2FA_SECRET
|
||||
sublabel: PLUGIN_ADMIN.2FA_SECRET_HELP
|
||||
|
||||
|
||||
security:
|
||||
title: PLUGIN_ADMIN.ACCESS_LEVELS
|
||||
type: section
|
||||
security: admin.super
|
||||
underline: true
|
||||
security:
|
||||
security@: admin.super
|
||||
title: PLUGIN_ADMIN.ACCESS_LEVELS
|
||||
type: section
|
||||
underline: true
|
||||
|
||||
fields:
|
||||
groups:
|
||||
type: select
|
||||
multiple: true
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.GROUPS
|
||||
data-options@: '\Grav\Common\User\Group::groupNames'
|
||||
classes: fancy
|
||||
help: PLUGIN_ADMIN.GROUPS_HELP
|
||||
validate:
|
||||
type: commalist
|
||||
fields:
|
||||
groups:
|
||||
security@: admin.super
|
||||
type: select
|
||||
multiple: true
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.GROUPS
|
||||
data-options@: '\Grav\Common\User\Group::groupNames'
|
||||
classes: fancy
|
||||
help: PLUGIN_ADMIN.GROUPS_HELP
|
||||
validate:
|
||||
type: commalist
|
||||
|
||||
access:
|
||||
type: permissions
|
||||
label: PLUGIN_ADMIN.PERMISSIONS
|
||||
ignore_empty: true
|
||||
validate:
|
||||
type: array
|
||||
access:
|
||||
security@: admin.super
|
||||
type: permissions
|
||||
label: PLUGIN_ADMIN.PERMISSIONS
|
||||
ignore_empty: true
|
||||
validate:
|
||||
type: array
|
||||
|
||||
@@ -12,5 +12,7 @@ form:
|
||||
type: text
|
||||
label: PLUGIN_ADMIN.USERNAME
|
||||
help: PLUGIN_ADMIN.USERNAME_HELP
|
||||
unset-disabled@: true
|
||||
unset-readonly@: true
|
||||
validate:
|
||||
required: true
|
||||
|
||||
39
system/blueprints/user/accounts.yaml
Normal file
39
system/blueprints/user/accounts.yaml
Normal file
@@ -0,0 +1,39 @@
|
||||
title: User Accounts
|
||||
description: User Accounts
|
||||
type: flex-objects
|
||||
|
||||
extends@: 'user/account'
|
||||
|
||||
config:
|
||||
admin:
|
||||
list:
|
||||
fields:
|
||||
username:
|
||||
link: edit
|
||||
search: true
|
||||
email:
|
||||
search: true
|
||||
fullname:
|
||||
search: true
|
||||
options:
|
||||
per_page: 20
|
||||
order:
|
||||
by: username
|
||||
dir: asc
|
||||
|
||||
menu:
|
||||
list:
|
||||
route: '/accounts'
|
||||
title: Accounts
|
||||
icon: fa-users
|
||||
authorize: ['admin.users', 'admin.accounts', 'admin.super']
|
||||
|
||||
form:
|
||||
fields:
|
||||
username:
|
||||
flex-disabled@: exists
|
||||
disabled: false
|
||||
flex-readonly@: exists
|
||||
readonly: false
|
||||
validate:
|
||||
required: true
|
||||
@@ -17,17 +17,17 @@ 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)
|
||||
|
||||
#menu: # Sample Menu Example
|
||||
#menu: # Menu Example
|
||||
# - text: Source
|
||||
# icon: github
|
||||
# url: https://github.com/getgrav/grav
|
||||
|
||||
@@ -13,6 +13,7 @@ intl_enabled: true # Special logic for PHP Interna
|
||||
|
||||
languages:
|
||||
supported: [] # List of languages supported. eg: [en, fr, de]
|
||||
default_lang: # Default is the first supported language. Must be one of the supported languages
|
||||
include_default_lang: true # Include the default lang prefix in all URLs
|
||||
pages_fallback_only: false # Only fallback to find page content through supported languages
|
||||
translations: true # Enable translations by default
|
||||
@@ -53,7 +54,7 @@ pages:
|
||||
special_chars: # List of special characters to automatically convert to entities
|
||||
'>': 'gt'
|
||||
'<': 'lt'
|
||||
types: [txt,xml,html,htm,json,rss,atom] # list of valid page types
|
||||
types: [html,htm,xml,txt,json,rss,atom] # list of valid page types
|
||||
append_url_extension: '' # Append page's extension in Page urls (e.g. '.html' results in /path/page.html)
|
||||
expires: 604800 # Page expires time in seconds (604800 seconds = 7 days)
|
||||
cache_control: # Can be blank for no setting, or a valid `cache-control` text value
|
||||
@@ -76,9 +77,11 @@ cache:
|
||||
enabled: true # Set to true to enable caching
|
||||
check:
|
||||
method: file # Method to check for updates in pages: file|folder|hash|none
|
||||
driver: auto # One of: auto|file|apc|xcache|memcache|wincache
|
||||
driver: auto # One of: auto|file|apcu|memcache|wincache
|
||||
prefix: 'g' # Cache prefix string (prevents cache conflicts)
|
||||
purge_at: '0 4 * * *' # How often to purge old cache (using new scheduler)
|
||||
purge_at: '0 4 * * *' # How often to purge old file cache (using new scheduler)
|
||||
clear_at: '0 3 * * *' # How often to clear cache (using new scheduler)
|
||||
clear_job_type: 'standard' # Type to clear when processing the scheduled clear job `standard`|`all`
|
||||
clear_images_by_default: true # By default grav will include processed images in cache clear, this can be disabled
|
||||
cli_compatibility: false # Ensures only non-volatile drivers are used (file, redis, memcache, etc.)
|
||||
lifetime: 604800 # Lifetime of cached data in seconds (0 = infinite)
|
||||
@@ -131,6 +134,7 @@ images:
|
||||
cache_perms: '0755' # MUST BE IN QUOTES!! Default cache folder perms. Usually '0755' or '0775'
|
||||
debug: false # Show an overlay over images indicating the pixel depth of the image when working with retina for example
|
||||
auto_fix_orientation: false # Automatically fix the image orientation based on the Exif data
|
||||
seofriendly: false # SEO-friendly processed image names
|
||||
|
||||
media:
|
||||
enable_media_timestamp: false # Enable media timestamps
|
||||
@@ -156,6 +160,10 @@ gpm:
|
||||
verify_peer: true # Sometimes on some systems (Windows most commonly) GPM is unable to connect because the SSL certificate cannot be verified. Disabling this setting might help.
|
||||
official_gpm_only: true # By default GPM direct-install will only allow URLs via the official GPM proxy to ensure security
|
||||
|
||||
accounts:
|
||||
type: data # Account type: data or flex
|
||||
storage: file # Flex storage type: file or folder
|
||||
|
||||
strict_mode:
|
||||
yaml_compat: true # Grav 1.5+: Enables YAML backwards compatibility
|
||||
twig_compat: true # Grav 1.5+: Enables deprecated Twig autoescape setting (autoescape: false)
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Grav.Core
|
||||
* @package Grav\Core
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
// Some standard defines
|
||||
define('GRAV', true);
|
||||
define('GRAV_VERSION', '1.6.0-beta.5');
|
||||
define('GRAV_TESTING', true);
|
||||
define('GRAV_VERSION', '1.6.20');
|
||||
define('GRAV_TESTING', false);
|
||||
define('DS', '/');
|
||||
|
||||
if (!defined('GRAV_PHP_MIN')) {
|
||||
|
||||
17
system/install.php
Normal file
17
system/install.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Grav\Core
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
if (!defined('GRAV_ROOT')) {
|
||||
die();
|
||||
}
|
||||
|
||||
use Grav\Installer\Install;
|
||||
|
||||
require_once __DIR__ . '/src/Grav/Installer/Install.php';
|
||||
|
||||
return Install::instance();
|
||||
@@ -1,19 +1,6 @@
|
||||
---
|
||||
GRAV:
|
||||
FRONTMATTER_ERROR_PAGE: |
|
||||
---
|
||||
العنوان: %1$s
|
||||
---
|
||||
# خطأ: مادة أمامية غير صحيحة
|
||||
|
||||
مسار: '%2$s'
|
||||
|
||||
**%3$s**
|
||||
|
||||
, , ,
|
||||
|
||||
%4$s
|
||||
, , ,
|
||||
FRONTMATTER_ERROR_PAGE: "---\nالعنوان: %1$s\n---\n# خطأ: مادة أمامية غير صحيحة\n\nمسار: '%2$s'\n\n**%3$s**\n\n, , ,\n\n%4$s\n, , ,"
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: لم يتم تقديم التاريخ
|
||||
BAD_DATE: تاريخ خاطئ
|
||||
@@ -35,7 +22,7 @@ GRAV:
|
||||
YR: سنة
|
||||
DEC: عقد
|
||||
SECOND_PLURAL: ثواني
|
||||
MINUTE_PLURAL: دقائق
|
||||
MINUTE_PLURAL: 'دقائق'
|
||||
HOUR_PLURAL: ساعات
|
||||
DAY_PLURAL: أيام
|
||||
WEEK_PLURAL: أسابيع
|
||||
@@ -50,27 +37,27 @@ GRAV:
|
||||
YR_PLURAL: سنوات
|
||||
DEC_PLURAL: عقود
|
||||
FORM:
|
||||
VALIDATION_FAIL: '<b>فشل التحقق من صحة:</b>'
|
||||
VALIDATION_FAIL: <b>فشل التحقق من صحة:</b>
|
||||
INVALID_INPUT: إدخال غير صحيح في
|
||||
MISSING_REQUIRED_FIELD: 'حقل مطلوب مفقود:'
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- كانون الثاني
|
||||
- شباط
|
||||
- آذار/ مارس
|
||||
- نيسان
|
||||
- أيار
|
||||
- حزيران
|
||||
- تموز
|
||||
- آب
|
||||
- أيلول
|
||||
- تشرين الأول
|
||||
- تشرين الثاني
|
||||
- كانون الأول
|
||||
- 'كانون الثاني'
|
||||
- 'شباط'
|
||||
- 'آذار/ مارس'
|
||||
- 'نيسان'
|
||||
- 'أيار'
|
||||
- 'حزيران'
|
||||
- 'تموز'
|
||||
- 'آب'
|
||||
- 'أيلول'
|
||||
- 'تشرين الأول'
|
||||
- 'تشرين الثاني'
|
||||
- 'كانون الأول'
|
||||
DAYS_OF_THE_WEEK:
|
||||
- الاثنين
|
||||
- الثلاثاء
|
||||
- الأربعاء
|
||||
- الخميس
|
||||
- الجمعة
|
||||
- السبت
|
||||
- الأحد
|
||||
- 'الاثنين'
|
||||
- 'الثلاثاء'
|
||||
- 'الأربعاء'
|
||||
- 'الخميس'
|
||||
- 'الجمعة'
|
||||
- 'السبت'
|
||||
- 'الأحد'
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
GRAV:
|
||||
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```"
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Не е въведена дата
|
||||
BAD_DATE: Невалидна дата
|
||||
|
||||
@@ -1,24 +1,11 @@
|
||||
---
|
||||
GRAV:
|
||||
FRONTMATTER_ERROR_PAGE: |
|
||||
---
|
||||
title: %1$s
|
||||
---
|
||||
|
||||
# S'ha produït un error: Frontmatter invàlid
|
||||
|
||||
Ruta: `%2$s`
|
||||
|
||||
**%3$s**
|
||||
|
||||
```
|
||||
%4$s
|
||||
```
|
||||
FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# S'ha produït un error: Frontmatter invàlid\n\nRuta: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: "No s'ha proporcionat data"
|
||||
NO_DATE_PROVIDED: No s'ha proporcionat data
|
||||
BAD_DATE: Data invàlida
|
||||
AGO: abans
|
||||
FROM_NOW: "des d'ara"
|
||||
FROM_NOW: des d'ara
|
||||
SECOND: segon
|
||||
MINUTE: minut
|
||||
HOUR: hora
|
||||
@@ -28,7 +15,6 @@ GRAV:
|
||||
YEAR: any
|
||||
DECADE: dècada
|
||||
SEC: s
|
||||
MIN: min
|
||||
HR: h
|
||||
WK: setm.
|
||||
MO: m.
|
||||
@@ -50,27 +36,27 @@ GRAV:
|
||||
YR_PLURAL: anys
|
||||
DEC_PLURAL: dèc.
|
||||
FORM:
|
||||
VALIDATION_FAIL: '<b>Ha fallat la validació:</b>'
|
||||
VALIDATION_FAIL: <b>Ha fallat la validació:</b>
|
||||
INVALID_INPUT: Entrada no vàlida a
|
||||
MISSING_REQUIRED_FIELD: 'Falta camp obligatori:'
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- Gener
|
||||
- Febrer
|
||||
- Març
|
||||
- Abril
|
||||
- Maig
|
||||
- Juny
|
||||
- Juliol
|
||||
- Agost
|
||||
- Setembre
|
||||
- Octubre
|
||||
- Novembre
|
||||
- Desembre
|
||||
- 'Gener'
|
||||
- 'Febrer'
|
||||
- 'Març'
|
||||
- 'Abril'
|
||||
- 'Maig'
|
||||
- 'Juny'
|
||||
- 'Juliol'
|
||||
- 'Agost'
|
||||
- 'Setembre'
|
||||
- 'Octubre'
|
||||
- 'Novembre'
|
||||
- 'Desembre'
|
||||
DAYS_OF_THE_WEEK:
|
||||
- Dilluns
|
||||
- Dimarts
|
||||
- Dimecres
|
||||
- Dijous
|
||||
- Divendres
|
||||
- Dissabte
|
||||
- Diumenge
|
||||
- 'Dilluns'
|
||||
- 'Dimarts'
|
||||
- 'Dimecres'
|
||||
- 'Dijous'
|
||||
- 'Divendres'
|
||||
- 'Dissabte'
|
||||
- 'Diumenge'
|
||||
|
||||
@@ -1,6 +1,49 @@
|
||||
---
|
||||
GRAV:
|
||||
FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Chyba: Chybný frontmatter\n\nPath: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
|
||||
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'
|
||||
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'
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- 'vybavení'
|
||||
- 'informace'
|
||||
@@ -26,6 +69,7 @@ GRAV:
|
||||
BAD_DATE: Chybné datum
|
||||
AGO: zpět
|
||||
FROM_NOW: od teď
|
||||
JUST_NOW: právě teď
|
||||
SECOND: sekunda
|
||||
MINUTE: minuta
|
||||
HOUR: hodina
|
||||
@@ -81,3 +125,20 @@ GRAV:
|
||||
- 'pátek'
|
||||
- 'sobota'
|
||||
- 'neděle'
|
||||
CRON:
|
||||
EVERY: každý
|
||||
EVERY_HOUR: každou hodinu
|
||||
EVERY_MINUTE: každou minutu
|
||||
EVERY_DAY_OF_WEEK: každý den v týdnu
|
||||
EVERY_DAY_OF_MONTH: každý den v měsíci
|
||||
EVERY_MONTH: každý měsíc
|
||||
TEXT_PERIOD: Every <b />
|
||||
TEXT_MINS: ' at <b /> minute(s) past the hour'
|
||||
TEXT_TIME: ' at <b />:<b />'
|
||||
TEXT_DOW: ' on <b />'
|
||||
TEXT_MONTH: ' of <b />'
|
||||
TEXT_DOM: ' on <b />'
|
||||
ERROR1: Tag %s není podporován!
|
||||
ERROR2: Chybný počet prvků
|
||||
ERROR3: jquery_element musí být nastaven v nastaveních pro jqCron
|
||||
ERROR4: Nerozpoznaný výraz
|
||||
|
||||
@@ -15,7 +15,6 @@ GRAV:
|
||||
YEAR: år
|
||||
DECADE: årti
|
||||
SEC: sek
|
||||
MIN: min
|
||||
HR: t
|
||||
WK: u
|
||||
MO: md
|
||||
@@ -41,23 +40,23 @@ GRAV:
|
||||
INVALID_INPUT: Ugyldigt input i
|
||||
MISSING_REQUIRED_FIELD: 'Mangler obligatorisk felt:'
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- 'Januar'
|
||||
- 'Februar'
|
||||
- 'Marts'
|
||||
- 'April'
|
||||
- 'Maj'
|
||||
- 'Juni'
|
||||
- 'Juli'
|
||||
- 'August'
|
||||
- 'September'
|
||||
- 'Oktober'
|
||||
- 'November'
|
||||
- 'December'
|
||||
- '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'
|
||||
- 'tirsdag'
|
||||
- 'onsdag'
|
||||
- 'torsdag'
|
||||
- 'fredag'
|
||||
- 'lørdag'
|
||||
- 'søndag'
|
||||
|
||||
@@ -1,15 +1,58 @@
|
||||
---
|
||||
GRAV:
|
||||
FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n# Fehler: Frontmatter enthält Fehler\n\nPfad: `%2$s`\n\n**%3$s ** \n\n```\n%4$s\n```"
|
||||
INFLECTOR_PLURALS:
|
||||
'/(quiz)$/i': '\1zes'
|
||||
'/^(ox)$/i': '\1en'
|
||||
'/([m|l])ouse$/i': '\1ice'
|
||||
'/(matr|vert|ind)ix|ex$/i': '\1ice'
|
||||
'/(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': '\1ies'
|
||||
'/(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\2ves'
|
||||
'/([ti])a$/i': '\1um'
|
||||
'/(n)ews$/i': '\1ews'
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- 'equipment'
|
||||
- 'Ausstattung'
|
||||
- 'Informationen'
|
||||
- 'Reis'
|
||||
- 'Geld'
|
||||
- 'species'
|
||||
- 'series'
|
||||
- 'fish'
|
||||
- 'sheep'
|
||||
- 'Arten'
|
||||
- 'Serie'
|
||||
- 'Fisch'
|
||||
- 'Schaf'
|
||||
INFLECTOR_IRREGULAR:
|
||||
'person': 'Personen'
|
||||
'man': 'Menschen'
|
||||
@@ -26,6 +69,7 @@ GRAV:
|
||||
BAD_DATE: Falsches Datum
|
||||
AGO: her
|
||||
FROM_NOW: ab jetzt
|
||||
JUST_NOW: jetzt gerade
|
||||
SECOND: Sekunde
|
||||
MINUTE: Minute
|
||||
HOUR: Stunde
|
||||
@@ -81,3 +125,20 @@ GRAV:
|
||||
- 'Freitag'
|
||||
- 'Samstag'
|
||||
- 'Sonntag'
|
||||
CRON:
|
||||
EVERY: jede
|
||||
EVERY_HOUR: jede Stunde
|
||||
EVERY_MINUTE: Jede Minute
|
||||
EVERY_DAY_OF_WEEK: jeden Tag der Woche
|
||||
EVERY_DAY_OF_MONTH: jeden Tag des Monats
|
||||
EVERY_MONTH: jeden Monat
|
||||
TEXT_PERIOD: Alle <b />
|
||||
TEXT_MINS: ' bei <b /> Minuten nach der vollen Stunde (n)'
|
||||
TEXT_TIME: ' bei <b />:<b />'
|
||||
TEXT_DOW: ' auf <b />'
|
||||
TEXT_MONTH: ' von <b />'
|
||||
TEXT_DOM: ' auf <b />'
|
||||
ERROR1: Der Tag %s wird nicht unterstützt!
|
||||
ERROR2: Ungültige Anzahl von Elementen
|
||||
ERROR3: jquery_element sollte in den jqCron Einstellungen gesetzt werden
|
||||
ERROR4: Unbekannter Ausdruck
|
||||
|
||||
@@ -99,6 +99,8 @@ GRAV:
|
||||
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']
|
||||
YES: "Yes"
|
||||
NO: "No"
|
||||
CRON:
|
||||
EVERY: every
|
||||
EVERY_HOUR: every hour
|
||||
|
||||
@@ -23,6 +23,7 @@ GRAV:
|
||||
BAD_DATE: Fecha errónea
|
||||
AGO: antes
|
||||
FROM_NOW: desde ahora
|
||||
JUST_NOW: hace un momento
|
||||
SECOND: segundo
|
||||
MINUTE: minuto
|
||||
HOUR: hora
|
||||
@@ -32,12 +33,10 @@ GRAV:
|
||||
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
|
||||
@@ -47,7 +46,6 @@ GRAV:
|
||||
YEAR_PLURAL: años
|
||||
DECADE_PLURAL: décadas
|
||||
SEC_PLURAL: segs
|
||||
MIN_PLURAL: mins
|
||||
HR_PLURAL: hs
|
||||
WK_PLURAL: sem
|
||||
MO_PLURAL: mes
|
||||
@@ -78,3 +76,20 @@ GRAV:
|
||||
- 'Viernes'
|
||||
- 'Sábado'
|
||||
- 'Domingo'
|
||||
CRON:
|
||||
EVERY: cada
|
||||
EVERY_HOUR: cada hora
|
||||
EVERY_MINUTE: cada minuto
|
||||
EVERY_DAY_OF_WEEK: cada día de la semana
|
||||
EVERY_DAY_OF_MONTH: cada día del mes
|
||||
EVERY_MONTH: cada mes
|
||||
TEXT_PERIOD: Cada <b />
|
||||
TEXT_MINS: ' a <b /> minuto(s) despues de la hora'
|
||||
TEXT_TIME: ' a <b />:<b />'
|
||||
TEXT_DOW: ' en <b />'
|
||||
TEXT_MONTH: ' de<b />'
|
||||
TEXT_DOM: ' en<b />'
|
||||
ERROR1: La etiqueta %s no está soportada!
|
||||
ERROR2: El número de elementos es erroneo
|
||||
ERROR3: El jquery_element debería establecerse en la configuración del jqCron
|
||||
ERROR4: Expresión no reconocida
|
||||
|
||||
@@ -1,11 +1,30 @@
|
||||
---
|
||||
GRAV:
|
||||
FRONTMATTER_ERROR_PAGE: "---\npealkiri: %1$s\n---\n\n# Viga: vigane Frontmatter'i\n\nasukoht: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- 'equipment'
|
||||
- 'informatsioon'
|
||||
- 'rice'
|
||||
- 'money'
|
||||
- 'species'
|
||||
- 'series'
|
||||
- 'kala'
|
||||
- 'lammas'
|
||||
INFLECTOR_IRREGULAR:
|
||||
'person': 'inimesed'
|
||||
'man': 'mees'
|
||||
'child': 'lapsed'
|
||||
INFLECTOR_ORDINALS:
|
||||
'default': '.'
|
||||
'first': '.'
|
||||
'second': '.'
|
||||
'third': '.'
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Kuupäev määramata
|
||||
BAD_DATE: Vigane kuupäev
|
||||
AGO: tagasi
|
||||
FROM_NOW: praegusest
|
||||
JUST_NOW: just nüüd
|
||||
SECOND: sekund
|
||||
MINUTE: minut
|
||||
HOUR: tundi
|
||||
@@ -15,7 +34,6 @@ GRAV:
|
||||
YEAR: aasta
|
||||
DECADE: 10 aastat
|
||||
SEC: sek
|
||||
MIN: min
|
||||
HR: t
|
||||
WK: näd
|
||||
MO: k.
|
||||
@@ -61,3 +79,7 @@ GRAV:
|
||||
- 'reede'
|
||||
- 'laupäev'
|
||||
- 'pühapäev'
|
||||
CRON:
|
||||
EVERY: iga
|
||||
EVERY_MONTH: iga kuu
|
||||
TEXT_PERIOD: Iga <b />
|
||||
|
||||
@@ -15,7 +15,6 @@ GRAV:
|
||||
YEAR: urtea
|
||||
DECADE: hamarkada
|
||||
SEC: seg
|
||||
MIN: min
|
||||
HR: h
|
||||
WK: ast
|
||||
MO: hil
|
||||
|
||||
@@ -33,7 +33,6 @@ GRAV:
|
||||
MIN_PLURAL: دقیقه
|
||||
HR_PLURAL: ساعت
|
||||
WK_PLURAL: هفته
|
||||
MO_PLURAL: mos
|
||||
YR_PLURAL: سال
|
||||
DEC_PLURAL: دهه
|
||||
FORM:
|
||||
|
||||
@@ -1,11 +1,74 @@
|
||||
---
|
||||
GRAV:
|
||||
FRONTMATTER_ERROR_PAGE: "---\notsikko: %1$s\n---\n\n# Virhe: Virheellinen Frontmatter\n\nPolku: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
|
||||
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'
|
||||
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'
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- 'equipment'
|
||||
- 'information'
|
||||
- 'riisi'
|
||||
- 'raha'
|
||||
- 'lajit'
|
||||
- 'series'
|
||||
- 'kala'
|
||||
- 'lammas'
|
||||
INFLECTOR_IRREGULAR:
|
||||
'person': 'ihmiset'
|
||||
'man': 'miehet'
|
||||
'child': 'lapset'
|
||||
'sex': 'sukupuoli'
|
||||
INFLECTOR_ORDINALS:
|
||||
'default': '.'
|
||||
'first': '.'
|
||||
'second': '.'
|
||||
'third': '.'
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Päivämäärää ei annettu
|
||||
BAD_DATE: Virheellinen päivämäärä
|
||||
AGO: sitten
|
||||
FROM_NOW: tästä lähtien
|
||||
JUST_NOW: juuri nyt
|
||||
SECOND: sekuntti
|
||||
MINUTE: minuutti
|
||||
HOUR: tunti
|
||||
@@ -61,3 +124,11 @@ GRAV:
|
||||
- 'Perjantai'
|
||||
- 'Lauantai'
|
||||
- 'Sunnuntai'
|
||||
CRON:
|
||||
EVERY: joka
|
||||
EVERY_HOUR: joka tunti
|
||||
EVERY_MINUTE: joka minuutti
|
||||
EVERY_DAY_OF_WEEK: viikon jokaisena päivänä
|
||||
EVERY_DAY_OF_MONTH: kuukauden jokaisena päivänä
|
||||
EVERY_MONTH: joka kuukausi
|
||||
TEXT_PERIOD: Joka <b />
|
||||
|
||||
@@ -1,87 +1,54 @@
|
||||
---
|
||||
GRAV:
|
||||
FRONTMATTER_ERROR_PAGE: |
|
||||
---
|
||||
title: %1$s
|
||||
---
|
||||
|
||||
# Erreur : Frontmatter invalide
|
||||
|
||||
Path: `%2$s`
|
||||
|
||||
**%3$s**
|
||||
|
||||
```
|
||||
%4$s
|
||||
```
|
||||
FRONTMATTER_ERROR_PAGE: "---\ntitre: %1$s\n---\n\n# Erreur : Frontmatter invalide\n\nChemin: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
|
||||
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': '\1es'
|
||||
'/(bu)s$/i': 'Bus'
|
||||
'/(alias|status)/i': 'alias|status'
|
||||
'/(ax|test)is$/i': '\1s'
|
||||
'/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'
|
||||
'/(quiz)zes$/i': '\1'
|
||||
'/(alias|status)es$/i': '\1'
|
||||
'/([octop|vir])i$/i': '\1us'
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- équipement
|
||||
- informations
|
||||
- riz
|
||||
- argent
|
||||
- espèces
|
||||
- séries
|
||||
- poisson
|
||||
- mouton
|
||||
- 'équipement'
|
||||
- 'information'
|
||||
- 'riz'
|
||||
- 'argent'
|
||||
- 'espèces'
|
||||
- 'séries'
|
||||
- 'poisson'
|
||||
- 'mouton'
|
||||
INFLECTOR_IRREGULAR:
|
||||
person: personnes
|
||||
man: hommes
|
||||
child: enfants
|
||||
sex: sexes
|
||||
move: déplacements
|
||||
'person': 'personnes'
|
||||
'man': 'hommes'
|
||||
'child': 'enfants'
|
||||
'sex': 'sexes'
|
||||
'move': 'déplacements'
|
||||
INFLECTOR_ORDINALS:
|
||||
default: ème
|
||||
first: er
|
||||
second: ème
|
||||
third: ème
|
||||
'default': 'ème'
|
||||
'first': 'er'
|
||||
'second': 'ème'
|
||||
'third': 'ème'
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Aucune date fournie
|
||||
BAD_DATE: Date erronée
|
||||
AGO: plus tôt
|
||||
FROM_NOW: à partir de maintenant
|
||||
JUST_NOW: à l'instant
|
||||
SECOND: seconde
|
||||
MINUTE: minute
|
||||
HOUR: heure
|
||||
@@ -113,27 +80,44 @@ GRAV:
|
||||
YR_PLURAL: a
|
||||
DEC_PLURAL: décs
|
||||
FORM:
|
||||
VALIDATION_FAIL: '<b>La validation a échoué :</b>'
|
||||
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
|
||||
- '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
|
||||
- 'Lundi'
|
||||
- 'Mardi'
|
||||
- 'Mercredi'
|
||||
- 'Jeudi'
|
||||
- 'Vendredi'
|
||||
- 'Samedi'
|
||||
- 'Dimanche'
|
||||
CRON:
|
||||
EVERY: chaque
|
||||
EVERY_HOUR: toutes les heures
|
||||
EVERY_MINUTE: chaque minute
|
||||
EVERY_DAY_OF_WEEK: tous les jours de la semaine
|
||||
EVERY_DAY_OF_MONTH: tous les jours du mois
|
||||
EVERY_MONTH: chaque mois
|
||||
TEXT_PERIOD: Chaque<b/>
|
||||
TEXT_MINS: ' à <b /> minute(s) après l''heure'
|
||||
TEXT_TIME: ' à<b/>:<b/>'
|
||||
TEXT_DOW: ' sur <b/>'
|
||||
TEXT_MONTH: ' de <b />'
|
||||
TEXT_DOM: ' sur <b/>'
|
||||
ERROR1: La balise %s n'est pas supportée!
|
||||
ERROR2: Nombre invalide d'éléments
|
||||
ERROR3: L'élément jquery_element doit être défini dans les paramètres jqCron
|
||||
ERROR4: Expression non reconnue
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
---
|
||||
GRAV:
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- oprema
|
||||
- informacije
|
||||
- riža
|
||||
- novac
|
||||
- vrsta
|
||||
- serija
|
||||
- riba
|
||||
- ovca
|
||||
- 'oprema'
|
||||
- 'informacije'
|
||||
- 'riža'
|
||||
- 'novac'
|
||||
- 'vrsta'
|
||||
- 'serija'
|
||||
- 'riba'
|
||||
- 'ovca'
|
||||
INFLECTOR_IRREGULAR:
|
||||
person: osobe
|
||||
man: ljudi
|
||||
child: djeca
|
||||
sex: spolovi
|
||||
move: Pomakni
|
||||
'person': 'osobe'
|
||||
'man': 'ljudi'
|
||||
'child': 'djeca'
|
||||
'sex': 'spolovi'
|
||||
'move': 'Pomakni'
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Datum nije upisan
|
||||
BAD_DATE: Pogrešan datum
|
||||
@@ -50,27 +50,27 @@ GRAV:
|
||||
YR_PLURAL: g
|
||||
DEC_PLURAL: des
|
||||
FORM:
|
||||
VALIDATION_FAIL: '<b>Validacija nije uspjela:</b>'
|
||||
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
|
||||
- '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
|
||||
- 'Ponedjeljak'
|
||||
- 'Utorak'
|
||||
- 'Srijeda'
|
||||
- 'Četvrtak'
|
||||
- 'Petak'
|
||||
- 'Subota'
|
||||
- 'Nedjelja'
|
||||
|
||||
@@ -1,49 +1,6 @@
|
||||
---
|
||||
GRAV:
|
||||
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```"
|
||||
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'
|
||||
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'
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- 'felszerelés'
|
||||
- 'információ'
|
||||
@@ -69,6 +26,7 @@ GRAV:
|
||||
BAD_DATE: Hibás dátum
|
||||
AGO: elteltével
|
||||
FROM_NOW: mostantól
|
||||
JUST_NOW: épp most
|
||||
SECOND: másodperc
|
||||
MINUTE: perc
|
||||
HOUR: óra
|
||||
@@ -124,3 +82,16 @@ GRAV:
|
||||
- 'péntek'
|
||||
- 'szombat'
|
||||
- 'vasárnap'
|
||||
CRON:
|
||||
EVERY: minden
|
||||
EVERY_HOUR: óránként
|
||||
EVERY_MINUTE: percenként
|
||||
EVERY_DAY_OF_WEEK: a hét minden napján
|
||||
EVERY_DAY_OF_MONTH: a hónap minden napján
|
||||
EVERY_MONTH: minden hónapban
|
||||
TEXT_PERIOD: Minden <b />
|
||||
TEXT_MINS: '<b /> perccel az óra elteltével'
|
||||
ERROR1: A %s címke nem engedélyezett!
|
||||
ERROR2: Hibás elemszám
|
||||
ERROR3: A jquery_element-et a jqCron beállítsokban kell meghatározni
|
||||
ERROR4: Ismeretlen kifejezés
|
||||
|
||||
@@ -1,11 +1,27 @@
|
||||
---
|
||||
GRAV:
|
||||
FRONTMATTER_ERROR_PAGE: "---\njudul: %1$s\n---\n\n# Error: Frontmatter Tidak Valid\n\nLokasi Path: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
|
||||
FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Error: Frontmatter tidak valid\n\nLokasi: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- 'peralatan'
|
||||
- 'informasi'
|
||||
- 'nasi'
|
||||
- 'uang'
|
||||
- 'spesies'
|
||||
- 'rangkaian'
|
||||
- 'ikan'
|
||||
- 'domba'
|
||||
INFLECTOR_IRREGULAR:
|
||||
'person': 'orang-orang'
|
||||
'man': 'laki-laki'
|
||||
'child': 'anak-anak'
|
||||
'sex': 'jenis kelamin'
|
||||
'move': 'pindahkan'
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Tanggal tidak ada
|
||||
NO_DATE_PROVIDED: Tanggal tidak tersedia
|
||||
BAD_DATE: Format tanggal salah
|
||||
AGO: yang lalu
|
||||
FROM_NOW: sejak sekarang
|
||||
FROM_NOW: dari saat ini
|
||||
JUST_NOW: baru saja
|
||||
SECOND: detik
|
||||
MINUTE: menit
|
||||
HOUR: jam
|
||||
@@ -17,7 +33,7 @@ GRAV:
|
||||
SEC: dtk
|
||||
MIN: mnt
|
||||
HR: j
|
||||
WK: mgg
|
||||
WK: mng
|
||||
MO: bln
|
||||
YR: thn
|
||||
DEC: desimal
|
||||
@@ -61,3 +77,19 @@ GRAV:
|
||||
- 'Jumat'
|
||||
- 'Sabtu'
|
||||
- 'Minggu'
|
||||
CRON:
|
||||
EVERY: Setiap
|
||||
EVERY_HOUR: Setiap jam
|
||||
EVERY_MINUTE: Setiap menit
|
||||
EVERY_DAY_OF_WEEK: Setiap hari selama seminggu
|
||||
EVERY_DAY_OF_MONTH: pada tanggal setiap bulannya
|
||||
EVERY_MONTH: setiap bulan
|
||||
TEXT_PERIOD: Setiap <b />
|
||||
TEXT_TIME: ' pada <b />:<b />'
|
||||
TEXT_DOW: ' pada <b />'
|
||||
TEXT_MONTH: ' pada <b />'
|
||||
TEXT_DOM: ' pada <b />'
|
||||
ERROR1: Tag %s tidak didukung!
|
||||
ERROR2: Jumlah elemen tidak valid
|
||||
ERROR3: jquery_element harus ditetapkan ke pengaturan jqCron
|
||||
ERROR4: Ekspresi tidak dikenali
|
||||
|
||||
80
system/languages/is.yaml
Normal file
80
system/languages/is.yaml
Normal file
@@ -0,0 +1,80 @@
|
||||
---
|
||||
GRAV:
|
||||
FRONTMATTER_ERROR_PAGE: "---\ntitill: %1$s\n---\n\n# Villa: Ógilt efni á forsíðu\n\nSlóð: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- 'equipment'
|
||||
- 'upplýsingar'
|
||||
- 'rice'
|
||||
- 'money'
|
||||
- 'species'
|
||||
- 'series'
|
||||
- 'fish'
|
||||
- 'sheep'
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Engin dagsetning gefin
|
||||
BAD_DATE: Röng dagsetning
|
||||
AGO: síðan
|
||||
JUST_NOW: í þessu
|
||||
SECOND: sekúndu
|
||||
MINUTE: mínútu
|
||||
HOUR: klukkustund
|
||||
DAY: degi
|
||||
WEEK: viku
|
||||
MONTH: mánuði
|
||||
YEAR: ári
|
||||
DECADE: áratug
|
||||
SEC: sek
|
||||
MIN: mín
|
||||
HR: klst
|
||||
WK: vk
|
||||
MO: mán
|
||||
YR: ár
|
||||
DEC: árat
|
||||
SECOND_PLURAL: sekúndum
|
||||
MINUTE_PLURAL: mínútum
|
||||
HOUR_PLURAL: klukkustundum
|
||||
DAY_PLURAL: dögum
|
||||
WEEK_PLURAL: vikum
|
||||
MONTH_PLURAL: mánuðum
|
||||
YEAR_PLURAL: árum
|
||||
DECADE_PLURAL: áratugum
|
||||
SEC_PLURAL: sek
|
||||
MIN_PLURAL: mín
|
||||
HR_PLURAL: klst
|
||||
WK_PLURAL: vik
|
||||
MO_PLURAL: mán
|
||||
YR_PLURAL: árum
|
||||
DEC_PLURAL: árat
|
||||
FORM:
|
||||
VALIDATION_FAIL: <b>Sannvottun mistókst:</b>
|
||||
INVALID_INPUT: Ógilt inntak í
|
||||
MISSING_REQUIRED_FIELD: 'Vantar nauðsynlegan reit:'
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- 'janúar'
|
||||
- 'Febrúar'
|
||||
- 'Mars'
|
||||
- 'Apríl'
|
||||
- 'Maí'
|
||||
- 'Júní'
|
||||
- 'Júlí'
|
||||
- 'Ágúst'
|
||||
- 'September'
|
||||
- 'Október'
|
||||
- 'Nóvember'
|
||||
- 'Desember'
|
||||
DAYS_OF_THE_WEEK:
|
||||
- 'Mánudagur'
|
||||
- 'Þriðjudagur'
|
||||
- 'Miðvikudagur'
|
||||
- 'Fimmtudagur'
|
||||
- 'Föstudagur'
|
||||
- 'Laugardagur'
|
||||
- 'Sunnudagur'
|
||||
CRON:
|
||||
TEXT_TIME: ' á <b />:<b />'
|
||||
TEXT_DOW: ' á <b />'
|
||||
TEXT_MONTH: ' af <b />'
|
||||
TEXT_DOM: ' á <b />'
|
||||
ERROR1: Merkið %s er ekki stutt!
|
||||
ERROR3: Það ætti að setja jquery_element inn í stillingar jqCron
|
||||
ERROR4: Óþekkt segð
|
||||
@@ -1,11 +1,32 @@
|
||||
---
|
||||
GRAV:
|
||||
FRONTMATTER_ERROR_PAGE: "---Titolo: %1$s---# Errore: Frontmatter non valido: '%2$s' * *%3$s * * ' '%4$s ' '"
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- 'dotazione'
|
||||
- 'informazione'
|
||||
- 'riso'
|
||||
- 'denaro'
|
||||
- 'specie'
|
||||
- 'serie'
|
||||
- 'pesce'
|
||||
- 'pecora'
|
||||
INFLECTOR_IRREGULAR:
|
||||
'person': 'persone'
|
||||
'man': 'uomini'
|
||||
'child': 'bambino'
|
||||
'sex': 'sessi'
|
||||
'move': 'sposta'
|
||||
INFLECTOR_ORDINALS:
|
||||
'default': '°'
|
||||
'first': '°'
|
||||
'second': 'o'
|
||||
'third': 'o'
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Nessuna data fornita
|
||||
BAD_DATE: Data non valida
|
||||
AGO: fa
|
||||
FROM_NOW: da adesso
|
||||
JUST_NOW: ora
|
||||
SECOND: secondo
|
||||
MINUTE: minuto
|
||||
HOUR: ora
|
||||
@@ -37,27 +58,44 @@ GRAV:
|
||||
YR_PLURAL: anni
|
||||
DEC_PLURAL: decenni
|
||||
FORM:
|
||||
VALIDATION_FAIL: '<b>Validazione fallita:</b>'
|
||||
VALIDATION_FAIL: <b>Validazione fallita:</b>
|
||||
INVALID_INPUT: Input non valido in
|
||||
MISSING_REQUIRED_FIELD: 'Campo richiesto mancante:'
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- Gennaio
|
||||
- Febbraio
|
||||
- Marzo
|
||||
- Aprile
|
||||
- Maggio
|
||||
- Giugno
|
||||
- Luglio
|
||||
- Agosto
|
||||
- Settembre
|
||||
- Ottobre
|
||||
- Novembre
|
||||
- Dicembre
|
||||
- 'Gennaio'
|
||||
- 'Febbraio'
|
||||
- 'Marzo'
|
||||
- 'Aprile'
|
||||
- 'Maggio'
|
||||
- 'Giugno'
|
||||
- 'Luglio'
|
||||
- 'Agosto'
|
||||
- 'Settembre'
|
||||
- 'Ottobre'
|
||||
- 'Novembre'
|
||||
- 'Dicembre'
|
||||
DAYS_OF_THE_WEEK:
|
||||
- Lunedì
|
||||
- Martedì
|
||||
- Mercoledì
|
||||
- Giovedì
|
||||
- Venerdì
|
||||
- Sabato
|
||||
- Domenica
|
||||
- 'Lunedì'
|
||||
- 'Martedì'
|
||||
- 'Mercoledì'
|
||||
- 'Giovedì'
|
||||
- 'Venerdì'
|
||||
- 'Sabato'
|
||||
- 'Domenica'
|
||||
CRON:
|
||||
EVERY: ogni
|
||||
EVERY_HOUR: ogni ora
|
||||
EVERY_MINUTE: ogni minuto
|
||||
EVERY_DAY_OF_WEEK: ogni giorno della settimana
|
||||
EVERY_DAY_OF_MONTH: ogni giorno del mese
|
||||
EVERY_MONTH: ogni mese
|
||||
TEXT_PERIOD: Ogni <b />
|
||||
TEXT_MINS: ' a <b /> minuto(i) dall''inizio dell''ora'
|
||||
TEXT_TIME: ' alle <b />:<b />'
|
||||
TEXT_DOW: ' su <b />'
|
||||
TEXT_MONTH: ' di <b />'
|
||||
TEXT_DOM: ' di <b />'
|
||||
ERROR1: Il tag %s non è supportato!
|
||||
ERROR2: Numero di elementi non valido
|
||||
ERROR3: Il jquery_element deve essere impostato nelle impostazioni di jqCron
|
||||
ERROR4: Espressione non riconosciuta
|
||||
|
||||
@@ -1,59 +1,66 @@
|
||||
---
|
||||
GRAV:
|
||||
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: 時
|
||||
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: 時
|
||||
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: ['月', '火', '水', '木', '金', '土', '日']
|
||||
INFLECTOR_IRREGULAR:
|
||||
'person': 'みんな'
|
||||
'man': '人'
|
||||
'child': '子供'
|
||||
'sex': '性別'
|
||||
'move': '移動'
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: 日付が設定されていません
|
||||
BAD_DATE: 不正な日付
|
||||
AGO: 前
|
||||
SECOND: 秒
|
||||
MINUTE: 分
|
||||
HOUR: 時
|
||||
DAY: 日
|
||||
WEEK: 週
|
||||
MONTH: 月
|
||||
YEAR: 年
|
||||
DECADE: 10年
|
||||
SEC: 秒
|
||||
MIN: 分
|
||||
HR: 時
|
||||
WK: 週
|
||||
MO: 月
|
||||
YR: 年
|
||||
SECOND_PLURAL: 秒
|
||||
MINUTE_PLURAL: 分
|
||||
HOUR_PLURAL: 時
|
||||
DAY_PLURAL: 日
|
||||
WEEK_PLURAL: 週
|
||||
MONTH_PLURAL: 月
|
||||
YEAR_PLURAL: 年
|
||||
DECADE_PLURAL: 10年
|
||||
SEC_PLURAL: 秒
|
||||
MIN_PLURAL: 分
|
||||
HR_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:
|
||||
- '月'
|
||||
- '火'
|
||||
- '水'
|
||||
- '木'
|
||||
- '金'
|
||||
- '土'
|
||||
- '日'
|
||||
|
||||
@@ -1,17 +1,75 @@
|
||||
---
|
||||
GRAV:
|
||||
FRONTMATTER_ERROR_PAGE: "---\ntitel: %1$s\n---\n\n# Fout: ongeldige frontmatter\n\nPad: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
|
||||
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'
|
||||
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'
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- 'uitrusting'
|
||||
- 'informatie'
|
||||
- 'rijst'
|
||||
- 'geld'
|
||||
- 'soorten'
|
||||
- 'reeks'
|
||||
- 'vis'
|
||||
- 'schaap'
|
||||
INFLECTOR_IRREGULAR:
|
||||
'person': 'personen'
|
||||
'man': 'mensen'
|
||||
'child': 'kinderen'
|
||||
'sex': 'geslacht'
|
||||
'move': 'verplaatsen'
|
||||
INFLECTOR_ORDINALS:
|
||||
'default': 'th'
|
||||
'first': 'st'
|
||||
'second': 'nd'
|
||||
'third': 'rd'
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: geen datum opgegeven
|
||||
BAD_DATE: Datumformaat onjuist
|
||||
AGO: geleden
|
||||
FROM_NOW: vanaf nu
|
||||
JUST_NOW: zojuist
|
||||
SECOND: seconde
|
||||
MINUTE: minuut
|
||||
HOUR: uur
|
||||
@@ -23,10 +81,10 @@ GRAV:
|
||||
SEC: s
|
||||
MIN: min
|
||||
HR: u
|
||||
WK: wk
|
||||
WK: week
|
||||
MO: ma
|
||||
YR: j
|
||||
DEC: dec
|
||||
DEC: decennia
|
||||
SECOND_PLURAL: seconden
|
||||
MINUTE_PLURAL: minuten
|
||||
HOUR_PLURAL: uren
|
||||
@@ -47,18 +105,18 @@ GRAV:
|
||||
INVALID_INPUT: Ongeldige invoer in
|
||||
MISSING_REQUIRED_FIELD: 'Ontbrekend verplicht veld:'
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- 'januari'
|
||||
- 'februari'
|
||||
- 'maart'
|
||||
- 'april'
|
||||
- 'mei'
|
||||
- 'juni'
|
||||
- 'juli'
|
||||
- 'augustus'
|
||||
- 'september'
|
||||
- 'oktober'
|
||||
- 'november'
|
||||
- 'december'
|
||||
- 'Januari'
|
||||
- 'Februari'
|
||||
- 'Maart'
|
||||
- 'April'
|
||||
- 'Mei'
|
||||
- 'Juni'
|
||||
- 'Juli'
|
||||
- 'Augustus'
|
||||
- 'September'
|
||||
- 'Oktober'
|
||||
- 'November'
|
||||
- 'December'
|
||||
DAYS_OF_THE_WEEK:
|
||||
- 'Maandag'
|
||||
- 'Dinsdag'
|
||||
@@ -67,3 +125,20 @@ GRAV:
|
||||
- 'Vrijdag'
|
||||
- 'Zaterdag'
|
||||
- 'Zondag'
|
||||
CRON:
|
||||
EVERY: elke
|
||||
EVERY_HOUR: elk uur
|
||||
EVERY_MINUTE: elke minuut
|
||||
EVERY_DAY_OF_WEEK: elke dag van de week
|
||||
EVERY_DAY_OF_MONTH: elke dag van de maand
|
||||
EVERY_MONTH: elke maand
|
||||
TEXT_PERIOD: Elke <b />
|
||||
TEXT_MINS: ' <b /> minuten te laat'
|
||||
TEXT_TIME: ' op <b />:<b />'
|
||||
TEXT_DOW: ' op <b />'
|
||||
TEXT_MONTH: ' van <b />'
|
||||
TEXT_DOM: ' op <b />'
|
||||
ERROR1: De tag %s wordt niet ondersteund!
|
||||
ERROR2: Slecht aantal elementen
|
||||
ERROR3: Het jquery_element moet ingesteld worden in de jqCron instellingen
|
||||
ERROR4: Onbekende expressie
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
GRAV:
|
||||
FRONTMATTER_ERROR_PAGE: "---\nTittel: %1$s\n---\n\n# Feilmelding: Ugyldig Frontmatter\n\nSti: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
|
||||
INFLECTOR_PLURALS:
|
||||
'/(quiz)$/i': '\1zes'
|
||||
'/^(ox)$/i': '\1en'
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- 'utstyr'
|
||||
- 'informasjon'
|
||||
@@ -33,7 +30,6 @@ GRAV:
|
||||
YEAR: år
|
||||
DECADE: tiår
|
||||
SEC: sek
|
||||
MIN: min
|
||||
HR: t
|
||||
WK: uke
|
||||
MO: må
|
||||
|
||||
@@ -15,7 +15,6 @@ GRAV:
|
||||
YEAR: rok
|
||||
DECADE: dekada
|
||||
SEC: sek
|
||||
MIN: min
|
||||
HR: godz
|
||||
WK: tydz
|
||||
MO: m-c
|
||||
|
||||
@@ -35,3 +35,12 @@ GRAV:
|
||||
- 'Outubro'
|
||||
- 'Novembro'
|
||||
- 'Dezembro'
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- 'equipment'
|
||||
- 'information'
|
||||
- 'arroz'
|
||||
- 'money'
|
||||
- 'species'
|
||||
- 'series'
|
||||
- 'fish'
|
||||
- 'sheep'
|
||||
|
||||
@@ -1,50 +1,27 @@
|
||||
---
|
||||
GRAV:
|
||||
FRONTMATTER_ERROR_PAGE: |
|
||||
---
|
||||
Titlu: %1$s
|
||||
---
|
||||
# Eroare: Frontmatter este invalid
|
||||
|
||||
Calea: `%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'
|
||||
FRONTMATTER_ERROR_PAGE: "---\nTitlu: %1$s\n---\n# Eroare: Frontmatter este invalid\n\nCalea: `%2$s`\n\n**%3$s**\n\n```\n%4$s"
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- echipament
|
||||
- informaţie
|
||||
- orez
|
||||
- bani
|
||||
- specii
|
||||
- serii
|
||||
- peşte
|
||||
- oaie
|
||||
- 'echipament'
|
||||
- 'informaţie'
|
||||
- 'orez'
|
||||
- 'bani'
|
||||
- 'specii'
|
||||
- 'serii'
|
||||
- 'peşte'
|
||||
- 'oaie'
|
||||
INFLECTOR_IRREGULAR:
|
||||
person: persoane
|
||||
man: bărbați
|
||||
child: copii
|
||||
sex: sexe
|
||||
move: mutări
|
||||
'person': 'persoane'
|
||||
'man': 'bărbați'
|
||||
'child': 'copii'
|
||||
'sex': 'sexe'
|
||||
'move': 'mutări'
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Nu există o dată prevăzută
|
||||
BAD_DATE: Dată incorectă
|
||||
AGO: în urmă
|
||||
FROM_NOW: de acum
|
||||
JUST_NOW: chiar acum
|
||||
SECOND: secundă
|
||||
MINUTE: minut
|
||||
HOUR: oră
|
||||
@@ -53,8 +30,8 @@ GRAV:
|
||||
MONTH: lună
|
||||
YEAR: an
|
||||
DECADE: decadă
|
||||
SEC: sec
|
||||
MIN: min
|
||||
SEC: secunde
|
||||
MIN: minute
|
||||
HR: oră
|
||||
WK: săpt
|
||||
MO: lună
|
||||
@@ -76,27 +53,44 @@ GRAV:
|
||||
YR_PLURAL: ani
|
||||
DEC_PLURAL: decenii
|
||||
FORM:
|
||||
VALIDATION_FAIL: '<b>Validare nereușită</b>'
|
||||
VALIDATION_FAIL: <b>Validare nereușită</b>
|
||||
INVALID_INPUT: Date incorecte în
|
||||
MISSING_REQUIRED_FIELD: 'Câmp obligatoriu lipsă:'
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- Ianuarie
|
||||
- Februarie
|
||||
- Martie
|
||||
- Aprilie
|
||||
- Mai
|
||||
- Iunie
|
||||
- Iulie
|
||||
- August
|
||||
- Septembrie
|
||||
- Octombrie
|
||||
- Noiembrie
|
||||
- Decembrie
|
||||
- 'Ianuarie'
|
||||
- 'Februarie'
|
||||
- 'Martie'
|
||||
- 'Aprilie'
|
||||
- 'Mai'
|
||||
- 'Iunie'
|
||||
- 'Iulie'
|
||||
- 'August'
|
||||
- 'Septembrie'
|
||||
- 'Octombrie'
|
||||
- 'Noiembrie'
|
||||
- 'Decembrie'
|
||||
DAYS_OF_THE_WEEK:
|
||||
- Luni
|
||||
- Marți
|
||||
- Miercuri
|
||||
- Joi
|
||||
- Vineri
|
||||
- Sâmbătă
|
||||
- Duminică
|
||||
- 'Luni'
|
||||
- 'Marți'
|
||||
- 'Miercuri'
|
||||
- 'Joi'
|
||||
- 'Vineri'
|
||||
- 'Sâmbătă'
|
||||
- 'Duminică'
|
||||
CRON:
|
||||
EVERY: la fiecare
|
||||
EVERY_HOUR: la fiecare oră
|
||||
EVERY_MINUTE: la fiecare minut
|
||||
EVERY_DAY_OF_WEEK: fiecare zi a săptămânii
|
||||
EVERY_DAY_OF_MONTH: fiecare zi a lunii
|
||||
EVERY_MONTH: fiecare lună
|
||||
TEXT_PERIOD: Fiecare <b />
|
||||
TEXT_MINS: ' la <b /> minut(e) ale fiecărei ore'
|
||||
TEXT_TIME: ' la <b />:<b />'
|
||||
TEXT_DOW: ' pe <b />'
|
||||
TEXT_MONTH: 'al(e) <b />'
|
||||
TEXT_DOM: ' pe <b />'
|
||||
ERROR1: Eticheta %s nu este acceptată!
|
||||
ERROR2: Număr nevalid de elemente
|
||||
ERROR3: jquery_element ar trebui setat în opțiunile jqCron
|
||||
ERROR4: Expresie necunoscută
|
||||
|
||||
@@ -1,17 +1,32 @@
|
||||
---
|
||||
GRAV:
|
||||
FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Ошибка: недопустимое содержимое\n\nПуть: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
|
||||
FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Ошибка: недопустимое содержимое Frontmatter\n\nПуть: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- 'экипировка'
|
||||
- 'информация'
|
||||
- 'рис'
|
||||
- 'деньги'
|
||||
- 'виды'
|
||||
- 'серии'
|
||||
- 'рыба'
|
||||
- 'овца'
|
||||
INFLECTOR_IRREGULAR:
|
||||
'person': 'люди'
|
||||
'man': 'человек'
|
||||
'child': 'ребенок'
|
||||
'sex': 'пол'
|
||||
'move': 'движется'
|
||||
INFLECTOR_ORDINALS:
|
||||
'default': 'й'
|
||||
'first': 'й'
|
||||
'second': 'й'
|
||||
'third': 'й'
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Дата не указана
|
||||
BAD_DATE: Неверная дата
|
||||
AGO: назад
|
||||
FROM_NOW: теперь
|
||||
JUST_NOW: только что
|
||||
SECOND: секунда
|
||||
MINUTE: минута
|
||||
HOUR: час
|
||||
@@ -67,3 +82,20 @@ GRAV:
|
||||
- 'пятница'
|
||||
- 'суббота'
|
||||
- 'воскресенье'
|
||||
CRON:
|
||||
EVERY: раз в
|
||||
EVERY_HOUR: раз в час
|
||||
EVERY_MINUTE: раз в минуту
|
||||
EVERY_DAY_OF_WEEK: каждый день недели
|
||||
EVERY_DAY_OF_MONTH: каждый день недели
|
||||
EVERY_MONTH: раз в месяц
|
||||
TEXT_PERIOD: Каждый <b />
|
||||
TEXT_MINS: ' в <b /> минуте(ах) за час'
|
||||
TEXT_TIME: ' в <b />:<b />'
|
||||
TEXT_DOW: ' на <b />'
|
||||
TEXT_MONTH: ' из <b />'
|
||||
TEXT_DOM: ' на <b />'
|
||||
ERROR1: Тег %s не поддерживается!
|
||||
ERROR2: Неверное количество элементов
|
||||
ERROR3: jquery_element должен быть установлен в настройки jqCron
|
||||
ERROR4: Выражение не распознано
|
||||
|
||||
@@ -1,10 +1,75 @@
|
||||
---
|
||||
GRAV:
|
||||
FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Chyba: Chybný frontmatter\n\nPath: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
|
||||
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'
|
||||
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'
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- 'vybavenie'
|
||||
- 'informácie'
|
||||
- 'ryža'
|
||||
- 'peniaze'
|
||||
- 'druhy'
|
||||
- 'séria'
|
||||
- 'ryba'
|
||||
- 'ovce'
|
||||
INFLECTOR_IRREGULAR:
|
||||
'person': 'ľudia'
|
||||
'man': 'muži'
|
||||
'child': 'deti'
|
||||
'sex': 'pohlavia'
|
||||
'move': 'pohyby'
|
||||
INFLECTOR_ORDINALS:
|
||||
'default': '.'
|
||||
'first': '.'
|
||||
'second': '.'
|
||||
'third': '.'
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Neposkytnutý žiaden dátum
|
||||
BAD_DATE: Nesprávny dátum
|
||||
AGO: pred
|
||||
FROM_NOW: odteraz
|
||||
JUST_NOW: práve teraz
|
||||
SECOND: sekunda
|
||||
MINUTE: minúta
|
||||
HOUR: hodina
|
||||
@@ -60,3 +125,20 @@ GRAV:
|
||||
- 'Piatok'
|
||||
- 'Sobota'
|
||||
- 'Nedeľa'
|
||||
CRON:
|
||||
EVERY: každý
|
||||
EVERY_HOUR: každú hodinu
|
||||
EVERY_MINUTE: každú minútu
|
||||
EVERY_DAY_OF_WEEK: každý deň v týždni
|
||||
EVERY_DAY_OF_MONTH: každý deň v mesiaci
|
||||
EVERY_MONTH: každý mesiac
|
||||
TEXT_PERIOD: Každý <b />
|
||||
TEXT_MINS: ' at <b /> minute(s) past the hour'
|
||||
TEXT_TIME: ' at <b />:<b />'
|
||||
TEXT_DOW: ' on <b />'
|
||||
TEXT_MONTH: ' of <b />'
|
||||
TEXT_DOM: ' on <b />'
|
||||
ERROR1: Tag %s nieje podporovaný!
|
||||
ERROR2: Chybný počet položiek
|
||||
ERROR3: jquery_element musí byť nastavený v nastaveniach pre jqCron
|
||||
ERROR4: Neznámy výraz
|
||||
|
||||
@@ -15,7 +15,6 @@ GRAV:
|
||||
YEAR: leto
|
||||
DECADE: desetletje
|
||||
SEC: sek
|
||||
MIN: min
|
||||
HR: ur
|
||||
WK: T.
|
||||
MO: m
|
||||
|
||||
@@ -1,6 +1,17 @@
|
||||
---
|
||||
GRAV:
|
||||
FRONTMATTER_ERROR_PAGE: "--- titel: %1$s --- # Fel: Ogiltig Frontmatter-sökväg: `%2$s` **%3$s** ``` %4$s ```"
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- 'utrustning'
|
||||
- 'information'
|
||||
- 'ris'
|
||||
- 'pengar'
|
||||
- 'arter'
|
||||
- 'serier'
|
||||
- 'fisk'
|
||||
- 'får'
|
||||
INFLECTOR_IRREGULAR:
|
||||
'person': 'personer'
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Inget datum har angivits
|
||||
BAD_DATE: Ogiltigt datum
|
||||
@@ -15,12 +26,10 @@ GRAV:
|
||||
YEAR: år
|
||||
DECADE: årtionde
|
||||
SEC: sek
|
||||
MIN: min
|
||||
HR: t
|
||||
WK: v
|
||||
MO: m
|
||||
YR: år
|
||||
DEC: dec
|
||||
SECOND_PLURAL: sekunder
|
||||
MINUTE_PLURAL: minuter
|
||||
HOUR_PLURAL: timmar
|
||||
|
||||
@@ -1,19 +1,6 @@
|
||||
---
|
||||
GRAV:
|
||||
FRONTMATTER_ERROR_PAGE: |
|
||||
---
|
||||
ชื่อเรื่อง: %1$s
|
||||
---
|
||||
|
||||
# ข้อผิดพลาด: Invalid Frontmatter
|
||||
|
||||
Path: `%2$s`
|
||||
|
||||
**%3$s**
|
||||
|
||||
```
|
||||
%4$s
|
||||
```
|
||||
FRONTMATTER_ERROR_PAGE: "---\nชื่อเรื่อง: %1$s\n---\n\n# ข้อผิดพลาด: Invalid Frontmatter\n\nPath: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: ไม่มีวันที่ให้
|
||||
BAD_DATE: รูปแบบวันที่ผิด
|
||||
@@ -30,10 +17,6 @@ GRAV:
|
||||
SEC: วิ
|
||||
MIN: นาที
|
||||
HR: ชม.
|
||||
WK: wk
|
||||
MO: mo
|
||||
YR: yr
|
||||
DEC: dec
|
||||
SECOND_PLURAL: วินาที
|
||||
MINUTE_PLURAL: นาที
|
||||
HOUR_PLURAL: ชั่วโมง
|
||||
@@ -45,32 +28,29 @@ GRAV:
|
||||
SEC_PLURAL: วินาที
|
||||
MIN_PLURAL: นาที
|
||||
HR_PLURAL: ชั่วโมง
|
||||
WK_PLURAL: wks
|
||||
MO_PLURAL: mos
|
||||
YR_PLURAL: ปี
|
||||
DEC_PLURAL: decs
|
||||
FORM:
|
||||
VALIDATION_FAIL: '<b>ตรวจสอบล้มเหลว: </b>'
|
||||
INVALID_INPUT: ป้อนข้อมูลไม่ถูกต้องใน
|
||||
MISSING_REQUIRED_FIELD: 'ขาดข้อมูลที่จำเป็น:'
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- มกราคม
|
||||
- กุมภาพันธ์
|
||||
- มีนาคม
|
||||
- เมษายน
|
||||
- พฤษภาคม
|
||||
- มิถุนายน
|
||||
- กรกฏาคม
|
||||
- สิงหาคม
|
||||
- กันยายน
|
||||
- ตุลาคม
|
||||
- พฤศจิกายน
|
||||
- ธันวาคม
|
||||
- 'มกราคม'
|
||||
- 'กุมภาพันธ์'
|
||||
- 'มีนาคม'
|
||||
- 'เมษายน'
|
||||
- 'พฤษภาคม'
|
||||
- 'มิถุนายน'
|
||||
- 'กรกฏาคม'
|
||||
- 'สิงหาคม'
|
||||
- 'กันยายน'
|
||||
- 'ตุลาคม'
|
||||
- 'พฤศจิกายน'
|
||||
- 'ธันวาคม'
|
||||
DAYS_OF_THE_WEEK:
|
||||
- จันทร์
|
||||
- อังคาร
|
||||
- พุธ
|
||||
- พฤหัสบดี
|
||||
- ศุกร์
|
||||
- เสาร์
|
||||
- อาทิตย์
|
||||
- 'จันทร์'
|
||||
- 'อังคาร'
|
||||
- 'พุธ'
|
||||
- 'พฤหัสบดี'
|
||||
- 'ศุกร์'
|
||||
- 'เสาร์'
|
||||
- 'อาทิตย์'
|
||||
|
||||
62
system/languages/zh-tw.yaml
Normal file
62
system/languages/zh-tw.yaml
Normal file
@@ -0,0 +1,62 @@
|
||||
---
|
||||
GRAV:
|
||||
FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# 錯誤: 不正確的 Frontmatter\n\n路徑: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: 沒有提供日期
|
||||
BAD_DATE: 錯誤日期
|
||||
AGO: 之前
|
||||
FROM_NOW: 之後
|
||||
JUST_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:
|
||||
MISSING_REQUIRED_FIELD: 遺漏必填欄位:
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- '一月'
|
||||
- '二月'
|
||||
- '三月'
|
||||
- '四月'
|
||||
- '五月'
|
||||
- '六月'
|
||||
- '七月'
|
||||
- '八月'
|
||||
- '九月'
|
||||
- '十月'
|
||||
- '十一月'
|
||||
- '十二月'
|
||||
DAYS_OF_THE_WEEK:
|
||||
- '星期一'
|
||||
- '星期二'
|
||||
- '星期三'
|
||||
- '星期四'
|
||||
- '星期五'
|
||||
- '星期六'
|
||||
- '星期日'
|
||||
144
system/languages/zh.yaml
Normal file
144
system/languages/zh.yaml
Normal file
@@ -0,0 +1,144 @@
|
||||
---
|
||||
GRAV:
|
||||
FRONTMATTER_ERROR_PAGE: "---\n标题: %1$s\n---\n\n# 错误:无效参数\n\n位置: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
|
||||
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'
|
||||
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'
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- '装备'
|
||||
- '信息'
|
||||
- '大米'
|
||||
- '钱'
|
||||
- '物种'
|
||||
- '系列'
|
||||
- '鱼'
|
||||
- '羊'
|
||||
INFLECTOR_IRREGULAR:
|
||||
'person': '人员'
|
||||
'man': '男人'
|
||||
'child': '儿童'
|
||||
'sex': '性别'
|
||||
'move': '移动'
|
||||
INFLECTOR_ORDINALS:
|
||||
'default': 'th'
|
||||
'first': 'st'
|
||||
'second': 'md'
|
||||
'third': 'rd'
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: 无日期信息
|
||||
BAD_DATE: 无效日期
|
||||
AGO: 前
|
||||
FROM_NOW: 距今
|
||||
JUST_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:
|
||||
- '1月'
|
||||
- '2月'
|
||||
- '3月'
|
||||
- '4月'
|
||||
- '5月'
|
||||
- '6月'
|
||||
- '7月'
|
||||
- '8月'
|
||||
- '9月'
|
||||
- '10月'
|
||||
- '11月'
|
||||
- '12月'
|
||||
DAYS_OF_THE_WEEK:
|
||||
- '星期一'
|
||||
- '星期二'
|
||||
- '星期三'
|
||||
- '星期四'
|
||||
- '星期五'
|
||||
- '星期六'
|
||||
- '星期日'
|
||||
CRON:
|
||||
EVERY: 每隔
|
||||
EVERY_HOUR: 每小时
|
||||
EVERY_MINUTE: 每分钟
|
||||
EVERY_DAY_OF_WEEK: 一周中的每一天
|
||||
EVERY_DAY_OF_MONTH: 月份中的每一天
|
||||
EVERY_MONTH: 每月
|
||||
TEXT_PERIOD: 所有 <b />
|
||||
TEXT_MINS: ' 在 <b /> 小时过后的分钟'
|
||||
TEXT_TIME: ' 在 <b />:<b />'
|
||||
TEXT_DOW: ' on <b />'
|
||||
TEXT_MONTH: ' of <b />'
|
||||
TEXT_DOM: ' on <b />'
|
||||
ERROR1: 不支持分享类型 %s
|
||||
ERROR2: 无效数字
|
||||
ERROR3: 请在 jqCron 设置中设定 jquery_element
|
||||
ERROR4: 无法识别表达式
|
||||
@@ -1,9 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Core
|
||||
* @package Grav\Core
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -17,11 +17,21 @@ if (is_file($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . $_SERVER['SCRIPT_N
|
||||
return false;
|
||||
}
|
||||
|
||||
$grav_index = 'index.php';
|
||||
|
||||
/* Check the GRAV_BASEDIR environment variable and use if set */
|
||||
$grav_basedir = getenv('GRAV_BASEDIR') ?: '';
|
||||
if ($grav_basedir) {
|
||||
$grav_index = ltrim($grav_basedir, '/') . DIRECTORY_SEPARATOR . $grav_index;
|
||||
$grav_basedir = DIRECTORY_SEPARATOR . trim($grav_basedir, DIRECTORY_SEPARATOR);
|
||||
define('GRAV_ROOT', str_replace(DIRECTORY_SEPARATOR, '/', getcwd()) . $grav_basedir);
|
||||
}
|
||||
|
||||
$_SERVER = array_merge($_SERVER, $_ENV);
|
||||
$_SERVER['SCRIPT_FILENAME'] = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'index.php';
|
||||
$_SERVER['SCRIPT_NAME'] = DIRECTORY_SEPARATOR . 'index.php';
|
||||
$_SERVER['PHP_SELF'] = DIRECTORY_SEPARATOR . 'index.php';
|
||||
$_SERVER['SCRIPT_FILENAME'] = $_SERVER['DOCUMENT_ROOT'] . $grav_basedir .DIRECTORY_SEPARATOR . 'index.php';
|
||||
$_SERVER['SCRIPT_NAME'] = $grav_basedir . DIRECTORY_SEPARATOR . 'index.php';
|
||||
$_SERVER['PHP_SELF'] = $grav_basedir . DIRECTORY_SEPARATOR . 'index.php';
|
||||
|
||||
error_log(sprintf('%s:%d [%d]: %s', $_SERVER['REMOTE_ADDR'], $_SERVER['REMOTE_PORT'], http_response_code(), $_SERVER['REQUEST_URI']), 4);
|
||||
|
||||
require 'index.php';
|
||||
require $grav_index;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common
|
||||
* @package Grav\Common
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -36,12 +37,6 @@ class Assets extends PropertyObject
|
||||
/** @const Regex to match JavaScript files */
|
||||
const JS_REGEX = '/.\.js$/i';
|
||||
|
||||
/**
|
||||
* @const Regex to match <script> or <style> tag when adding inline style/script. Note that this only supports a
|
||||
* single tag, so the check is greedy to avoid issues in JS.
|
||||
*/
|
||||
const HTML_TAG_REGEX = '#(<([A-Z][A-Z0-9]*)>)+(.*)(<\/\2>)#is';
|
||||
|
||||
protected $assets_dir;
|
||||
protected $assets_url;
|
||||
|
||||
@@ -50,8 +45,10 @@ class Assets extends PropertyObject
|
||||
|
||||
// Config Options
|
||||
protected $css_pipeline;
|
||||
protected $css_pipeline_include_externals;
|
||||
protected $css_pipeline_before_excludes;
|
||||
protected $js_pipeline;
|
||||
protected $js_pipeline_include_externals;
|
||||
protected $js_pipeline_before_excludes;
|
||||
protected $pipeline_options = [];
|
||||
|
||||
@@ -122,7 +119,7 @@ class Assets extends PropertyObject
|
||||
* It automatically detects the asset type (JavaScript, CSS or collection).
|
||||
* You may add more than one asset passing an array as argument.
|
||||
*
|
||||
* @param $asset
|
||||
* @param array|string $asset
|
||||
* @return $this
|
||||
*/
|
||||
public function add($asset)
|
||||
@@ -175,7 +172,8 @@ class Assets extends PropertyObject
|
||||
// If pipeline disabled, set to position if provided, else after
|
||||
if (isset($options['pipeline'])) {
|
||||
if ($options['pipeline'] === false) {
|
||||
$excludes = strtolower($type . '_pipeline_before_excludes');
|
||||
$exclude_type = ($type === $this::JS_TYPE || $type === $this::INLINE_JS_TYPE) ? $this::JS_TYPE : $this::CSS_TYPE;
|
||||
$excludes = strtolower($exclude_type . '_pipeline_before_excludes');
|
||||
if ($this->{$excludes}) {
|
||||
$default = 'after';
|
||||
} else {
|
||||
@@ -269,6 +267,22 @@ class Assets extends PropertyObject
|
||||
protected function filterAssets($assets, $key, $value, $sort = false)
|
||||
{
|
||||
$results = array_filter($assets, function($asset) use ($key, $value) {
|
||||
|
||||
if ($key === 'position' && $value === 'pipeline') {
|
||||
|
||||
$type = $asset->getType();
|
||||
|
||||
if ($asset->getRemote() && $this->{$type . '_pipeline_include_externals'} === false && $asset['position'] === 'pipeline' ) {
|
||||
if ($this->{$type . '_pipeline_before_excludes'}) {
|
||||
$asset->setPosition('after');
|
||||
} else {
|
||||
$asset->setPosition('before');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($asset[$key] === $value) return true;
|
||||
return false;
|
||||
});
|
||||
@@ -297,11 +311,9 @@ class Assets extends PropertyObject
|
||||
$before_output = '';
|
||||
$pipeline_output = '';
|
||||
$after_output = '';
|
||||
$no_pipeline = [];
|
||||
|
||||
$assets = 'assets_' . $type;
|
||||
$pipeline_enabled = $type . '_pipeline';
|
||||
$before_excludes = $type . '_pipeline_before_excludes';
|
||||
$render_pipeline = 'render' . ucfirst($type);
|
||||
|
||||
$group_assets = $this->filterAssets($this->$assets, 'group', $group);
|
||||
@@ -314,22 +326,13 @@ class Assets extends PropertyObject
|
||||
$options = array_merge($this->pipeline_options, ['timestamp' => $this->timestamp]);
|
||||
|
||||
$pipeline = new Pipeline($options);
|
||||
$pipeline_output = $pipeline->$render_pipeline($pipeline_assets, $group, $attributes, $no_pipeline);
|
||||
$pipeline_output = $pipeline->$render_pipeline($pipeline_assets, $group, $attributes);
|
||||
} else {
|
||||
foreach ($pipeline_assets as $asset) {
|
||||
$pipeline_output .= $asset->render();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle stuff that couldn't be pipelined
|
||||
if (!empty($no_pipeline)) {
|
||||
if ($this->{$before_excludes}) {
|
||||
$after_assets = array_merge($after_assets, $no_pipeline);
|
||||
} else {
|
||||
$before_assets = array_merge($before_assets, $no_pipeline);
|
||||
}
|
||||
}
|
||||
|
||||
// Before Pipeline
|
||||
foreach ($before_assets as $asset) {
|
||||
$before_output .= $asset->render();
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Assets
|
||||
* @package Grav\Common\Assets
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -13,17 +14,16 @@ use Grav\Common\Grav;
|
||||
use Grav\Common\Uri;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Framework\Object\PropertyObject;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
abstract class BaseAsset extends PropertyObject
|
||||
{
|
||||
use AssetUtilsTrait;
|
||||
|
||||
const CSS_ASSET = true;
|
||||
const JS_ASSET = false;
|
||||
protected const CSS_ASSET = true;
|
||||
protected const JS_ASSET = false;
|
||||
|
||||
/** @const Regex to match CSS import content */
|
||||
const CSS_IMPORT_REGEX = '{@import(.*?);}';
|
||||
protected const CSS_IMPORT_REGEX = '{@import(.*?);}';
|
||||
|
||||
protected $asset;
|
||||
|
||||
@@ -78,10 +78,13 @@ abstract class BaseAsset extends PropertyObject
|
||||
}
|
||||
}
|
||||
|
||||
// Force priority to be an int
|
||||
$this->priority = (int) $this->priority;
|
||||
|
||||
// Do some special stuff for CSS/JS (not inline)
|
||||
if (!Utils::startsWith($this->getType(), 'inline')) {
|
||||
$this->base_url = rtrim($uri->rootUrl($config->get('system.absolute_urls')), '/') . '/';
|
||||
$this->remote = $this->isRemoteLink($asset);
|
||||
$this->remote = static::isRemoteLink($asset);
|
||||
|
||||
// Move this to render?
|
||||
if (!$this->remote) {
|
||||
@@ -129,6 +132,12 @@ abstract class BaseAsset extends PropertyObject
|
||||
return $this->remote;
|
||||
}
|
||||
|
||||
public function setPosition($position)
|
||||
{
|
||||
$this->position = $position;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -153,7 +162,6 @@ abstract class BaseAsset extends PropertyObject
|
||||
* Build local links including grav asset shortcodes
|
||||
*
|
||||
* @param string $asset the asset string reference
|
||||
* @param bool $absolute build absolute asset link
|
||||
*
|
||||
* @return string the final link url to the asset
|
||||
*/
|
||||
@@ -175,4 +183,16 @@ abstract class BaseAsset extends PropertyObject
|
||||
{
|
||||
return ['type' => $this->getType(), 'elements' => $this->getElements()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Placeholder for AssetUtilsTrait method
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $dir
|
||||
* @param bool $local
|
||||
*/
|
||||
protected function cssRewrite($file, $dir, $local)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Assets
|
||||
* @package Grav\Common\Assets
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -12,7 +13,6 @@ use Grav\Common\Utils;
|
||||
|
||||
class Css extends BaseAsset
|
||||
{
|
||||
|
||||
public function __construct(array $elements = [], $key = null)
|
||||
{
|
||||
$base_options = [
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Assets
|
||||
* @package Grav\Common\Assets
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Assets
|
||||
* @package Grav\Common\Assets
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Assets
|
||||
* @package Grav\Common\Assets
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Assets
|
||||
* @package Grav\Common\Assets
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -20,17 +21,19 @@ class Pipeline extends PropertyObject
|
||||
{
|
||||
use AssetUtilsTrait;
|
||||
|
||||
const CSS_ASSET = true;
|
||||
const JS_ASSET = false;
|
||||
protected const CSS_ASSET = true;
|
||||
protected const JS_ASSET = false;
|
||||
|
||||
/** @const Regex to match CSS urls */
|
||||
const CSS_URL_REGEX = '{url\(([\'\"]?)(.*?)\1\)}';
|
||||
protected const CSS_URL_REGEX = '{url\(([\'\"]?)(.*?)\1\)}';
|
||||
|
||||
/** @const Regex to match CSS sourcemap comments */
|
||||
const CSS_SOURCEMAP_REGEX = '{\/\*# (.*?) \*\/}';
|
||||
protected const CSS_SOURCEMAP_REGEX = '{\/\*# (.*?) \*\/}';
|
||||
|
||||
/** @const Regex to match CSS import content */
|
||||
const CSS_IMPORT_REGEX = '{@import(.*?);}';
|
||||
protected const CSS_IMPORT_REGEX = '{@import(.*?);}';
|
||||
|
||||
protected const FIRST_FORWARDSLASH_REGEX = '{^\/{1}\w}';
|
||||
|
||||
protected $css_minify;
|
||||
protected $css_minify_windows;
|
||||
@@ -47,9 +50,6 @@ class Pipeline extends PropertyObject
|
||||
protected $query;
|
||||
protected $asset;
|
||||
|
||||
protected $css_pipeline_include_externals;
|
||||
protected $js_pipeline_include_externals;
|
||||
|
||||
/**
|
||||
* Closure used by the pipeline to fetch assets.
|
||||
*
|
||||
@@ -88,11 +88,10 @@ class Pipeline extends PropertyObject
|
||||
* @param array $assets
|
||||
* @param string $group
|
||||
* @param array $attributes
|
||||
* @param array $no_pipeline
|
||||
*
|
||||
* @return bool|string URL or generated content if available, else false
|
||||
*/
|
||||
public function renderCss($assets, $group, $attributes = [], &$no_pipeline = [])
|
||||
public function renderCss($assets, $group, $attributes = [])
|
||||
{
|
||||
// temporary list of assets to pipeline
|
||||
$inline_group = false;
|
||||
@@ -116,21 +115,13 @@ class Pipeline extends PropertyObject
|
||||
if (file_exists($this->assets_dir . $file)) {
|
||||
$buffer = file_get_contents($this->assets_dir . $file) . "\n";
|
||||
} else {
|
||||
|
||||
foreach ($assets as $id => $asset) {
|
||||
if ($this->css_pipeline_include_externals === false && $asset->getRemote()) {
|
||||
$no_pipeline[$id] = $asset;
|
||||
unset($assets[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
//if nothing found get out of here!
|
||||
if (empty($assets) && empty($no_pipeline)) {
|
||||
if (empty($assets)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Concatenate files
|
||||
$buffer = $this->gatherLinks($assets, self::CSS_ASSET, $no_pipeline);
|
||||
$buffer = $this->gatherLinks($assets, self::CSS_ASSET);
|
||||
|
||||
// Minify if required
|
||||
if ($this->shouldMinify('css')) {
|
||||
@@ -140,7 +131,7 @@ class Pipeline extends PropertyObject
|
||||
}
|
||||
|
||||
// Write file
|
||||
if (\strlen(trim($buffer)) > 0) {
|
||||
if (trim($buffer) !== '') {
|
||||
file_put_contents($this->assets_dir . $file, $buffer);
|
||||
}
|
||||
}
|
||||
@@ -161,11 +152,10 @@ class Pipeline extends PropertyObject
|
||||
* @param array $assets
|
||||
* @param string $group
|
||||
* @param array $attributes
|
||||
* @param array $no_pipeline
|
||||
*
|
||||
* @return bool|string URL or generated content if available, else false
|
||||
*/
|
||||
public function renderJs($assets, $group, $attributes = [], &$no_pipeline = [])
|
||||
public function renderJs($assets, $group, $attributes = [])
|
||||
{
|
||||
// temporary list of assets to pipeline
|
||||
$inline_group = false;
|
||||
@@ -189,21 +179,13 @@ class Pipeline extends PropertyObject
|
||||
if (file_exists($this->assets_dir . $file)) {
|
||||
$buffer = file_get_contents($this->assets_dir . $file) . "\n";
|
||||
} else {
|
||||
|
||||
foreach ($assets as $id => $asset) {
|
||||
if ($this->js_pipeline_include_externals === false && $asset->getRemote()) {
|
||||
$no_pipeline[$id] = $asset;
|
||||
unset($assets[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
//if nothing found get out of here!
|
||||
if (empty($assets) && empty($no_pipeline)) {
|
||||
if (empty($assets)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Concatenate files
|
||||
$buffer = $this->gatherLinks($assets, self::JS_ASSET, $no_pipeline);
|
||||
$buffer = $this->gatherLinks($assets, self::JS_ASSET);
|
||||
|
||||
// Minify if required
|
||||
if ($this->shouldMinify('js')) {
|
||||
@@ -213,16 +195,16 @@ class Pipeline extends PropertyObject
|
||||
}
|
||||
|
||||
// Write file
|
||||
if (\strlen(trim($buffer)) > 0) {
|
||||
if (trim($buffer) !== '') {
|
||||
file_put_contents($this->assets_dir . $file, $buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if ($inline_group) {
|
||||
$output = "<script" . $this->renderAttributes(). ">\n" . $buffer . "\n</script>\n";
|
||||
$output = '<script' . $this->renderAttributes(). ">\n" . $buffer . "\n</script>\n";
|
||||
} else {
|
||||
$this->asset = $relative_path;
|
||||
$output = "<script src=\"" . $relative_path . $this->renderQueryString() . "\"" . $this->renderAttributes() . "></script>\n";
|
||||
$output = '<script src="' . $relative_path . $this->renderQueryString() . '"' . $this->renderAttributes() . "></script>\n";
|
||||
}
|
||||
|
||||
return $output;
|
||||
@@ -234,7 +216,7 @@ class Pipeline extends PropertyObject
|
||||
*
|
||||
* @param string $file the css source file
|
||||
* @param string $dir , $local relative path to the css file
|
||||
* @param boolean $local is this a local or remote asset
|
||||
* @param bool $local is this a local or remote asset
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -249,14 +231,22 @@ class Pipeline extends PropertyObject
|
||||
|
||||
$old_url = $matches[2];
|
||||
|
||||
// Ensure link is not rooted to webserver, a data URL, or to a remote host
|
||||
if (Utils::startsWith($old_url, '/') || Utils::startsWith($old_url, 'data:') || $this->isRemoteLink($old_url)) {
|
||||
// Ensure link is not rooted to web server, a data URL, or to a remote host
|
||||
if (preg_match(self::FIRST_FORWARDSLASH_REGEX, $old_url) || Utils::startsWith($old_url, 'data:') || $this->isRemoteLink($old_url)) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
$new_url = ($local ? $this->base_url: '') . ltrim(Utils::normalizePath($dir . '/' . $old_url), '/');
|
||||
// clean leading /
|
||||
$old_url = Utils::normalizePath($dir . '/' . $old_url);
|
||||
if (preg_match(self::FIRST_FORWARDSLASH_REGEX, $old_url)) {
|
||||
$old_url = ltrim($old_url, '/');
|
||||
}
|
||||
|
||||
return str_replace($old_url, $new_url, $matches[0]);
|
||||
$new_url = ($local ? $this->base_url: '') . $old_url;
|
||||
|
||||
$fixed = str_replace($matches[2], $new_url, $matches[0]);
|
||||
|
||||
return $fixed;
|
||||
}, $file);
|
||||
|
||||
return $file;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Assets.Traits
|
||||
* @package Grav\Common\Assets\Traits
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -24,7 +25,7 @@ trait AssetUtilsTrait
|
||||
{
|
||||
$base = Grav::instance()['uri']->rootUrl(true);
|
||||
|
||||
// sanity check for local URLs with absolute URL's enabled
|
||||
// Sanity check for local URLs with absolute URL's enabled
|
||||
if (Utils::startsWith($link, $base)) {
|
||||
return false;
|
||||
}
|
||||
@@ -37,11 +38,10 @@ trait AssetUtilsTrait
|
||||
*
|
||||
* @param array $assets
|
||||
* @param bool $css
|
||||
* @param array $no_pipeline
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function gatherLinks(array $assets, $css = true, &$no_pipeline = [])
|
||||
protected function gatherLinks(array $assets, $css = true)
|
||||
{
|
||||
$buffer = '';
|
||||
|
||||
@@ -52,12 +52,12 @@ trait AssetUtilsTrait
|
||||
$link = $asset->getAsset();
|
||||
$relative_path = $link;
|
||||
|
||||
if ($this->isRemoteLink($link)) {
|
||||
if (static::isRemoteLink($link)) {
|
||||
$local = false;
|
||||
if (0 === strpos($link, '//')) {
|
||||
$link = 'http:' . $link;
|
||||
}
|
||||
$relative_dir = dirname($relative_path);
|
||||
$relative_dir = \dirname($relative_path);
|
||||
} else {
|
||||
// Fix to remove relative dir if grav is in one
|
||||
if (($this->base_url !== '/') && Utils::startsWith($relative_path, $this->base_url)) {
|
||||
@@ -65,7 +65,7 @@ trait AssetUtilsTrait
|
||||
$relative_path = ltrim(preg_replace($base_url, '/', $link, 1), '/');
|
||||
}
|
||||
|
||||
$relative_dir = dirname($relative_path);
|
||||
$relative_dir = \dirname($relative_path);
|
||||
$link = ROOT_DIR . $relative_path;
|
||||
}
|
||||
|
||||
@@ -73,9 +73,6 @@ trait AssetUtilsTrait
|
||||
|
||||
// No file found, skip it...
|
||||
if ($file === false) {
|
||||
if (!$local) { // Assume we coudln't download this file for some reason assume it's not pipeline compatible
|
||||
$no_pipeline[$id] = $asset;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -112,7 +109,7 @@ trait AssetUtilsTrait
|
||||
{
|
||||
$imports = [];
|
||||
|
||||
$file = (string)preg_replace_callback(self::CSS_IMPORT_REGEX, function ($matches) {
|
||||
$file = (string)preg_replace_callback(self::CSS_IMPORT_REGEX, function ($matches) use (&$imports) {
|
||||
$imports[] = $matches[0];
|
||||
|
||||
return '';
|
||||
@@ -125,8 +122,6 @@ trait AssetUtilsTrait
|
||||
*
|
||||
* Build an HTML attribute string from an array.
|
||||
*
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function renderAttributes()
|
||||
@@ -157,6 +152,7 @@ trait AssetUtilsTrait
|
||||
/**
|
||||
* Render Querystring
|
||||
*
|
||||
* @param string $asset
|
||||
* @return string
|
||||
*/
|
||||
protected function renderQueryString($asset = null)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Assets.Traits
|
||||
* @package Grav\Common\Assets\Traits
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -13,24 +14,31 @@ use Grav\Common\Assets;
|
||||
trait LegacyAssetsTrait
|
||||
{
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
* @param string $type
|
||||
* @return array
|
||||
*/
|
||||
protected function unifyLegacyArguments($args, $type = Assets::CSS_TYPE)
|
||||
{
|
||||
// First argument is always the asset
|
||||
array_shift($args);
|
||||
|
||||
if (\count($args) === 0) {
|
||||
if (count($args) === 0) {
|
||||
return [];
|
||||
}
|
||||
if (\count($args) === 1 && \is_array($args[0])) {
|
||||
// New options array format
|
||||
if (count($args) === 1 && is_array($args[0])) {
|
||||
return $args[0];
|
||||
}
|
||||
// Handle obscure case where options array is mixed with a priority
|
||||
if (count($args) === 2 && is_array($args[0]) && is_int($args[1])) {
|
||||
$arguments = $args[0];
|
||||
$arguments['priority'] = $args[1];
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case(Assets::INLINE_CSS_TYPE):
|
||||
$defaults = ['priority' => null, 'group' => null];
|
||||
$arguments = $this->createArgumentsFromLegacy($args, $defaults);
|
||||
break;
|
||||
|
||||
case(Assets::JS_TYPE):
|
||||
$defaults = ['priority' => null, 'pipeline' => true, 'loading' => null, 'group' => null];
|
||||
$arguments = $this->createArgumentsFromLegacy($args, $defaults);
|
||||
@@ -43,12 +51,21 @@ trait LegacyAssetsTrait
|
||||
// special case to handle old attributes being passed in
|
||||
if (isset($arguments['attributes'])) {
|
||||
$old_attributes = $arguments['attributes'];
|
||||
$arguments = array_merge($arguments, $old_attributes);
|
||||
if (is_array($old_attributes)) {
|
||||
$arguments = array_merge($arguments, $old_attributes);
|
||||
} else {
|
||||
$arguments['type'] = $old_attributes;
|
||||
}
|
||||
}
|
||||
unset($arguments['attributes']);
|
||||
|
||||
break;
|
||||
|
||||
case(Assets::INLINE_CSS_TYPE):
|
||||
$defaults = ['priority' => null, 'group' => null];
|
||||
$arguments = $this->createArgumentsFromLegacy($args, $defaults);
|
||||
break;
|
||||
|
||||
default:
|
||||
case(Assets::CSS_TYPE):
|
||||
$defaults = ['priority' => null, 'pipeline' => true, 'group' => null, 'loading' => null];
|
||||
@@ -76,34 +93,36 @@ trait LegacyAssetsTrait
|
||||
/**
|
||||
* Convenience wrapper for async loading of JavaScript
|
||||
*
|
||||
* @param $asset
|
||||
* @param int $priority
|
||||
* @param bool $pipeline
|
||||
* @param string $group name of the group
|
||||
*
|
||||
* @deprecated Please use dynamic method with ['loading' => 'async']
|
||||
* @param string|array $asset
|
||||
* @param int $priority
|
||||
* @param bool $pipeline
|
||||
* @param string $group name of the group
|
||||
*
|
||||
* @return \Grav\Common\Assets
|
||||
* @deprecated Please use dynamic method with ['loading' => 'async'].
|
||||
*/
|
||||
public function addAsyncJs($asset, $priority = 10, $pipeline = true, $group = 'head')
|
||||
{
|
||||
user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use dynamic method with [\'loading\' => \'async\']', E_USER_DEPRECATED);
|
||||
|
||||
return $this->addJs($asset, $priority, $pipeline, 'async', $group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience wrapper for deferred loading of JavaScript
|
||||
*
|
||||
* @param $asset
|
||||
* @param int $priority
|
||||
* @param bool $pipeline
|
||||
* @param string $group name of the group
|
||||
*
|
||||
* @deprecated Please use dynamic method with ['loading' => 'defer']
|
||||
* @param string|array $asset
|
||||
* @param int $priority
|
||||
* @param bool $pipeline
|
||||
* @param string $group name of the group
|
||||
*
|
||||
* @return \Grav\Common\Assets
|
||||
* @deprecated Please use dynamic method with ['loading' => 'defer'].
|
||||
*/
|
||||
public function addDeferJs($asset, $priority = 10, $pipeline = true, $group = 'head')
|
||||
{
|
||||
user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use dynamic method with [\'loading\' => \'defer\']', E_USER_DEPRECATED);
|
||||
|
||||
return $this->addJs($asset, $priority, $pipeline, 'defer', $group);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Assets.Traits
|
||||
* @package Grav\Common\Assets\Traits
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -15,7 +16,7 @@ trait TestingAssetsTrait
|
||||
/**
|
||||
* Determines if an asset exists as a collection, CSS or JS reference
|
||||
*
|
||||
* @param $asset
|
||||
* @param string $asset
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -37,13 +38,14 @@ trait TestingAssetsTrait
|
||||
/**
|
||||
* Set the array of collections explicitly
|
||||
*
|
||||
* @param $collections
|
||||
* @param array $collections
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setCollection($collections)
|
||||
{
|
||||
$this->collections = $collections;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -88,7 +90,7 @@ trait TestingAssetsTrait
|
||||
/**
|
||||
* Set the whole array of CSS assets
|
||||
*
|
||||
* @param $css
|
||||
* @param array $css
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -102,7 +104,7 @@ trait TestingAssetsTrait
|
||||
/**
|
||||
* Set the whole array of JS assets
|
||||
*
|
||||
* @param $js
|
||||
* @param array $js
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -150,7 +152,7 @@ trait TestingAssetsTrait
|
||||
/**
|
||||
* Sets the state of CSS Pipeline
|
||||
*
|
||||
* @param boolean $value
|
||||
* @param bool $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -164,7 +166,7 @@ trait TestingAssetsTrait
|
||||
/**
|
||||
* Sets the state of JS Pipeline
|
||||
*
|
||||
* @param boolean $value
|
||||
* @param bool $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -217,7 +219,7 @@ trait TestingAssetsTrait
|
||||
/**
|
||||
* Explicitly set's a timestamp for assets
|
||||
*
|
||||
* @param $value
|
||||
* @param string|int $value
|
||||
*/
|
||||
public function setTimestamp($value)
|
||||
{
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Backup
|
||||
* @package Grav\Common\Backup
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -17,13 +18,14 @@ use Grav\Common\Utils;
|
||||
use Grav\Common\Grav;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
use RocketTheme\Toolbox\Event\EventDispatcher;
|
||||
use RocketTheme\Toolbox\File\JsonFile;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
class Backups
|
||||
{
|
||||
const BACKUP_FILENAME_REGEXZ = "#(.*)--(\d*).zip#";
|
||||
protected const BACKUP_FILENAME_REGEXZ = "#(.*)--(\d*).zip#";
|
||||
|
||||
const BACKUP_DATE_FORMAT = 'YmdHis';
|
||||
protected const BACKUP_DATE_FORMAT = 'YmdHis';
|
||||
|
||||
protected static $backup_dir;
|
||||
|
||||
@@ -39,7 +41,7 @@ class Backups
|
||||
|
||||
public function setup()
|
||||
{
|
||||
if (is_null(static::$backup_dir)) {
|
||||
if (null === static::$backup_dir) {
|
||||
static::$backup_dir = Grav::instance()['locator']->findResource('backup://', true, true);
|
||||
Folder::create(static::$backup_dir);
|
||||
}
|
||||
@@ -53,14 +55,15 @@ class Backups
|
||||
/** @var Inflector $inflector */
|
||||
$inflector = Grav::instance()['inflector'];
|
||||
|
||||
foreach ($this->getBackupProfiles() as $id => $profile) {
|
||||
foreach (static::getBackupProfiles() as $id => $profile) {
|
||||
$at = $profile['schedule_at'];
|
||||
$name = $inflector->hyphenize($profile['name']);
|
||||
$name = $inflector::hyphenize($profile['name']);
|
||||
$logs = 'logs/backup-' . $name . '.out';
|
||||
/** @var Job $job */
|
||||
$job = $scheduler->addFunction('Grav\Common\Backup\Backups::backup', [$id], $name );
|
||||
$job->at($at);
|
||||
$job->output($logs);
|
||||
$job->backlink('/tools/backups');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +89,7 @@ class Backups
|
||||
|
||||
public function getBackupNames()
|
||||
{
|
||||
return array_column($this->getBackupProfiles(), 'name');
|
||||
return array_column(static::getBackupProfiles(), 'name');
|
||||
}
|
||||
|
||||
public static function getTotalBackupsSize()
|
||||
@@ -99,7 +102,7 @@ class Backups
|
||||
|
||||
public static function getAvailableBackups($force = false)
|
||||
{
|
||||
if ($force || is_null(static::$backups)) {
|
||||
if ($force || null === static::$backups) {
|
||||
static::$backups = [];
|
||||
$backups_itr = new \GlobIterator(static::$backup_dir . '/*.zip', \FilesystemIterator::KEY_AS_FILENAME);
|
||||
$inflector = Grav::instance()['inflector'];
|
||||
@@ -165,7 +168,7 @@ class Backups
|
||||
}
|
||||
|
||||
if (!file_exists($backup_root)) {
|
||||
throw new \RuntimeException("Backup location: " . $backup_root . ' does not exist...');
|
||||
throw new \RuntimeException("Backup location: {$backup_root} does not exist...");
|
||||
}
|
||||
|
||||
$options = [
|
||||
@@ -192,7 +195,7 @@ class Backups
|
||||
}
|
||||
|
||||
// Log the backup
|
||||
Grav::instance()['log']->error('Backup Created: ' . $destination);
|
||||
Grav::instance()['log']->notice('Backup Created: ' . $destination);
|
||||
|
||||
// Fire Finished event
|
||||
Grav::instance()->fireEvent('onBackupFinished', new Event(['backup' => $destination]));
|
||||
@@ -200,6 +203,14 @@ class Backups
|
||||
// Purge anything required
|
||||
static::purge();
|
||||
|
||||
// Log
|
||||
$log = JsonFile::instance(Grav::instance()['locator']->findResource("log://backup.log", true, true));
|
||||
$log->content([
|
||||
'time' => time(),
|
||||
'location' => $destination
|
||||
]);
|
||||
$log->save();
|
||||
|
||||
return $destination;
|
||||
}
|
||||
|
||||
@@ -245,6 +256,6 @@ class Backups
|
||||
protected static function convertExclude($exclude)
|
||||
{
|
||||
$lines = preg_split("/[\s,]+/", $exclude);
|
||||
return array_map('trim', $lines, array_fill(0,count($lines),'/'));
|
||||
return array_map('trim', $lines, array_fill(0, \count($lines), '/'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common
|
||||
* @package Grav\Common
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -113,7 +114,7 @@ class Browser
|
||||
{
|
||||
$version = explode('.', $this->getLongVersion());
|
||||
|
||||
return intval($version[0]);
|
||||
return (int)$version[0];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,4 +135,15 @@ class Browser
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if “Do Not Track” is set by browser
|
||||
* @see https://www.w3.org/TR/tracking-dnt/
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isTrackable(): bool
|
||||
{
|
||||
return !(isset($_SERVER['HTTP_DNT']) && $_SERVER['HTTP_DNT'] === '1');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common
|
||||
* @package Grav\Common
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -11,15 +12,16 @@ namespace Grav\Common;
|
||||
use \Doctrine\Common\Cache as DoctrineCache;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Filesystem\Folder;
|
||||
use Grav\Common\Scheduler\Scheduler;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
use RocketTheme\Toolbox\Event\EventDispatcher;
|
||||
|
||||
/**
|
||||
* The GravCache object is used throughout Grav to store and retrieve cached data.
|
||||
* It uses DoctrineCache library and supports a variety of caching mechanisms. Those include:
|
||||
*
|
||||
* APCu
|
||||
* APC
|
||||
* XCache
|
||||
* RedisCache
|
||||
* MemCache
|
||||
* MemCacheD
|
||||
@@ -43,6 +45,11 @@ class Cache extends Getters
|
||||
*/
|
||||
protected $driver;
|
||||
|
||||
/**
|
||||
* @var CacheInterface
|
||||
*/
|
||||
protected $simpleCache;
|
||||
|
||||
protected $driver_name;
|
||||
|
||||
protected $driver_setting;
|
||||
@@ -117,7 +124,7 @@ class Cache extends Getters
|
||||
$this->config = $grav['config'];
|
||||
$this->now = time();
|
||||
|
||||
if (is_null($this->enabled)) {
|
||||
if (null === $this->enabled) {
|
||||
$this->enabled = (bool)$this->config->get('system.cache.enabled');
|
||||
}
|
||||
|
||||
@@ -139,6 +146,28 @@ class Cache extends Getters
|
||||
$dispatcher->addListener('onSchedulerInitialized', [$this, 'onSchedulerInitialized']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CacheInterface
|
||||
*/
|
||||
public function getSimpleCache()
|
||||
{
|
||||
if (null === $this->simpleCache) {
|
||||
$cache = new \Grav\Framework\Cache\Adapter\DoctrineCache($this->driver, '', $this->getLifetime());
|
||||
|
||||
// Disable cache key validation.
|
||||
$cache->setValidation(false);
|
||||
|
||||
$this->simpleCache = $cache;
|
||||
}
|
||||
|
||||
return $this->simpleCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the old out of date file-based caches
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function purgeOldCache()
|
||||
{
|
||||
$cache_dir = dirname($this->cache_dir);
|
||||
@@ -147,7 +176,7 @@ class Cache extends Getters
|
||||
|
||||
foreach (new \DirectoryIterator($cache_dir) as $file) {
|
||||
$dir = $file->getBasename();
|
||||
if ($file->isDot() || $file->isFile() || $dir === $current) {
|
||||
if ($dir === $current || $file->isDot() || $file->isFile()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -161,11 +190,11 @@ class Cache extends Getters
|
||||
/**
|
||||
* Public accessor to set the enabled state of the cache
|
||||
*
|
||||
* @param $enabled
|
||||
* @param bool|int $enabled
|
||||
*/
|
||||
public function setEnabled($enabled)
|
||||
{
|
||||
$this->enabled = (bool) $enabled;
|
||||
$this->enabled = (bool)$enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -202,19 +231,15 @@ class Cache extends Getters
|
||||
|
||||
// CLI compatibility requires a non-volatile cache driver
|
||||
if ($this->config->get('system.cache.cli_compatibility') && (
|
||||
$setting == 'auto' || $this->isVolatileDriver($setting))) {
|
||||
$setting === 'auto' || $this->isVolatileDriver($setting))) {
|
||||
$setting = $driver_name;
|
||||
}
|
||||
|
||||
if (!$setting || $setting == 'auto') {
|
||||
if (!$setting || $setting === 'auto') {
|
||||
if (extension_loaded('apcu')) {
|
||||
$driver_name = 'apcu';
|
||||
} elseif (extension_loaded('apc')) {
|
||||
$driver_name = 'apc';
|
||||
} elseif (extension_loaded('wincache')) {
|
||||
$driver_name = 'wincache';
|
||||
} elseif (extension_loaded('xcache')) {
|
||||
$driver_name = 'xcache';
|
||||
}
|
||||
} else {
|
||||
$driver_name = $setting;
|
||||
@@ -224,9 +249,6 @@ class Cache extends Getters
|
||||
|
||||
switch ($driver_name) {
|
||||
case 'apc':
|
||||
$driver = new DoctrineCache\ApcCache();
|
||||
break;
|
||||
|
||||
case 'apcu':
|
||||
$driver = new DoctrineCache\ApcuCache();
|
||||
break;
|
||||
@@ -235,45 +257,53 @@ class Cache extends Getters
|
||||
$driver = new DoctrineCache\WinCacheCache();
|
||||
break;
|
||||
|
||||
case 'xcache':
|
||||
$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 DoctrineCache\MemcacheCache();
|
||||
$driver->setMemcache($memcache);
|
||||
if (extension_loaded('memcache')) {
|
||||
$memcache = new \Memcache();
|
||||
$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);
|
||||
} else {
|
||||
throw new \LogicException('Memcache PHP extension has not been installed');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'memcached':
|
||||
$memcached = new \Memcached();
|
||||
$memcached->addServer($this->config->get('system.cache.memcached.server', 'localhost'),
|
||||
$this->config->get('system.cache.memcached.port', 11211));
|
||||
$driver = new DoctrineCache\MemcachedCache();
|
||||
$driver->setMemcached($memcached);
|
||||
if (extension_loaded('memcached')) {
|
||||
$memcached = new \Memcached();
|
||||
$memcached->addServer($this->config->get('system.cache.memcached.server', 'localhost'),
|
||||
$this->config->get('system.cache.memcached.port', 11211));
|
||||
$driver = new DoctrineCache\MemcachedCache();
|
||||
$driver->setMemcached($memcached);
|
||||
} else {
|
||||
throw new \LogicException('Memcached PHP extension has not been installed');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'redis':
|
||||
$redis = new \Redis();
|
||||
$socket = $this->config->get('system.cache.redis.socket', false);
|
||||
$password = $this->config->get('system.cache.redis.password', false);
|
||||
if (extension_loaded('redis')) {
|
||||
$redis = new \Redis();
|
||||
$socket = $this->config->get('system.cache.redis.socket', false);
|
||||
$password = $this->config->get('system.cache.redis.password', false);
|
||||
|
||||
if ($socket) {
|
||||
$redis->connect($socket);
|
||||
if ($socket) {
|
||||
$redis->connect($socket);
|
||||
} else {
|
||||
$redis->connect($this->config->get('system.cache.redis.server', 'localhost'),
|
||||
$this->config->get('system.cache.redis.port', 6379));
|
||||
}
|
||||
|
||||
// Authenticate with password if set
|
||||
if ($password && !$redis->auth($password)) {
|
||||
throw new \RedisException('Redis authentication failed');
|
||||
}
|
||||
|
||||
$driver = new DoctrineCache\RedisCache();
|
||||
$driver->setRedis($redis);
|
||||
} else {
|
||||
$redis->connect($this->config->get('system.cache.redis.server', 'localhost'),
|
||||
$this->config->get('system.cache.redis.port', 6379));
|
||||
throw new \LogicException('Redis PHP extension has not been installed');
|
||||
}
|
||||
|
||||
// Authenticate with password if set
|
||||
if ($password && !$redis->auth($password)) {
|
||||
throw new \RedisException('Redis authentication failed');
|
||||
}
|
||||
|
||||
$driver = new DoctrineCache\RedisCache();
|
||||
$driver->setRedis($redis);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -295,9 +325,9 @@ class Cache extends Getters
|
||||
{
|
||||
if ($this->enabled) {
|
||||
return $this->driver->fetch($id);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -328,6 +358,7 @@ class Cache extends Getters
|
||||
if ($this->enabled) {
|
||||
return $this->driver->delete($id);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -341,6 +372,7 @@ class Cache extends Getters
|
||||
if ($this->enabled) {
|
||||
return $this->driver->deleteAll();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -355,6 +387,7 @@ class Cache extends Getters
|
||||
if ($this->enabled) {
|
||||
return $this->driver->contains(($id));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -404,6 +437,9 @@ class Cache extends Getters
|
||||
case 'tmp-only':
|
||||
$remove_paths = self::$tmp_remove;
|
||||
break;
|
||||
case 'invalidate':
|
||||
$remove_paths = [];
|
||||
break;
|
||||
default:
|
||||
if (Grav::instance()['config']->get('system.cache.clear_images_by_default')) {
|
||||
$remove_paths = self::$standard_remove;
|
||||
@@ -459,7 +495,7 @@ class Cache extends Getters
|
||||
|
||||
$output[] = '';
|
||||
|
||||
if (($remove == 'all' || $remove == 'standard') && file_exists($user_config)) {
|
||||
if (($remove === 'all' || $remove === 'standard') && file_exists($user_config)) {
|
||||
touch($user_config);
|
||||
|
||||
$output[] = '<red>Touched: </red>' . $user_config;
|
||||
@@ -477,6 +513,23 @@ class Cache extends Getters
|
||||
return $output;
|
||||
}
|
||||
|
||||
public static function invalidateCache()
|
||||
{
|
||||
$user_config = USER_DIR . 'config/system.yaml';
|
||||
|
||||
if (file_exists($user_config)) {
|
||||
touch($user_config);
|
||||
}
|
||||
|
||||
// Clear stat cache
|
||||
@clearstatcache();
|
||||
|
||||
// Clear opcache
|
||||
if (function_exists('opcache_reset')) {
|
||||
@opcache_reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the cache lifetime programmatically
|
||||
@@ -489,7 +542,7 @@ class Cache extends Getters
|
||||
return;
|
||||
}
|
||||
|
||||
$interval = $future - $this->now;
|
||||
$interval = (int)($future - $this->now);
|
||||
if ($interval > 0 && $interval < $this->getLifetime()) {
|
||||
$this->lifetime = $interval;
|
||||
}
|
||||
@@ -504,7 +557,7 @@ class Cache extends Getters
|
||||
public function getLifetime()
|
||||
{
|
||||
if ($this->lifetime === null) {
|
||||
$this->lifetime = $this->config->get('system.cache.lifetime') ?: 604800; // 1 week default
|
||||
$this->lifetime = (int)($this->config->get('system.cache.lifetime') ?: 604800); // 1 week default
|
||||
}
|
||||
|
||||
return $this->lifetime;
|
||||
@@ -533,24 +586,41 @@ class Cache extends Getters
|
||||
/**
|
||||
* is this driver a volatile driver in that it resides in PHP process memory
|
||||
*
|
||||
* @param $setting
|
||||
* @param string $setting
|
||||
* @return bool
|
||||
*/
|
||||
public function isVolatileDriver($setting)
|
||||
{
|
||||
if (in_array($setting, ['apc', 'apcu', 'xcache', 'wincache'])) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static function to call as a scheduled Job to purge old Doctrine files
|
||||
*/
|
||||
public static function purgeJob()
|
||||
{
|
||||
/** @var Cache $cache */
|
||||
$cache = Grav::instance()['cache'];
|
||||
$deleted_folders = $cache->purgeOldCache();
|
||||
$msg = 'Purged ' . $deleted_folders . ' old cache folders...';
|
||||
return $msg;
|
||||
|
||||
echo 'Purged ' . $deleted_folders . ' old cache folders...';
|
||||
}
|
||||
|
||||
/**
|
||||
* Static function to call as a scheduled Job to clear Grav cache
|
||||
*
|
||||
* @param string $type
|
||||
*/
|
||||
public static function clearJob($type)
|
||||
{
|
||||
$result = static::clearCache($type);
|
||||
static::invalidateCache();
|
||||
|
||||
echo strip_tags(implode("\n", $result));
|
||||
}
|
||||
|
||||
public function onSchedulerInitialized(Event $event)
|
||||
@@ -559,13 +629,26 @@ class Cache extends Getters
|
||||
$scheduler = $event['scheduler'];
|
||||
$config = Grav::instance()['config'];
|
||||
|
||||
// File Cache Purge
|
||||
$at = $config->get('system.cache.purge_at');
|
||||
$name = 'cache-purge';
|
||||
$logs = 'logs/' . $name . '.out';
|
||||
|
||||
$job = $scheduler->addFunction('Grav\Common\Cache::purgeJob', null, $name );
|
||||
$job = $scheduler->addFunction('Grav\Common\Cache::purgeJob', [], $name );
|
||||
$job->at($at);
|
||||
$job->output($logs);
|
||||
$job->backlink('/config/system#caching');
|
||||
|
||||
// Cache Clear
|
||||
$at = $config->get('system.cache.clear_at');
|
||||
$clear_type = $config->get('system.cache.clear_job_type');
|
||||
$name = 'cache-clear';
|
||||
$logs = 'logs/' . $name . '.out';
|
||||
|
||||
$job = $scheduler->addFunction('Grav\Common\Cache::clearJob', [$clear_type], $name );
|
||||
$job->at($at);
|
||||
$job->output($logs);
|
||||
$job->backlink('/config/system#caching');
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common
|
||||
* @package Grav\Common
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -46,7 +47,7 @@ class Composer
|
||||
$composer = static::getComposerLocation();
|
||||
|
||||
if ($composer !== static::DEFAULT_PATH && is_executable($composer)) {
|
||||
$file = fopen($composer, 'r');
|
||||
$file = fopen($composer, 'rb');
|
||||
$firstLine = fgets($file);
|
||||
fclose($file);
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Config
|
||||
* @package Grav\Common\Config
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -198,9 +199,7 @@ abstract class CompiledBase
|
||||
$cache = include $filename;
|
||||
if (
|
||||
!\is_array($cache)
|
||||
|| !isset($cache['checksum'])
|
||||
|| !isset($cache['data'])
|
||||
|| !isset($cache['@class'])
|
||||
|| !isset($cache['checksum'], $cache['data'], $cache['@class'])
|
||||
|| $cache['@class'] !== \get_class($this)
|
||||
) {
|
||||
return false;
|
||||
|
||||
@@ -1,27 +1,30 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Config
|
||||
* @package Grav\Common\Config
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Common\Config;
|
||||
|
||||
use Grav\Common\Data\Blueprint;
|
||||
use Grav\Common\Data\BlueprintSchema;
|
||||
use Grav\Common\Grav;
|
||||
|
||||
/**
|
||||
* Class CompiledBlueprints
|
||||
* @package Grav\Common\Config
|
||||
*/
|
||||
class CompiledBlueprints extends CompiledBase
|
||||
{
|
||||
/**
|
||||
* @var int Version number for the compiled file.
|
||||
*/
|
||||
public $version = 2;
|
||||
public function __construct($cacheFolder, array $files, $path)
|
||||
{
|
||||
parent::__construct($cacheFolder, $files, $path);
|
||||
|
||||
/**
|
||||
* @var BlueprintSchema Blueprints object.
|
||||
*/
|
||||
protected $object;
|
||||
$this->version = 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns checksum from the configuration files.
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Config
|
||||
* @package Grav\Common\Config
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -12,16 +13,6 @@ use Grav\Common\File\CompiledYamlFile;
|
||||
|
||||
class CompiledConfig extends CompiledBase
|
||||
{
|
||||
/**
|
||||
* @var int Version number for the compiled file.
|
||||
*/
|
||||
public $version = 1;
|
||||
|
||||
/**
|
||||
* @var Config Configuration object.
|
||||
*/
|
||||
protected $object;
|
||||
|
||||
/**
|
||||
* @var callable Blueprints loader.
|
||||
*/
|
||||
@@ -32,6 +23,13 @@ class CompiledConfig extends CompiledBase
|
||||
*/
|
||||
protected $withDefaults;
|
||||
|
||||
public function __construct($cacheFolder, array $files, $path)
|
||||
{
|
||||
parent::__construct($cacheFolder, $files, $path);
|
||||
|
||||
$this->version = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set blueprints for the configuration.
|
||||
*
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Config
|
||||
* @package Grav\Common\Config
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -12,15 +13,12 @@ use Grav\Common\File\CompiledYamlFile;
|
||||
|
||||
class CompiledLanguages extends CompiledBase
|
||||
{
|
||||
/**
|
||||
* @var int Version number for the compiled file.
|
||||
*/
|
||||
public $version = 1;
|
||||
public function __construct($cacheFolder, array $files, $path)
|
||||
{
|
||||
parent::__construct($cacheFolder, $files, $path);
|
||||
|
||||
/**
|
||||
* @var Languages Configuration object.
|
||||
*/
|
||||
protected $object;
|
||||
$this->version = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create configuration object.
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Config
|
||||
* @package Grav\Common\Config
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -18,14 +19,22 @@ class Config extends Data
|
||||
{
|
||||
public $environment;
|
||||
|
||||
/** @var string */
|
||||
protected $key;
|
||||
/** @var string */
|
||||
protected $checksum;
|
||||
protected $modified = false;
|
||||
/** @var int */
|
||||
protected $timestamp = 0;
|
||||
/** @var bool */
|
||||
protected $modified = false;
|
||||
|
||||
public function key()
|
||||
{
|
||||
return $this->checksum();
|
||||
if (null === $this->key) {
|
||||
$this->key = md5($this->checksum . $this->timestamp);
|
||||
}
|
||||
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function checksum($checksum = null)
|
||||
@@ -100,14 +109,13 @@ class Config extends Data
|
||||
}
|
||||
}
|
||||
|
||||
// Override the media.upload_limit based on PHP values
|
||||
$upload_limit = Utils::getUploadLimit();
|
||||
$this->items['system']['media']['upload_limit'] = $upload_limit > 0 ? $upload_limit : 1024*1024*1024;
|
||||
// Legacy value - Override the media.upload_limit based on PHP values
|
||||
$this->items['system']['media']['upload_limit'] = Utils::getUploadLimit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @deprecated
|
||||
* @deprecated 1.5 Use Grav::instance()['languages'] instead.
|
||||
*/
|
||||
public function getLanguages()
|
||||
{
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Config
|
||||
* @package Grav\Common\Config
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Config
|
||||
* @package Grav\Common\Config
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -13,6 +14,22 @@ use Grav\Common\Utils;
|
||||
|
||||
class Languages extends Data
|
||||
{
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected $checksum;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected $modified;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected $timestamp;
|
||||
|
||||
|
||||
public function checksum($checksum = null)
|
||||
{
|
||||
if ($checksum !== null) {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Config
|
||||
* @package Grav\Common\Config
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -12,11 +13,23 @@ use Grav\Common\File\CompiledYamlFile;
|
||||
use Grav\Common\Data\Data;
|
||||
use Grav\Common\Utils;
|
||||
use Pimple\Container;
|
||||
use RocketTheme\Toolbox\File\YamlFile;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
class Setup extends Data
|
||||
{
|
||||
/**
|
||||
* @var array Environment aliases normalized to lower case.
|
||||
*/
|
||||
public static $environments = [
|
||||
'' => 'unknown',
|
||||
'127.0.0.1' => 'localhost',
|
||||
'::1' => 'localhost'
|
||||
];
|
||||
|
||||
/**
|
||||
* @var string Current environment normalized to lower case.
|
||||
*/
|
||||
public static $environment;
|
||||
|
||||
protected $streams = [
|
||||
@@ -120,6 +133,13 @@ class Setup extends Data
|
||||
'' => ['user://pages']
|
||||
]
|
||||
],
|
||||
'user-data' => [
|
||||
'type' => 'Stream',
|
||||
'force' => true,
|
||||
'prefixes' => [
|
||||
'' => ['user://data']
|
||||
]
|
||||
],
|
||||
'account' => [
|
||||
'type' => 'ReadOnlyStream',
|
||||
'prefixes' => [
|
||||
@@ -133,11 +153,25 @@ class Setup extends Data
|
||||
*/
|
||||
public function __construct($container)
|
||||
{
|
||||
$environment = static::$environment ?? $container['uri']->environment() ?: 'localhost';
|
||||
// If no environment is set, make sure we get one (CLI or hostname).
|
||||
if (!static::$environment) {
|
||||
if (\defined('GRAV_CLI')) {
|
||||
static::$environment = 'cli';
|
||||
} else {
|
||||
/** @var ServerRequestInterface $request */
|
||||
$request = $container['request'];
|
||||
$host = $request->getUri()->getHost();
|
||||
|
||||
static::$environment = Utils::substrToString($host, ':');
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve server aliases to the proper environment.
|
||||
$environment = $this->environments[static::$environment] ?? static::$environment;
|
||||
|
||||
// Pre-load setup.php which contains our initial configuration.
|
||||
// Configuration may contain dynamic parts, which is why we need to always load it.
|
||||
// If "GRAVE_SETUP_PATH" has been defined, use it, otherwise use defaults.
|
||||
// If "GRAV_SETUP_PATH" has been defined, use it, otherwise use defaults.
|
||||
$file = \defined('GRAV_SETUP_PATH') ? GRAV_SETUP_PATH : GRAV_ROOT . '/setup.php';
|
||||
$setup = is_file($file) ? (array) include $file : [];
|
||||
|
||||
@@ -151,8 +185,8 @@ class Setup extends Data
|
||||
parent::__construct($setup);
|
||||
|
||||
// Set up environment.
|
||||
$this->def('environment', $environment ?: 'cli');
|
||||
$this->def('streams.schemes.environment.prefixes', ['' => $environment ? ["user://{$environment}"] : []]);
|
||||
$this->def('environment', $environment);
|
||||
$this->def('streams.schemes.environment.prefixes', ['' => ["user://{$this->get('environment')}"]]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -272,7 +306,7 @@ class Setup extends Data
|
||||
// Create security.yaml if it doesn't exist.
|
||||
$filename = $locator->findResource('config://security.yaml', true, true);
|
||||
$security_file = CompiledYamlFile::instance($filename);
|
||||
$security_content = $security_file->content();
|
||||
$security_content = (array)$security_file->content();
|
||||
|
||||
if (!isset($security_content['salt'])) {
|
||||
$security_content = array_merge($security_content, ['salt' => Utils::generateRandomString(14)]);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Data
|
||||
* @package Grav\Common\Data
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -10,7 +11,7 @@ namespace Grav\Common\Data;
|
||||
|
||||
use Grav\Common\File\CompiledYamlFile;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\User\User;
|
||||
use Grav\Common\User\Interfaces\UserInterface;
|
||||
use RocketTheme\Toolbox\Blueprints\BlueprintForm;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
@@ -24,6 +25,18 @@ class Blueprint extends BlueprintForm
|
||||
/** @var BlueprintSchema */
|
||||
protected $blueprintSchema;
|
||||
|
||||
/** @var array */
|
||||
protected $defaults;
|
||||
|
||||
protected $handlers = [];
|
||||
|
||||
public function __clone()
|
||||
{
|
||||
if ($this->blueprintSchema) {
|
||||
$this->blueprintSchema = clone $this->blueprintSchema;
|
||||
}
|
||||
}
|
||||
|
||||
public function setScope($scope)
|
||||
{
|
||||
$this->scope = $scope;
|
||||
@@ -55,7 +68,60 @@ class Blueprint extends BlueprintForm
|
||||
{
|
||||
$this->initInternals();
|
||||
|
||||
return $this->blueprintSchema->getDefaults();
|
||||
if (null === $this->defaults) {
|
||||
$this->defaults = $this->blueprintSchema->getDefaults();
|
||||
}
|
||||
|
||||
return $this->defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize blueprints with its dynamic fields.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
foreach ($this->dynamic as $key => $data) {
|
||||
// Locate field.
|
||||
$path = explode('/', $key);
|
||||
$current = &$this->items;
|
||||
|
||||
foreach ($path as $field) {
|
||||
if (\is_object($current)) {
|
||||
// Handle objects.
|
||||
if (!isset($current->{$field})) {
|
||||
$current->{$field} = [];
|
||||
}
|
||||
|
||||
$current = &$current->{$field};
|
||||
} else {
|
||||
// Handle arrays and scalars.
|
||||
if (!\is_array($current)) {
|
||||
$current = [$field => []];
|
||||
} elseif (!isset($current[$field])) {
|
||||
$current[$field] = [];
|
||||
}
|
||||
|
||||
$current = &$current[$field];
|
||||
}
|
||||
}
|
||||
|
||||
// Set dynamic property.
|
||||
foreach ($data as $property => $call) {
|
||||
$action = $call['action'];
|
||||
$method = 'dynamic' . ucfirst($action);
|
||||
|
||||
if (isset($this->handlers[$action])) {
|
||||
$callable = $this->handlers[$action];
|
||||
$callable($current, $property, $call);
|
||||
} elseif (method_exists($this, $method)) {
|
||||
$this->{$method}($current, $property, $call);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,6 +140,20 @@ class Blueprint extends BlueprintForm
|
||||
return $this->blueprintSchema->mergeData($data1, $data2, $name, $separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process data coming from a form.
|
||||
*
|
||||
* @param array $data
|
||||
* @param array $toggles
|
||||
* @return array
|
||||
*/
|
||||
public function processForm(array $data, array $toggles = [])
|
||||
{
|
||||
$this->initInternals();
|
||||
|
||||
return $this->blueprintSchema->processForm($data, $toggles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return data fields that do not exist in blueprints.
|
||||
*
|
||||
@@ -105,15 +185,32 @@ class Blueprint extends BlueprintForm
|
||||
* Filter data by using blueprints.
|
||||
*
|
||||
* @param array $data
|
||||
* @param bool $missingValuesAsNull
|
||||
* @param bool $keepEmptyValues
|
||||
* @return array
|
||||
*/
|
||||
public function filter(array $data)
|
||||
public function filter(array $data, bool $missingValuesAsNull = false, bool $keepEmptyValues = false)
|
||||
{
|
||||
$this->initInternals();
|
||||
|
||||
return $this->blueprintSchema->filter($data);
|
||||
return $this->blueprintSchema->filter($data, $missingValuesAsNull, $keepEmptyValues);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Flatten data by using blueprints.
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function flattenData(array $data)
|
||||
{
|
||||
$this->initInternals();
|
||||
|
||||
return $this->blueprintSchema->flattenData($data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return blueprint data schema.
|
||||
*
|
||||
@@ -126,6 +223,11 @@ class Blueprint extends BlueprintForm
|
||||
return $this->blueprintSchema;
|
||||
}
|
||||
|
||||
public function addDynamicHandler(string $name, callable $callable): void
|
||||
{
|
||||
$this->handlers[$name] = $callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize validator.
|
||||
*/
|
||||
@@ -142,6 +244,7 @@ class Blueprint extends BlueprintForm
|
||||
|
||||
$this->blueprintSchema->embed('', $this->items);
|
||||
$this->blueprintSchema->init();
|
||||
$this->defaults = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,21 +371,19 @@ class Blueprint extends BlueprintForm
|
||||
*/
|
||||
protected function dynamicSecurity(array &$field, $property, array &$call)
|
||||
{
|
||||
if ($property) {
|
||||
if ($property || !empty($field['validate']['ignore'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$grav = Grav::instance();
|
||||
$actions = (array)$call['params'];
|
||||
|
||||
/** @var User $user */
|
||||
if (isset($grav['user'])) {
|
||||
$user = Grav::instance()['user'] ?? null;
|
||||
foreach ($actions as $action) {
|
||||
if (!$user->authorize($action)) {
|
||||
$this->addPropertyRecursive($field, 'validate', ['ignore' => true]);
|
||||
return;
|
||||
}
|
||||
/** @var UserInterface|null $user */
|
||||
$user = $grav['user'] ?? null;
|
||||
foreach ($actions as $action) {
|
||||
if (!$user || !$user->authorize($action)) {
|
||||
$this->addPropertyRecursive($field, 'validate', ['ignore' => true]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Data
|
||||
* @package Grav\Common\Data
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -52,7 +53,7 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
|
||||
public function validate(array $data)
|
||||
{
|
||||
try {
|
||||
$messages = $this->validateArray($data, $this->nested);
|
||||
$messages = $this->validateArray($data, $this->nested, $this->items['']['form'] ?? []);
|
||||
|
||||
} catch (\RuntimeException $e) {
|
||||
throw (new ValidationException($e->getMessage(), $e->getCode(), $e))->setMessages();
|
||||
@@ -63,44 +64,95 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param array $toggles
|
||||
* @return array
|
||||
*/
|
||||
public function processForm(array $data, array $toggles = [])
|
||||
{
|
||||
return $this->processFormRecursive($data, $toggles, $this->nested);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter data by using blueprints.
|
||||
*
|
||||
* @param array $data Incoming data, for example from a form.
|
||||
* @param bool $missingValuesAsNull Include missing values as nulls.
|
||||
* @param bool $keepEmptyValues Include empty values.
|
||||
* @return array
|
||||
*/
|
||||
public function filter(array $data, $missingValuesAsNull = false)
|
||||
public function filter(array $data, $missingValuesAsNull = false, $keepEmptyValues = false)
|
||||
{
|
||||
return $this->filterArray($data, $this->nested, $missingValuesAsNull);
|
||||
return $this->filterArray($data, $this->nested, $missingValuesAsNull, $keepEmptyValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten data by using blueprints.
|
||||
*
|
||||
* @param array $data Data to be flattened.
|
||||
* @return array
|
||||
*/
|
||||
public function flattenData(array $data)
|
||||
{
|
||||
return $this->flattenArray($data, $this->nested, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param array $rules
|
||||
* @param string $prefix
|
||||
* @return array
|
||||
*/
|
||||
protected function flattenArray(array $data, array $rules, string $prefix)
|
||||
{
|
||||
$array = [];
|
||||
|
||||
foreach ($data as $key => $field) {
|
||||
$val = $rules[$key] ?? $rules['*'] ?? null;
|
||||
$rule = is_string($val) ? $this->items[$val] : null;
|
||||
|
||||
if ($rule || isset($val['*'])) {
|
||||
// Item has been defined in blueprints.
|
||||
$array[$prefix.$key] = $field;
|
||||
} elseif (is_array($field) && is_array($val)) {
|
||||
// Array has been defined in blueprints.
|
||||
$array += $this->flattenArray($field, $val, $prefix . $key . '.');
|
||||
} else {
|
||||
// Undefined/extra item.
|
||||
$array[$prefix.$key] = $field;
|
||||
}
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param array $rules
|
||||
* @param array $parent
|
||||
* @return array
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function validateArray(array $data, array $rules)
|
||||
protected function validateArray(array $data, array $rules, array $parent)
|
||||
{
|
||||
$messages = $this->checkRequired($data, $rules);
|
||||
|
||||
foreach ($data as $key => $field) {
|
||||
foreach ($data as $key => $child) {
|
||||
$val = $rules[$key] ?? $rules['*'] ?? null;
|
||||
$rule = \is_string($val) ? $this->items[$val] : null;
|
||||
|
||||
if ($rule) {
|
||||
// Item has been defined in blueprints.
|
||||
if (!empty($rule['validate']['ignore'])) {
|
||||
if (!empty($rule['disabled']) || !empty($rule['validate']['ignore'])) {
|
||||
// Skip validation in the ignored field.
|
||||
continue;
|
||||
}
|
||||
|
||||
$messages += Validation::validate($field, $rule);
|
||||
} elseif (\is_array($field) && \is_array($val)) {
|
||||
$messages += Validation::validate($child, $rule);
|
||||
} elseif (\is_array($child) && \is_array($val)) {
|
||||
// Array has been defined in blueprints.
|
||||
$messages += $this->validateArray($field, $val);
|
||||
} elseif (isset($rules['validation']) && $rules['validation'] === 'strict') {
|
||||
$messages += $this->validateArray($child, $val, $rule ?? []);
|
||||
} elseif (isset($parent['validation']) && $parent['validation'] === 'strict') {
|
||||
// Undefined/extra item.
|
||||
throw new \RuntimeException(sprintf('%s is not defined in blueprints', $key));
|
||||
}
|
||||
@@ -113,9 +165,10 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
|
||||
* @param array $data
|
||||
* @param array $rules
|
||||
* @param bool $missingValuesAsNull
|
||||
* @param bool $keepEmptyValues
|
||||
* @return array
|
||||
*/
|
||||
protected function filterArray(array $data, array $rules, $missingValuesAsNull)
|
||||
protected function filterArray(array $data, array $rules, $missingValuesAsNull, $keepEmptyValues)
|
||||
{
|
||||
$results = [];
|
||||
|
||||
@@ -126,8 +179,8 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
|
||||
$val = $rules[$key] ?? $rules['*'] ?? null;
|
||||
$rule = \is_string($val) ? $this->items[$val] : null;
|
||||
|
||||
if (empty($rule['validate']['ignore'])) {
|
||||
$results[$key] = null;
|
||||
if (empty($rule['disabled']) && empty($rule['validate']['ignore'])) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,25 +192,71 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
|
||||
|
||||
if ($rule) {
|
||||
// Item has been defined in blueprints.
|
||||
if (!empty($rule['validate']['ignore'])) {
|
||||
if (!empty($rule['disabled']) || !empty($rule['validate']['ignore'])) {
|
||||
// Skip any data in the ignored field.
|
||||
unset($results[$key]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$field = Validation::filter($field, $rule);
|
||||
} elseif (\is_array($field) && \is_array($val)) {
|
||||
// Array has been defined in blueprints.
|
||||
$field = $this->filterArray($field, $val, $missingValuesAsNull);
|
||||
$field = $this->filterArray($field, $val, $missingValuesAsNull, $keepEmptyValues);
|
||||
|
||||
} elseif (isset($rules['validation']) && $rules['validation'] === 'strict') {
|
||||
$field = null;
|
||||
// Skip any extra data.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (null !== $field && (!\is_array($field) || !empty($field))) {
|
||||
if ($keepEmptyValues || (null !== $field && (!\is_array($field) || !empty($field)))) {
|
||||
$results[$key] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
return $results ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $data
|
||||
* @param array $toggles
|
||||
* @param array $nested
|
||||
* @return array|null
|
||||
*/
|
||||
protected function processFormRecursive(?array $data, array $toggles, array $nested)
|
||||
{
|
||||
foreach ($nested as $key => $value) {
|
||||
if ($key === '') {
|
||||
continue;
|
||||
}
|
||||
if ($key === '*') {
|
||||
// TODO: Add support to collections.
|
||||
continue;
|
||||
}
|
||||
if (is_array($value)) {
|
||||
// Recursively fetch the items.
|
||||
$data[$key] = $this->processFormRecursive($data[$key] ?? null, $toggles[$key] ?? [], $value);
|
||||
} else {
|
||||
$field = $this->get($value);
|
||||
// Do not add the field if:
|
||||
if (
|
||||
// Not an input field
|
||||
!$field
|
||||
// Field has been disabled
|
||||
|| !empty($field['disabled'])
|
||||
// Field validation is set to be ignored
|
||||
|| !empty($field['validate']['ignore'])
|
||||
// Field is toggleable and the toggle is turned off
|
||||
|| (!empty($field['toggleable']) && empty($toggles[$key]))
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
if (!isset($data[$key])) {
|
||||
$data[$key] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -177,7 +276,7 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
|
||||
$field = $this->items[$field];
|
||||
|
||||
// Skip ignored field, it will not be required.
|
||||
if (!empty($field['validate']['ignore'])) {
|
||||
if (!empty($field['disabled']) || !empty($field['validate']['ignore'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Data
|
||||
* @package Grav\Common\Data
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -38,7 +39,8 @@ class Blueprints
|
||||
public function get($type)
|
||||
{
|
||||
if (!isset($this->instances[$type])) {
|
||||
$this->instances[$type] = $this->loadFile($type);
|
||||
$blueprint = $this->loadFile($type);
|
||||
$this->instances[$type] = $blueprint;
|
||||
}
|
||||
|
||||
return $this->instances[$type];
|
||||
@@ -98,6 +100,15 @@ class Blueprints
|
||||
$blueprint->setContext($this->search);
|
||||
}
|
||||
|
||||
return $blueprint->load()->init();
|
||||
try {
|
||||
$blueprint->load()->init();
|
||||
} catch (\RuntimeException $e) {
|
||||
$log = Grav::instance()['log'];
|
||||
$log->error(sprintf('Blueprint %s cannot be loaded: %s', $name, $e->getMessage()));
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return $blueprint;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Data
|
||||
* @package Grav\Common\Data
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -25,12 +26,18 @@ class Data implements DataInterface, \ArrayAccess, \Countable, \JsonSerializable
|
||||
/** @var array */
|
||||
protected $items;
|
||||
|
||||
/** @var Blueprints */
|
||||
/** @var Blueprint */
|
||||
protected $blueprints;
|
||||
|
||||
/** @var File */
|
||||
protected $storage;
|
||||
|
||||
/** @var bool */
|
||||
private $missingValuesAsNull = false;
|
||||
|
||||
/** @var bool */
|
||||
private $keepEmptyValues = true;
|
||||
|
||||
/**
|
||||
* @param array $items
|
||||
* @param Blueprint|callable $blueprints
|
||||
@@ -41,6 +48,28 @@ class Data implements DataInterface, \ArrayAccess, \Countable, \JsonSerializable
|
||||
$this->blueprints = $blueprints;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $value
|
||||
* @return $this
|
||||
*/
|
||||
public function setKeepEmptyValues(bool $value)
|
||||
{
|
||||
$this->keepEmptyValues = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $value
|
||||
* @return $this
|
||||
*/
|
||||
public function setMissingValuesAsNull(bool $value)
|
||||
{
|
||||
$this->missingValuesAsNull = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
@@ -197,11 +226,14 @@ class Data implements DataInterface, \ArrayAccess, \Countable, \JsonSerializable
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
* Filter all items by using blueprints.
|
||||
*/
|
||||
public function filter()
|
||||
{
|
||||
$this->items = $this->blueprints()->filter($this->items);
|
||||
$args = func_get_args();
|
||||
$missingValuesAsNull = (bool)(array_shift($args) ?? $this->missingValuesAsNull);
|
||||
$keepEmptyValues = (bool)(array_shift($args) ?? $this->keepEmptyValues);
|
||||
|
||||
$this->items = $this->blueprints()->filter($this->items, $missingValuesAsNull, $keepEmptyValues);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Data
|
||||
* @package Grav\Common\Data
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Data
|
||||
* @package Grav\Common\Data
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -11,35 +12,32 @@ namespace Grav\Common\Data;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Common\Yaml;
|
||||
use RocketTheme\Toolbox\Compat\Yaml\Yaml as FallbackYaml;
|
||||
|
||||
class Validation
|
||||
{
|
||||
/**
|
||||
* Validate value against a blueprint field definition.
|
||||
*
|
||||
* @param $value
|
||||
* @param mixed $value
|
||||
* @param array $field
|
||||
* @return array
|
||||
*/
|
||||
public static function validate($value, array $field)
|
||||
{
|
||||
$messages = [];
|
||||
|
||||
$validate = isset($field['validate']) ? (array) $field['validate'] : [];
|
||||
// Validate type with fallback type text.
|
||||
$type = (string) isset($validate['type']) ? $validate['type'] : $field['type'];
|
||||
$method = 'type' . str_replace('-', '_', $type);
|
||||
|
||||
// If value isn't required, we will stop validation if empty value is given.
|
||||
if ((empty($validate['required']) || (isset($validate['required']) && $validate['required'] !== true)) && ($value === null || $value === '' || (($field['type'] === 'checkbox' || $field['type'] === 'switch') && $value == false))) {
|
||||
return $messages;
|
||||
}
|
||||
|
||||
if (!isset($field['type'])) {
|
||||
$field['type'] = 'text';
|
||||
}
|
||||
|
||||
$validate = (array)($field['validate'] ?? null);
|
||||
$type = $validate['type'] ?? $field['type'];
|
||||
$required = $validate['required'] ?? false;
|
||||
|
||||
// If value isn't required, we will stop validation if empty value is given.
|
||||
if ($required !== true && ($value === null || $value === '' || (($field['type'] === 'checkbox' || $field['type'] === 'switch') && $value == false))
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Get language class.
|
||||
$language = Grav::instance()['language'];
|
||||
|
||||
@@ -49,17 +47,17 @@ class Validation
|
||||
: $language->translate('GRAV.FORM.INVALID_INPUT', null, true) . ' "' . $language->translate($name) . '"';
|
||||
|
||||
|
||||
// Validate type with fallback type text.
|
||||
$method = 'type' . str_replace('-', '_', $type);
|
||||
|
||||
// If this is a YAML field validate/filter as such
|
||||
if ($type !== 'yaml' && isset($field['yaml']) && $field['yaml'] === true) {
|
||||
if (isset($field['yaml']) && $field['yaml'] === true) {
|
||||
$method = 'typeYaml';
|
||||
}
|
||||
|
||||
if (method_exists(__CLASS__, $method)) {
|
||||
$success = self::$method($value, $validate, $field);
|
||||
} else {
|
||||
$success = true;
|
||||
}
|
||||
$messages = [];
|
||||
|
||||
$success = method_exists(__CLASS__, $method) ? self::$method($value, $validate, $field) : true;
|
||||
if (!$success) {
|
||||
$messages[$field['name']][] = $message;
|
||||
}
|
||||
@@ -89,7 +87,7 @@ class Validation
|
||||
*/
|
||||
public static function filter($value, array $field)
|
||||
{
|
||||
$validate = isset($field['validate']) ? (array) $field['validate'] : [];
|
||||
$validate = (array)($field['filter'] ?? $field['validate'] ?? null);
|
||||
|
||||
// If value isn't required, we will return null if empty value is given.
|
||||
if (($value === null || $value === '') && empty($validate['required'])) {
|
||||
@@ -99,19 +97,17 @@ class Validation
|
||||
if (!isset($field['type'])) {
|
||||
$field['type'] = 'text';
|
||||
}
|
||||
$type = $field['filter']['type'] ?? $field['validate']['type'] ?? $field['type'];
|
||||
|
||||
|
||||
// Validate type with fallback type text.
|
||||
$type = (string) isset($field['validate']['type']) ? $field['validate']['type'] : $field['type'];
|
||||
$method = 'filter' . ucfirst(str_replace('-', '_', $type));
|
||||
|
||||
// If this is a YAML field validate/filter as such
|
||||
if ($type !== 'yaml' && isset($field['yaml']) && $field['yaml'] === true) {
|
||||
if (isset($field['yaml']) && $field['yaml'] === true) {
|
||||
$method = 'filterYaml';
|
||||
}
|
||||
|
||||
if (!method_exists(__CLASS__, $method)) {
|
||||
$method = 'filterText';
|
||||
$method = isset($field['array']) && $field['array'] === true ? 'filterArray' : 'filterText';
|
||||
}
|
||||
|
||||
return self::$method($value, $validate, $field);
|
||||
@@ -133,6 +129,10 @@ class Validation
|
||||
|
||||
$value = (string)$value;
|
||||
|
||||
if (!empty($params['trim'])) {
|
||||
$value = trim($value);
|
||||
}
|
||||
|
||||
if (isset($params['min']) && \strlen($value) < $params['min']) {
|
||||
return false;
|
||||
}
|
||||
@@ -155,9 +155,31 @@ class Validation
|
||||
|
||||
protected static function filterText($value, array $params, array $field)
|
||||
{
|
||||
if (!\is_string($value) && !is_numeric($value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (!empty($params['trim'])) {
|
||||
$value = trim($value);
|
||||
}
|
||||
|
||||
return (string) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @param array $params
|
||||
* @param array $field
|
||||
* @return string|null
|
||||
*/
|
||||
protected static function filterCheckbox($value, array $params, array $field)
|
||||
{
|
||||
$value = (string)$value;
|
||||
$field_value = (string)($field['value'] ?? '1');
|
||||
|
||||
return $value === $field_value ? $value : null;
|
||||
}
|
||||
|
||||
protected static function filterCommaList($value, array $params, array $field)
|
||||
{
|
||||
return \is_array($value) ? $value : preg_split('/\s*,\s*/', $value, -1, PREG_SPLIT_NO_EMPTY);
|
||||
@@ -253,8 +275,8 @@ class Validation
|
||||
*/
|
||||
public static function typeCheckbox($value, array $params, array $field)
|
||||
{
|
||||
$value = (string) $value;
|
||||
$field_value = (string) ($field['value'] ?? '1');
|
||||
$value = (string)$value;
|
||||
$field_value = (string)($field['value'] ?? '1');
|
||||
|
||||
return $value === $field_value;
|
||||
}
|
||||
@@ -282,6 +304,10 @@ class Validation
|
||||
*/
|
||||
public static function typeToggle($value, array $params, array $field)
|
||||
{
|
||||
if (\is_bool($value)) {
|
||||
$value = (int)$value;
|
||||
}
|
||||
|
||||
return self::typeArray((array) $value, $params, $field);
|
||||
}
|
||||
|
||||
@@ -295,12 +321,12 @@ class Validation
|
||||
*/
|
||||
public static function typeFile($value, array $params, array $field)
|
||||
{
|
||||
return self::typeArray((array) $value, $params, $field);
|
||||
return self::typeArray((array)$value, $params, $field);
|
||||
}
|
||||
|
||||
protected static function filterFile($value, array $params, array $field)
|
||||
{
|
||||
return (array) $value;
|
||||
return (array)$value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -560,10 +586,22 @@ class Validation
|
||||
}
|
||||
}
|
||||
|
||||
$options = isset($field['options']) ? array_keys($field['options']) : [];
|
||||
$values = isset($field['use']) && $field['use'] === 'keys' ? array_keys($value) : $value;
|
||||
// If creating new values is allowed, no further checks are needed.
|
||||
if (!empty($field['selectize']['create'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !($options && array_diff($values, $options));
|
||||
$options = $field['options'] ?? [];
|
||||
$use = $field['use'] ?? 'values';
|
||||
|
||||
if (empty($field['selectize']) || empty($field['multiple'])) {
|
||||
$options = array_keys($options);
|
||||
}
|
||||
if ($use === 'keys') {
|
||||
$value = array_keys($value);
|
||||
}
|
||||
|
||||
return !($options && array_diff($value, $options));
|
||||
}
|
||||
|
||||
protected static function filterArray($value, $params, $field)
|
||||
@@ -597,9 +635,13 @@ class Validation
|
||||
|
||||
if (isset($field['ignore_empty']) && Utils::isPositive($field['ignore_empty'])) {
|
||||
foreach ($values as $key => $val) {
|
||||
foreach ($val as $inner_key => $inner_value) {
|
||||
if ($inner_value == '') {
|
||||
unset($val[$inner_key]);
|
||||
if ($val === '') {
|
||||
unset($values[$key]);
|
||||
} elseif (\is_array($val)) {
|
||||
foreach ($val as $inner_key => $inner_value) {
|
||||
if ($inner_value === '') {
|
||||
unset($val[$inner_key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -662,6 +704,23 @@ class Validation
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Input value which can be ignored.
|
||||
*
|
||||
* @param mixed $value Value to be validated.
|
||||
* @param array $params Validation parameters.
|
||||
* @param array $field Blueprint for the field.
|
||||
* @return bool True if validation succeeded.
|
||||
*/
|
||||
public static function typeUnset($value, array $params, array $field)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function filterUnset($value, array $params, array $field)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// HTML5 attributes (min, max and range are handled inside the types)
|
||||
|
||||
@@ -729,20 +788,17 @@ class Validation
|
||||
|
||||
public static function validateInt($value, $params)
|
||||
{
|
||||
return is_numeric($value) && (int) $value == $value;
|
||||
return is_numeric($value) && (int)$value == $value;
|
||||
}
|
||||
|
||||
protected static function filterInt($value, $params)
|
||||
{
|
||||
return (int) $value;
|
||||
return (int)$value;
|
||||
}
|
||||
|
||||
public static function validateArray($value, $params)
|
||||
{
|
||||
return \is_array($value)
|
||||
|| ($value instanceof \ArrayAccess
|
||||
&& $value instanceof \Traversable
|
||||
&& $value instanceof \Countable);
|
||||
return \is_array($value) || ($value instanceof \ArrayAccess && $value instanceof \Traversable && $value instanceof \Countable);
|
||||
}
|
||||
|
||||
public static function filterItem_List($value, $params)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Data
|
||||
* @package Grav\Common\Data
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common
|
||||
* @package Grav\Common
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Common;
|
||||
|
||||
use DebugBar\DataCollector\ConfigCollector;
|
||||
use DebugBar\DataCollector\DataCollectorInterface;
|
||||
use DebugBar\DataCollector\ExceptionsCollector;
|
||||
use DebugBar\DataCollector\MemoryCollector;
|
||||
use DebugBar\DataCollector\MessagesCollector;
|
||||
@@ -19,6 +21,9 @@ use DebugBar\DebugBar;
|
||||
use DebugBar\JavascriptRenderer;
|
||||
use DebugBar\StandardDebugBar;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Processors\ProcessorInterface;
|
||||
use Twig\Template;
|
||||
use Twig\TemplateWrapper;
|
||||
|
||||
class Debugger
|
||||
{
|
||||
@@ -37,10 +42,12 @@ class Debugger
|
||||
/** @var bool */
|
||||
protected $enabled;
|
||||
|
||||
protected $initialized = false;
|
||||
|
||||
/** @var array */
|
||||
protected $timers = [];
|
||||
|
||||
/** @var string[] $deprecations */
|
||||
/** @var array $deprecations */
|
||||
protected $deprecations = [];
|
||||
|
||||
/** @var callable */
|
||||
@@ -84,13 +91,18 @@ class Debugger
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if ($this->initialized) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->grav = Grav::instance();
|
||||
$this->config = $this->grav['config'];
|
||||
|
||||
// Enable/disable debugger based on configuration.
|
||||
$this->enabled = $this->config->get('system.debugger.enabled');
|
||||
$this->enabled = (bool)$this->config->get('system.debugger.enabled');
|
||||
|
||||
if ($this->enabled()) {
|
||||
$this->initialized = true;
|
||||
|
||||
$plugins_config = (array)$this->config->get('plugins');
|
||||
|
||||
@@ -112,12 +124,12 @@ class Debugger
|
||||
*
|
||||
* @param bool $state If null, the method returns the enabled value. If set, the method sets the enabled state
|
||||
*
|
||||
* @return null
|
||||
* @return bool
|
||||
*/
|
||||
public function enabled($state = null)
|
||||
{
|
||||
if ($state !== null) {
|
||||
$this->enabled = $state;
|
||||
$this->enabled = (bool)$state;
|
||||
}
|
||||
|
||||
return $this->enabled;
|
||||
@@ -173,7 +185,7 @@ class Debugger
|
||||
/**
|
||||
* Adds a data collector
|
||||
*
|
||||
* @param $collector
|
||||
* @param DataCollectorInterface $collector
|
||||
*
|
||||
* @return $this
|
||||
* @throws \DebugBar\DebugBarException
|
||||
@@ -188,9 +200,9 @@ class Debugger
|
||||
/**
|
||||
* Returns a data collector
|
||||
*
|
||||
* @param $collector
|
||||
* @param DataCollectorInterface $collector
|
||||
*
|
||||
* @return \DebugBar\DataCollector\DataCollectorInterface
|
||||
* @return DataCollectorInterface
|
||||
* @throws \DebugBar\DebugBarException
|
||||
*/
|
||||
public function getCollector($collector)
|
||||
@@ -262,7 +274,7 @@ class Debugger
|
||||
*/
|
||||
public function startTimer($name, $description = null)
|
||||
{
|
||||
if ($name[0] === '_' || $this->enabled()) {
|
||||
if (strpos($name, '_') === 0 || $this->enabled()) {
|
||||
$this->debugbar['time']->startMeasure($name, $description);
|
||||
$this->timers[] = $name;
|
||||
}
|
||||
@@ -279,7 +291,7 @@ class Debugger
|
||||
*/
|
||||
public function stopTimer($name)
|
||||
{
|
||||
if (\in_array($name, $this->timers, true) && ($name[0] === '_' || $this->enabled())) {
|
||||
if (\in_array($name, $this->timers, true) && (strpos($name, '_') === 0 || $this->enabled())) {
|
||||
$this->debugbar['time']->stopMeasure($name);
|
||||
}
|
||||
|
||||
@@ -289,7 +301,7 @@ class Debugger
|
||||
/**
|
||||
* Dump variables into the Messages tab of the Debug Bar
|
||||
*
|
||||
* @param $message
|
||||
* @param mixed $message
|
||||
* @param string $label
|
||||
* @param bool $isString
|
||||
*
|
||||
@@ -312,7 +324,7 @@ class Debugger
|
||||
*/
|
||||
public function addException(\Exception $e)
|
||||
{
|
||||
if ($this->enabled()) {
|
||||
if ($this->initialized && $this->enabled()) {
|
||||
$this->debugbar['exceptions']->addException($e);
|
||||
}
|
||||
|
||||
@@ -335,7 +347,7 @@ class Debugger
|
||||
*/
|
||||
public function deprecatedErrorHandler($errno, $errstr, $errfile, $errline)
|
||||
{
|
||||
if ($errno !== E_USER_DEPRECATED) {
|
||||
if ($errno !== E_USER_DEPRECATED && $errno !== E_DEPRECATED) {
|
||||
if ($this->errorHandler) {
|
||||
return \call_user_func($this->errorHandler, $errno, $errstr, $errfile, $errline);
|
||||
}
|
||||
@@ -347,57 +359,183 @@ class Debugger
|
||||
return true;
|
||||
}
|
||||
|
||||
$backtrace = debug_backtrace(false);
|
||||
// Figure out error scope from the error.
|
||||
$scope = 'unknown';
|
||||
if (stripos($errstr, 'grav') !== false) {
|
||||
$scope = 'grav';
|
||||
} elseif (strpos($errfile, '/twig/') !== false) {
|
||||
$scope = 'twig';
|
||||
} elseif (stripos($errfile, '/yaml/') !== false) {
|
||||
$scope = 'yaml';
|
||||
} elseif (strpos($errfile, '/vendor/') !== false) {
|
||||
$scope = 'vendor';
|
||||
}
|
||||
|
||||
// Clean up backtrace to make it more useful.
|
||||
$backtrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT);
|
||||
|
||||
// Skip current call.
|
||||
array_shift($backtrace);
|
||||
|
||||
// Find yaml file where the error happened.
|
||||
if ($scope === 'yaml') {
|
||||
foreach ($backtrace as $current) {
|
||||
if (isset($current['args'])) {
|
||||
foreach ($current['args'] as $arg) {
|
||||
if ($arg instanceof \SplFileInfo) {
|
||||
$arg = $arg->getPathname();
|
||||
}
|
||||
if (\is_string($arg) && preg_match('/.+\.(yaml|md)$/i', $arg)) {
|
||||
$errfile = $arg;
|
||||
$errline = 0;
|
||||
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter arguments.
|
||||
$cut = 0;
|
||||
$previous = null;
|
||||
foreach ($backtrace as $i => &$current) {
|
||||
if (isset($current['args'])) {
|
||||
$args = [];
|
||||
foreach ($current['args'] as $arg) {
|
||||
if (\is_string($arg)) {
|
||||
$arg = "'" . $arg . "'";
|
||||
if (mb_strlen($arg) > 100) {
|
||||
$arg = 'string';
|
||||
}
|
||||
} elseif (\is_bool($arg)) {
|
||||
$arg = $arg ? 'true' : 'false';
|
||||
} elseif (\is_scalar($arg)) {
|
||||
$arg = $arg;
|
||||
} elseif (\is_object($arg)) {
|
||||
$arg = get_class($arg) . ' $object';
|
||||
} elseif (\is_array($arg)) {
|
||||
$arg = '$array';
|
||||
} else {
|
||||
$arg = '$object';
|
||||
}
|
||||
|
||||
$args[] = $arg;
|
||||
}
|
||||
$current['args'] = $args;
|
||||
}
|
||||
|
||||
$object = $current['object'] ?? null;
|
||||
unset($current['object']);
|
||||
|
||||
$reflection = null;
|
||||
if ($object instanceof TemplateWrapper) {
|
||||
$reflection = new \ReflectionObject($object);
|
||||
$property = $reflection->getProperty('template');
|
||||
$property->setAccessible(true);
|
||||
$object = $property->getValue($object);
|
||||
}
|
||||
|
||||
if ($object instanceof Template) {
|
||||
$file = $current['file'] ?? null;
|
||||
|
||||
if (preg_match('`(Template.php|TemplateWrapper.php)$`', $file)) {
|
||||
$current = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
$debugInfo = $object->getDebugInfo();
|
||||
|
||||
$line = 1;
|
||||
if (!$reflection) {
|
||||
foreach ($debugInfo as $codeLine => $templateLine) {
|
||||
if ($codeLine <= $current['line']) {
|
||||
$line = $templateLine;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$src = $object->getSourceContext();
|
||||
//$code = preg_split('/\r\n|\r|\n/', $src->getCode());
|
||||
//$current['twig']['twig'] = trim($code[$line - 1]);
|
||||
$current['twig']['file'] = $src->getPath();
|
||||
$current['twig']['line'] = $line;
|
||||
|
||||
$prevFile = $previous['file'] ?? null;
|
||||
if ($prevFile && $file === $prevFile) {
|
||||
$prevLine = $previous['line'];
|
||||
|
||||
$line = 1;
|
||||
foreach ($debugInfo as $codeLine => $templateLine) {
|
||||
if ($codeLine <= $prevLine) {
|
||||
$line = $templateLine;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//$previous['twig']['twig'] = trim($code[$line - 1]);
|
||||
$previous['twig']['file'] = $src->getPath();
|
||||
$previous['twig']['line'] = $line;
|
||||
}
|
||||
|
||||
$cut = $i;
|
||||
} elseif ($object instanceof ProcessorInterface) {
|
||||
$cut = $cut ?: $i;
|
||||
break;
|
||||
}
|
||||
|
||||
$previous = &$backtrace[$i];
|
||||
}
|
||||
unset($current);
|
||||
|
||||
if ($cut) {
|
||||
$backtrace = array_slice($backtrace, 0, $cut + 1);
|
||||
}
|
||||
$backtrace = array_values(array_filter($backtrace));
|
||||
|
||||
// Skip vendor libraries and the method where error was triggered.
|
||||
while ($current = array_shift($backtrace)) {
|
||||
if (isset($current['file']) && strpos($current['file'], 'vendor') !== false) {
|
||||
foreach ($backtrace as $i => $current) {
|
||||
if (!isset($current['file'])) {
|
||||
continue;
|
||||
}
|
||||
if (strpos($current['file'], '/vendor/') !== false) {
|
||||
$cut = $i + 1;
|
||||
continue;
|
||||
}
|
||||
if (isset($current['function']) && ($current['function'] === 'user_error' || $current['function'] === 'trigger_error')) {
|
||||
$current = array_shift($backtrace);
|
||||
$cut = $i + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Add back last call.
|
||||
array_unshift($backtrace, $current);
|
||||
|
||||
// Filter arguments.
|
||||
foreach ($backtrace as &$current) {
|
||||
if (isset($current['args'])) {
|
||||
$args = [];
|
||||
foreach ($current['args'] as $arg) {
|
||||
if (\is_string($arg)) {
|
||||
$args[] = "'" . $arg . "'";
|
||||
} elseif (\is_bool($arg)) {
|
||||
$args[] = $arg ? 'true' : 'false';
|
||||
} elseif (\is_scalar($arg)) {
|
||||
$args[] = $arg;
|
||||
} elseif (\is_object($arg)) {
|
||||
$args[] = get_class($arg) . ' $object';
|
||||
} elseif (\is_array($arg)) {
|
||||
$args[] = '$array';
|
||||
} else {
|
||||
$args[] = '$object';
|
||||
}
|
||||
}
|
||||
$current['args'] = $args;
|
||||
}
|
||||
if ($cut) {
|
||||
$backtrace = array_slice($backtrace, $cut);
|
||||
}
|
||||
unset($current);
|
||||
$backtrace = array_values(array_filter($backtrace));
|
||||
|
||||
$this->deprecations[] = [
|
||||
$current = reset($backtrace);
|
||||
|
||||
// If the issue happened inside twig file, change the file and line to match that file.
|
||||
$file = $current['twig']['file'] ?? '';
|
||||
if ($file) {
|
||||
$errfile = $file;
|
||||
$errline = $current['twig']['line'] ?? 0;
|
||||
}
|
||||
|
||||
$deprecation = [
|
||||
'scope' => $scope,
|
||||
'message' => $errstr,
|
||||
'file' => $errfile,
|
||||
'line' => $errline,
|
||||
'trace' => $backtrace,
|
||||
'count' => 1
|
||||
];
|
||||
|
||||
$this->deprecations[] = $deprecation;
|
||||
|
||||
// Do not pass forward.
|
||||
return true;
|
||||
}
|
||||
@@ -422,38 +560,37 @@ class Debugger
|
||||
|
||||
protected function getDepracatedMessage($deprecated)
|
||||
{
|
||||
$scope = 'unknown';
|
||||
if (stripos($deprecated['message'], 'grav') !== false) {
|
||||
$scope = 'grav';
|
||||
} elseif (!isset($deprecated['file'])) {
|
||||
$scope = 'unknown';
|
||||
} elseif (stripos($deprecated['file'], 'twig') !== false) {
|
||||
$scope = 'twig';
|
||||
} elseif (stripos($deprecated['file'], 'yaml') !== false) {
|
||||
$scope = 'yaml';
|
||||
} elseif (stripos($deprecated['file'], 'vendor') !== false) {
|
||||
$scope = 'vendor';
|
||||
}
|
||||
$scope = $deprecated['scope'];
|
||||
|
||||
$trace = [];
|
||||
foreach ($deprecated['trace'] as $current) {
|
||||
$class = $current['class'] ?? '';
|
||||
$type = $current['type'] ?? '';
|
||||
$function = $this->getFunction($current);
|
||||
if (isset($current['file'])) {
|
||||
$current['file'] = str_replace(GRAV_ROOT . '/', '', $current['file']);
|
||||
if (isset($deprecated['trace'])) {
|
||||
foreach ($deprecated['trace'] as $current) {
|
||||
$class = $current['class'] ?? '';
|
||||
$type = $current['type'] ?? '';
|
||||
$function = $this->getFunction($current);
|
||||
if (isset($current['file'])) {
|
||||
$current['file'] = str_replace(GRAV_ROOT . '/', '', $current['file']);
|
||||
}
|
||||
|
||||
unset($current['class'], $current['type'], $current['function'], $current['args']);
|
||||
|
||||
if (isset($current['twig'])) {
|
||||
$trace[] = $current['twig'];
|
||||
} else {
|
||||
$trace[] = ['call' => $class . $type . $function] + $current;
|
||||
}
|
||||
}
|
||||
|
||||
unset($current['class'], $current['type'], $current['function'], $current['args']);
|
||||
|
||||
$trace[] = ['call' => $class . $type . $function] + $current;
|
||||
}
|
||||
|
||||
$array = [
|
||||
'message' => $deprecated['message'],
|
||||
'file' => $deprecated['file'],
|
||||
'line' => $deprecated['line'],
|
||||
'trace' => $trace
|
||||
];
|
||||
|
||||
return [
|
||||
[
|
||||
'message' => $deprecated['message'],
|
||||
'trace' => $trace
|
||||
],
|
||||
array_filter($array),
|
||||
$scope
|
||||
];
|
||||
}
|
||||
@@ -464,6 +601,6 @@ class Debugger
|
||||
return '';
|
||||
}
|
||||
|
||||
return $trace['function'] . '(' . implode(', ', $trace['args']) . ')';
|
||||
return $trace['function'] . '(' . implode(', ', $trace['args'] ?? []) . ')';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Errors
|
||||
* @package Grav\Common\Errors
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -18,6 +19,13 @@ class BareHandler extends Handler
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$inspector = $this->getInspector();
|
||||
$code = $inspector->getException()->getCode();
|
||||
if ( ($code >= 400) && ($code < 600) )
|
||||
{
|
||||
$this->getRun()->sendHttpCode($code);
|
||||
}
|
||||
|
||||
return Handler::QUIT;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Errors
|
||||
* @package Grav\Common\Errors
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -17,11 +18,11 @@ class Errors
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
$config = $grav['config']->get('system.errors');
|
||||
$jsonRequest = $_SERVER && isset($_SERVER['HTTP_ACCEPT']) && $_SERVER['HTTP_ACCEPT'] == 'application/json';
|
||||
$jsonRequest = $_SERVER && isset($_SERVER['HTTP_ACCEPT']) && $_SERVER['HTTP_ACCEPT'] === 'application/json';
|
||||
|
||||
// Setup Whoops-based error handler
|
||||
$system = new SystemFacade;
|
||||
$whoops = new \Whoops\Run($system);
|
||||
$whoops = new Whoops\Run($system);
|
||||
|
||||
$verbosity = 1;
|
||||
|
||||
@@ -49,17 +50,8 @@ class Errors
|
||||
break;
|
||||
}
|
||||
|
||||
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 (Whoops\Util\Misc::isAjaxRequest() || $jsonRequest) {
|
||||
$whoops->pushHandler(new Whoops\Handler\JsonResponseHandler);
|
||||
}
|
||||
|
||||
if (isset($config['log']) && $config['log']) {
|
||||
@@ -70,7 +62,7 @@ class Errors
|
||||
} catch (\Exception $e) {
|
||||
echo $e;
|
||||
}
|
||||
}, 'log');
|
||||
});
|
||||
}
|
||||
|
||||
$whoops->register();
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Errors
|
||||
* @package Grav\Common\Errors
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -20,7 +21,7 @@ class SimplePageHandler extends Handler
|
||||
public function __construct()
|
||||
{
|
||||
// Add the default, local resource search path:
|
||||
$this->searchPaths[] = __DIR__ . "/Resources";
|
||||
$this->searchPaths[] = __DIR__ . '/Resources';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -31,10 +32,14 @@ class SimplePageHandler extends Handler
|
||||
$inspector = $this->getInspector();
|
||||
|
||||
$helper = new TemplateHelper();
|
||||
$templateFile = $this->getResource("layout.html.php");
|
||||
$cssFile = $this->getResource("error.css");
|
||||
$templateFile = $this->getResource('layout.html.php');
|
||||
$cssFile = $this->getResource('error.css');
|
||||
|
||||
$code = $inspector->getException()->getCode();
|
||||
if ( ($code >= 400) && ($code < 600) )
|
||||
{
|
||||
$this->getRun()->sendHttpCode($code);
|
||||
}
|
||||
$message = $inspector->getException()->getMessage();
|
||||
|
||||
if ($inspector->getException() instanceof \ErrorException) {
|
||||
@@ -42,9 +47,9 @@ class SimplePageHandler extends Handler
|
||||
}
|
||||
|
||||
$vars = array(
|
||||
"stylesheet" => file_get_contents($cssFile),
|
||||
"code" => $code,
|
||||
"message" => filter_var(rawurldecode($message), FILTER_SANITIZE_STRING),
|
||||
'stylesheet' => file_get_contents($cssFile),
|
||||
'code' => $code,
|
||||
'message' => filter_var(rawurldecode($message), FILTER_SANITIZE_STRING),
|
||||
);
|
||||
|
||||
$helper->setVariables($vars);
|
||||
@@ -54,7 +59,7 @@ class SimplePageHandler extends Handler
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $resource
|
||||
* @param string $resource
|
||||
*
|
||||
* @return string
|
||||
* @throws \RuntimeException
|
||||
@@ -70,7 +75,7 @@ class SimplePageHandler extends Handler
|
||||
// Search through available search paths, until we find the
|
||||
// resource we're after:
|
||||
foreach ($this->searchPaths as $path) {
|
||||
$fullPath = $path . "/$resource";
|
||||
$fullPath = "{$path}/{$resource}";
|
||||
|
||||
if (is_file($fullPath)) {
|
||||
// Cache the result:
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.Errors
|
||||
* @package Grav\Common\Errors
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.File
|
||||
* @package Grav\Common\File
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -82,4 +83,28 @@ trait CompiledFile
|
||||
|
||||
return parent::content($var);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize file.
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
return [
|
||||
'filename',
|
||||
'extension',
|
||||
'raw',
|
||||
'content',
|
||||
'settings'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Unserialize file.
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
if (!isset(static::$instances[$this->filename])) {
|
||||
static::$instances[$this->filename] = $this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.File
|
||||
* @package Grav\Common\File
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -23,6 +24,6 @@ class CompiledJsonFile extends JsonFile
|
||||
*/
|
||||
protected function decode($var, $assoc = true)
|
||||
{
|
||||
return (array) json_decode($var, $assoc);
|
||||
return (array)json_decode($var, $assoc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.File
|
||||
* @package Grav\Common\File
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.File
|
||||
* @package Grav\Common\File
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.FileSystem
|
||||
* @package Grav\Common\Filesystem
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Common\Filesystem;
|
||||
|
||||
use Grav\Common\Utils;
|
||||
|
||||
abstract class Archiver
|
||||
{
|
||||
protected $options = [
|
||||
@@ -19,11 +22,11 @@ abstract class Archiver
|
||||
|
||||
public static function create($compression)
|
||||
{
|
||||
if ($compression == 'zip') {
|
||||
return new ZipArchiver();
|
||||
} else {
|
||||
if ($compression === 'zip') {
|
||||
return new ZipArchiver();
|
||||
}
|
||||
|
||||
return new ZipArchiver();
|
||||
}
|
||||
|
||||
public function setArchive($archive_file)
|
||||
@@ -34,6 +37,11 @@ abstract class Archiver
|
||||
|
||||
public function setOptions($options)
|
||||
{
|
||||
// Set infinite PHP execution time if possible.
|
||||
if (function_exists('set_time_limit') && !Utils::isFunctionDisabled('set_time_limit')) {
|
||||
set_time_limit(0);
|
||||
}
|
||||
|
||||
$this->options = $options + $this->options;
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.FileSystem
|
||||
* @package Grav\Common\Filesystem
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -21,6 +22,10 @@ abstract class Folder
|
||||
*/
|
||||
public static function lastModifiedFolder($path)
|
||||
{
|
||||
if (!file_exists($path)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$last_modified = 0;
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
@@ -48,13 +53,17 @@ abstract class Folder
|
||||
/**
|
||||
* Recursively find the last modified time under given path by file.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $path
|
||||
* @param string $extensions which files to search for specifically
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function lastModifiedFile($path, $extensions = 'md|yaml')
|
||||
{
|
||||
if (!file_exists($path)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$last_modified = 0;
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
@@ -86,26 +95,29 @@ abstract class Folder
|
||||
/**
|
||||
* Recursively md5 hash all files in a path
|
||||
*
|
||||
* @param $path
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
public static function hashAllFiles($path)
|
||||
{
|
||||
$flags = \RecursiveDirectoryIterator::SKIP_DOTS;
|
||||
$files = [];
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
if ($locator->isStream($path)) {
|
||||
$directory = $locator->getRecursiveIterator($path, $flags);
|
||||
} else {
|
||||
$directory = new \RecursiveDirectoryIterator($path, $flags);
|
||||
}
|
||||
if (file_exists($path)) {
|
||||
$flags = \RecursiveDirectoryIterator::SKIP_DOTS;
|
||||
|
||||
$iterator = new \RecursiveIteratorIterator($directory, \RecursiveIteratorIterator::SELF_FIRST);
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
if ($locator->isStream($path)) {
|
||||
$directory = $locator->getRecursiveIterator($path, $flags);
|
||||
} else {
|
||||
$directory = new \RecursiveDirectoryIterator($path, $flags);
|
||||
}
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
$files[] = $file->getPathname() . '?'. $file->getMTime();
|
||||
$iterator = new \RecursiveIteratorIterator($directory, \RecursiveIteratorIterator::SELF_FIRST);
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
$files[] = $file->getPathname() . '?'. $file->getMTime();
|
||||
}
|
||||
}
|
||||
|
||||
return md5(serialize($files));
|
||||
@@ -141,6 +153,7 @@ abstract class Folder
|
||||
*/
|
||||
public static function getRelativePathDotDot($path, $base)
|
||||
{
|
||||
// Normalize paths.
|
||||
$base = preg_replace('![\\\/]+!', '/', $base);
|
||||
$path = preg_replace('![\\\/]+!', '/', $path);
|
||||
|
||||
@@ -148,8 +161,8 @@ abstract class Folder
|
||||
return '';
|
||||
}
|
||||
|
||||
$baseParts = explode('/', isset($base[0]) && '/' === $base[0] ? substr($base, 1) : $base);
|
||||
$pathParts = explode('/', isset($path[0]) && '/' === $path[0] ? substr($path, 1) : $path);
|
||||
$baseParts = explode('/', ltrim($base, '/'));
|
||||
$pathParts = explode('/', ltrim($path, '/'));
|
||||
|
||||
array_pop($baseParts);
|
||||
$lastPart = array_pop($pathParts);
|
||||
@@ -164,7 +177,7 @@ abstract class Folder
|
||||
$path = str_repeat('../', count($baseParts)) . implode('/', $pathParts);
|
||||
|
||||
return '' === $path
|
||||
|| '/' === $path[0]
|
||||
|| strpos($path, '/') === 0
|
||||
|| false !== ($colonPos = strpos($path, ':')) && ($colonPos < ($slashPos = strpos($path, '/')) || false === $slashPos)
|
||||
? "./$path" : $path;
|
||||
}
|
||||
@@ -197,16 +210,19 @@ abstract class Folder
|
||||
if ($path === false) {
|
||||
throw new \RuntimeException("Path doesn't exist.");
|
||||
}
|
||||
if (!file_exists($path)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$compare = isset($params['compare']) ? 'get' . $params['compare'] : null;
|
||||
$pattern = isset($params['pattern']) ? $params['pattern'] : null;
|
||||
$filters = isset($params['filters']) ? $params['filters'] : null;
|
||||
$recursive = isset($params['recursive']) ? $params['recursive'] : true;
|
||||
$levels = isset($params['levels']) ? $params['levels'] : -1;
|
||||
$pattern = $params['pattern'] ?? null;
|
||||
$filters = $params['filters'] ?? null;
|
||||
$recursive = $params['recursive'] ?? true;
|
||||
$levels = $params['levels'] ?? -1;
|
||||
$key = isset($params['key']) ? 'get' . $params['key'] : null;
|
||||
$value = isset($params['value']) ? 'get' . $params['value'] : ($recursive ? 'getSubPathname' : 'getFilename');
|
||||
$folders = isset($params['folders']) ? $params['folders'] : true;
|
||||
$files = isset($params['files']) ? $params['files'] : true;
|
||||
$value = 'get' . ($params['value'] ?? ($recursive ? 'SubPathname' : 'Filename'));
|
||||
$folders = $params['folders'] ?? true;
|
||||
$files = $params['files'] ?? true;
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
@@ -233,7 +249,7 @@ abstract class Folder
|
||||
/** @var \RecursiveDirectoryIterator $file */
|
||||
foreach ($iterator as $file) {
|
||||
// Ignore hidden files.
|
||||
if ($file->getFilename()[0] === '.') {
|
||||
if (strpos($file->getFilename(), '.') === 0 && $file->isFile()) {
|
||||
continue;
|
||||
}
|
||||
if (!$folders && $file->isDir()) {
|
||||
@@ -255,7 +271,7 @@ abstract class Folder
|
||||
if (isset($filters['value'])) {
|
||||
$filter = $filters['value'];
|
||||
if (is_callable($filter)) {
|
||||
$filePath = call_user_func($filter, $file);
|
||||
$filePath = $filter($file);
|
||||
} else {
|
||||
$filePath = preg_replace($filter, '', $filePath);
|
||||
}
|
||||
@@ -316,7 +332,7 @@ abstract class Folder
|
||||
|
||||
if (!$success) {
|
||||
$error = error_get_last();
|
||||
throw new \RuntimeException($error['message']);
|
||||
throw new \RuntimeException($error['message'] ?? 'Unknown error');
|
||||
}
|
||||
|
||||
// Make sure that the change will be detected when caching.
|
||||
@@ -416,23 +432,27 @@ abstract class Folder
|
||||
*/
|
||||
public static function create($folder)
|
||||
{
|
||||
if (is_dir($folder)) {
|
||||
// Silence error for open_basedir; should fail in mkdir instead.
|
||||
if (@is_dir($folder)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$success = @mkdir($folder, 0777, true);
|
||||
|
||||
if (!$success) {
|
||||
$error = error_get_last();
|
||||
throw new \RuntimeException($error['message']);
|
||||
// Take yet another look, make sure that the folder doesn't exist.
|
||||
clearstatcache(true, $folder);
|
||||
if (!@is_dir($folder)) {
|
||||
throw new \RuntimeException(sprintf('Unable to create directory: %s', $folder));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive copy of one directory to another
|
||||
*
|
||||
* @param $src
|
||||
* @param $dest
|
||||
* @param string $src
|
||||
* @param string $dest
|
||||
*
|
||||
* @return bool
|
||||
* @throws \RuntimeException
|
||||
@@ -448,7 +468,7 @@ abstract class Folder
|
||||
|
||||
// If the destination directory does not exist create it
|
||||
if (!is_dir($dest)) {
|
||||
static::mkdir($dest);
|
||||
static::create($dest);
|
||||
}
|
||||
|
||||
// Open the source directory to read in files
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.FileSystem
|
||||
* @package Grav\Common\Filesystem
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -38,7 +39,7 @@ class RecursiveDirectoryFilterIterator extends \RecursiveFilterIterator
|
||||
*/
|
||||
public function accept()
|
||||
{
|
||||
/** @var $file \SplFileInfo */
|
||||
/** @var \SplFileInfo $file */
|
||||
$file = $this->current();
|
||||
$filename = $file->getFilename();
|
||||
$relative_filename = str_replace($this::$root . '/', '', $file->getPathname());
|
||||
@@ -56,7 +57,11 @@ class RecursiveDirectoryFilterIterator extends \RecursiveFilterIterator
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getChildren() {
|
||||
return new self($this->getInnerIterator()->getChildren(), $this::$root, $this::$ignore_folders, $this::$ignore_files);
|
||||
public function getChildren()
|
||||
{
|
||||
/** @var RecursiveDirectoryFilterIterator $iterator */
|
||||
$iterator = $this->getInnerIterator();
|
||||
|
||||
return new self($iterator->getChildren(), $this::$root, $this::$ignore_folders, $this::$ignore_files);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav.Common.FileSystem
|
||||
* @package Grav\Common\Filesystem
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -38,12 +39,9 @@ class RecursiveFolderFilterIterator extends \RecursiveFilterIterator
|
||||
*/
|
||||
public function accept()
|
||||
{
|
||||
/** @var $current \SplFileInfo */
|
||||
/** @var \SplFileInfo $current */
|
||||
$current = $this->current();
|
||||
|
||||
if ($current->isDir() && !in_array($current->getFilename(), $this::$ignore_folders, true)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return $current->isDir() && !in_array($current->getFilename(), $this::$ignore_folders, true);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user