mirror of
https://framagit.org/hubzilla/core.git
synced 2026-06-21 09:01:15 -04:00
Compare commits
607 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8aee932525 | ||
|
|
8b737e9610 | ||
|
|
0b16a5531a | ||
|
|
b7fbd0ee50 | ||
|
|
2afdb7854b | ||
|
|
1bd784cf12 | ||
|
|
17fa2d8801 | ||
|
|
b89c869e7c | ||
|
|
1a506ad49c | ||
|
|
b0d3c17f19 | ||
|
|
f4507d878d | ||
|
|
d4ef3c183c | ||
|
|
5c3b06b8a9 | ||
|
|
15d9bf4ebe | ||
|
|
6dd4e9ac60 | ||
|
|
2b0c2891e3 | ||
|
|
fbb357ac47 | ||
|
|
38de583db0 | ||
|
|
055ee75302 | ||
|
|
f95011a565 | ||
|
|
6bb5ea7a81 | ||
|
|
efcde8f3dd | ||
|
|
057266653b | ||
|
|
2755c74c29 | ||
|
|
5ad5afe63b | ||
|
|
2c3843ee4c | ||
|
|
e5d1dd111e | ||
|
|
125713e938 | ||
|
|
e128ff4e8f | ||
|
|
2c8a82713e | ||
|
|
7d2a17ea6e | ||
|
|
91b8c769bd | ||
|
|
0637a71669 | ||
|
|
45dc995967 | ||
|
|
d8240a40b7 | ||
|
|
adf34fb201 | ||
|
|
82e867a9a8 | ||
|
|
7a557d31e0 | ||
|
|
de12503fad | ||
|
|
5238a27ab3 | ||
|
|
12162f53b4 | ||
|
|
ec3ca11d0d | ||
|
|
07dca90352 | ||
|
|
3338f3c5b2 | ||
|
|
de455e4cd0 | ||
|
|
5243dd153b | ||
|
|
e1659b0725 | ||
|
|
89c026924b | ||
|
|
4f0b138692 | ||
|
|
b6db0f72f5 | ||
|
|
9068ae68ad | ||
|
|
1bff63bd2e | ||
|
|
531baa8fc4 | ||
|
|
e67f5bc6bb | ||
|
|
316b090433 | ||
|
|
b2298d44a4 | ||
|
|
c029839971 | ||
|
|
e7e73e6fd1 | ||
|
|
bed0a5773f | ||
|
|
53a2262fef | ||
|
|
709206accd | ||
|
|
eeabf514ea | ||
|
|
faf1045ef5 | ||
|
|
6a82ff871f | ||
|
|
7e5428c697 | ||
|
|
036b72757c | ||
|
|
120e9a1e4c | ||
|
|
b49cfb2efd | ||
|
|
0340160ba7 | ||
|
|
4ede3fd771 | ||
|
|
3783c1af3e | ||
|
|
51c610de73 | ||
|
|
92862f93f3 | ||
|
|
05a9f0aa14 | ||
|
|
64810405ef | ||
|
|
382ce4cc61 | ||
|
|
178c983871 | ||
|
|
908e15bc90 | ||
|
|
df27a48e72 | ||
|
|
b959641ca8 | ||
|
|
c50bfa07ca | ||
|
|
416adeb169 | ||
|
|
61f591cc88 | ||
|
|
8f2106da2b | ||
|
|
1e988b1fea | ||
|
|
0febfce268 | ||
|
|
c4fd0af16d | ||
|
|
69354e808f | ||
|
|
3a7d3e3a54 | ||
|
|
4c76b31684 | ||
|
|
3d0c90cbc5 | ||
|
|
9b9621e10d | ||
|
|
86eb923f29 | ||
|
|
14ca376902 | ||
|
|
77a9be845d | ||
|
|
9dd9e27fa8 | ||
|
|
74c68f09e5 | ||
|
|
b60e36ea7a | ||
|
|
fae7993f93 | ||
|
|
215659a234 | ||
|
|
99afd0a449 | ||
|
|
c0e0379bab | ||
|
|
c761531947 | ||
|
|
42b718b3e0 | ||
|
|
1e3a645abe | ||
|
|
7c47557554 | ||
|
|
da9b6690e5 | ||
|
|
32366284a8 | ||
|
|
f17f51a9c1 | ||
|
|
d858bd9265 | ||
|
|
287e9c8d68 | ||
|
|
5e5ec5a66a | ||
|
|
ae5c10a71c | ||
|
|
4d5202353f | ||
|
|
142bcd6806 | ||
|
|
7075697f60 | ||
|
|
3a320462fa | ||
|
|
856133b07d | ||
|
|
0b2d809309 | ||
|
|
ec383aca03 | ||
|
|
8925e0c6c9 | ||
|
|
bc74425872 | ||
|
|
b15a53b672 | ||
|
|
ed7e4df014 | ||
|
|
3bf2935ee3 | ||
|
|
35f17acb38 | ||
|
|
58cf5f310d | ||
|
|
2d916b531b | ||
|
|
12952c9821 | ||
|
|
4ce8f965aa | ||
|
|
47e1c4e059 | ||
|
|
47119ddc7d | ||
|
|
500ee4c1bf | ||
|
|
fc105cf141 | ||
|
|
18f0961caa | ||
|
|
e65949f594 | ||
|
|
b05c1a9829 | ||
|
|
9fa3956aa8 | ||
|
|
02fc082e45 | ||
|
|
be1ffca6f4 | ||
|
|
987eb90e18 | ||
|
|
932aeebcf1 | ||
|
|
5f3a8cbe93 | ||
|
|
f808f1601b | ||
|
|
672c3d7c6d | ||
|
|
72479041ae | ||
|
|
e286b510f1 | ||
|
|
315dafbe12 | ||
|
|
80e4338314 | ||
|
|
db176eec40 | ||
|
|
02f88fc7b2 | ||
|
|
56957b60e2 | ||
|
|
7126fd4b31 | ||
|
|
560af7a5b8 | ||
|
|
e38880a686 | ||
|
|
29dd4ad39b | ||
|
|
54ecf0f45f | ||
|
|
6900dd34a4 | ||
|
|
70dae328b5 | ||
|
|
5d4245ff01 | ||
|
|
24d28bc23a | ||
|
|
d786eca126 | ||
|
|
2fb4952137 | ||
|
|
da512cef64 | ||
|
|
f41b037fbe | ||
|
|
0f5f1c98ca | ||
|
|
01338a7610 | ||
|
|
063b4286e7 | ||
|
|
271f85be3b | ||
|
|
b5f2b4af35 | ||
|
|
9967f2ab28 | ||
|
|
52c3960946 | ||
|
|
1b1170bcf6 | ||
|
|
eb03877aa4 | ||
|
|
4c4d185937 | ||
|
|
6998bb1f23 | ||
|
|
3a60bef2b6 | ||
|
|
eb1eb38c01 | ||
|
|
3c5598407e | ||
|
|
4ffc4ee70a | ||
|
|
52db649022 | ||
|
|
38e46fff54 | ||
|
|
744ad84714 | ||
|
|
7d897a3f03 | ||
|
|
79eeeaee95 | ||
|
|
2c1b432613 | ||
|
|
0c3d5e99a2 | ||
|
|
dca8a05026 | ||
|
|
5cfc286972 | ||
|
|
bc46f70a90 | ||
|
|
5a63ddd645 | ||
|
|
8566f91303 | ||
|
|
b63aff77df | ||
|
|
5a1eb65ed6 | ||
|
|
98a2dcad90 | ||
|
|
77a021025f | ||
|
|
63123759ed | ||
|
|
6167291488 | ||
|
|
cf0b1f1f15 | ||
|
|
824dedbe9d | ||
|
|
da707736a0 | ||
|
|
8f57bb95fe | ||
|
|
0c3543ac43 | ||
|
|
d2e5b7cb76 | ||
|
|
6a56a509d3 | ||
|
|
dffa08adcc | ||
|
|
779885f9af | ||
|
|
d504197a78 | ||
|
|
542fcaff9a | ||
|
|
bc8c74eb42 | ||
|
|
3affb2e817 | ||
|
|
df0cd4dbc7 | ||
|
|
d54ad98802 | ||
|
|
1d90c4ea99 | ||
|
|
4da005e209 | ||
|
|
c3149a8d59 | ||
|
|
fd507ff597 | ||
|
|
8c2b93da72 | ||
|
|
ca82b45fe4 | ||
|
|
da49befb18 | ||
|
|
e0d9d30bcf | ||
|
|
99f7dd0fd4 | ||
|
|
0c7ad924a8 | ||
|
|
a3e5307b93 | ||
|
|
ae6256f95a | ||
|
|
a961d5e6c8 | ||
|
|
237cca7a0d | ||
|
|
2c9938f0d5 | ||
|
|
ea83032863 | ||
|
|
6a4573b935 | ||
|
|
9421e42dad | ||
|
|
f4b658d7b1 | ||
|
|
7272b97e9a | ||
|
|
8a9f062b95 | ||
|
|
eac35c05e9 | ||
|
|
07b96f2430 | ||
|
|
269b3cef72 | ||
|
|
99cf2cbaa9 | ||
|
|
b63165b6e0 | ||
|
|
32ce790717 | ||
|
|
b5b57523f1 | ||
|
|
7524948a97 | ||
|
|
f9b67d3630 | ||
|
|
3beb94dc52 | ||
|
|
4371e6ad97 | ||
|
|
f44ca74e99 | ||
|
|
10fa5c20e7 | ||
|
|
f7833411a1 | ||
|
|
de4f9d68bd | ||
|
|
571b8cc85b | ||
|
|
883fc5d753 | ||
|
|
25b2a6e0cf | ||
|
|
4febdc3bcd | ||
|
|
c3617f5d1e | ||
|
|
fc78ba7c2f | ||
|
|
279359c1bd | ||
|
|
dc9fa7cf64 | ||
|
|
d6b28cdc57 | ||
|
|
75fb065526 | ||
|
|
6c5086a933 | ||
|
|
2b674d4cd9 | ||
|
|
5d0ddb3123 | ||
|
|
2d4b75428a | ||
|
|
f39d20ac97 | ||
|
|
db2b6f1268 | ||
|
|
99354ac576 | ||
|
|
e7b8531751 | ||
|
|
ff2f599142 | ||
|
|
f396b1bf73 | ||
|
|
e237dfc660 | ||
|
|
641029ab18 | ||
|
|
065ef29de2 | ||
|
|
aac0fa2b5f | ||
|
|
17edec8e4a | ||
|
|
8e667866fd | ||
|
|
01fe7d6620 | ||
|
|
f3aff45042 | ||
|
|
d6d94d9427 | ||
|
|
acb78205c8 | ||
|
|
dcb3c2c299 | ||
|
|
9048f8cffe | ||
|
|
4a2fb8336e | ||
|
|
34a16e0ab9 | ||
|
|
c2779b6f33 | ||
|
|
2e32b5f467 | ||
|
|
da5ec98f98 | ||
|
|
d54f5a3831 | ||
|
|
5e475acb85 | ||
|
|
f666d8a083 | ||
|
|
7ee7f00bf3 | ||
|
|
397a23499d | ||
|
|
d660bde324 | ||
|
|
94bd53c0f1 | ||
|
|
f70f4a4e85 | ||
|
|
f3eb9af046 | ||
|
|
0edf248cd1 | ||
|
|
514ffb74aa | ||
|
|
e6c8614801 | ||
|
|
05a9f2f0f5 | ||
|
|
115ef3249c | ||
|
|
191cd21028 | ||
|
|
b3a785711c | ||
|
|
503b420292 | ||
|
|
0aa205044b | ||
|
|
00afe56cad | ||
|
|
1fd65c934d | ||
|
|
960e9edff5 | ||
|
|
b72720f6b6 | ||
|
|
f60a0c5ce0 | ||
|
|
ba903e21ed | ||
|
|
75b943b98a | ||
|
|
18565600b2 | ||
|
|
f4e4e734de | ||
|
|
6424bac47c | ||
|
|
bdd7d24ac1 | ||
|
|
5131759823 | ||
|
|
1e4ef81244 | ||
|
|
0fa807e7ad | ||
|
|
b6987b4287 | ||
|
|
ed0e2b52d7 | ||
|
|
168d35747d | ||
|
|
a01baab4f0 | ||
|
|
17c3e12eab | ||
|
|
71b001fdb7 | ||
|
|
833de9180e | ||
|
|
fb36561a68 | ||
|
|
67c60229ca | ||
|
|
f4bcb82041 | ||
|
|
983ccef87c | ||
|
|
a849dcadb6 | ||
|
|
d5afd0d7c2 | ||
|
|
cc83983ae5 | ||
|
|
ba5183b244 | ||
|
|
3d3584b36c | ||
|
|
c5e534c0cb | ||
|
|
a338a97d5b | ||
|
|
e11219888d | ||
|
|
e6638b4715 | ||
|
|
c9db8c6857 | ||
|
|
917a465ccd | ||
|
|
ce5adbf51e | ||
|
|
50e581d88a | ||
|
|
47d7fc70e8 | ||
|
|
e2574cf069 | ||
|
|
ee1ec0428b | ||
|
|
3b17dca252 | ||
|
|
eef40cb3fd | ||
|
|
9f413ed174 | ||
|
|
233cfc29d6 | ||
|
|
e11330a5c8 | ||
|
|
0b2ad9deca | ||
|
|
227320f6f0 | ||
|
|
3bee6543fb | ||
|
|
581a3c5323 | ||
|
|
a59e84cadd | ||
|
|
d4627a0b1c | ||
|
|
08a4763bff | ||
|
|
537f30f707 | ||
|
|
ad954d01de | ||
|
|
e3d70e6b62 | ||
|
|
cbf009a95d | ||
|
|
35cc763a92 | ||
|
|
cf05111622 | ||
|
|
e6224898d2 | ||
|
|
d566ffa678 | ||
|
|
6bf2e8a108 | ||
|
|
805ecde6a5 | ||
|
|
2a26b0ae91 | ||
|
|
916e088462 | ||
|
|
c918bbba25 | ||
|
|
57226b2e13 | ||
|
|
f46eecc1e7 | ||
|
|
5c062aaec4 | ||
|
|
b87106b6fe | ||
|
|
523e7b5084 | ||
|
|
41fa2d6c69 | ||
|
|
5947467339 | ||
|
|
0a11991340 | ||
|
|
0630609d6e | ||
|
|
205924ff29 | ||
|
|
7371e08625 | ||
|
|
bb5ec8cfb8 | ||
|
|
e6c8de5e4c | ||
|
|
bd403276f2 | ||
|
|
7f8dcf4f12 | ||
|
|
eef8f3b417 | ||
|
|
0fd8eeec23 | ||
|
|
7124c0aee5 | ||
|
|
852b2659e9 | ||
|
|
1cc816f662 | ||
|
|
bfe84a9ff7 | ||
|
|
339e620738 | ||
|
|
9ef710c557 | ||
|
|
df4ff26845 | ||
|
|
2e93a09d83 | ||
|
|
05aba0b4dd | ||
|
|
f098600c41 | ||
|
|
ad83825d4f | ||
|
|
3102440d40 | ||
|
|
715b1667d9 | ||
|
|
7d62e087c6 | ||
|
|
dcc65bbacb | ||
|
|
feaad50b6c | ||
|
|
7b2d54dffa | ||
|
|
e170217c33 | ||
|
|
aff58934c0 | ||
|
|
9f576369a9 | ||
|
|
7d7f43c205 | ||
|
|
30a5fe3061 | ||
|
|
b155e93ab1 | ||
|
|
3704ff57cb | ||
|
|
ee1d527497 | ||
|
|
f40f7b4d6e | ||
|
|
911510f999 | ||
|
|
45f5ac560d | ||
|
|
fe7020e2f8 | ||
|
|
17e161006a | ||
|
|
85d2ad4aea | ||
|
|
5b9cd0af64 | ||
|
|
8d298d5a06 | ||
|
|
3035c792dc | ||
|
|
2029b2b9ed | ||
|
|
900d8f3b0a | ||
|
|
e2de2f65d5 | ||
|
|
81da9f99e4 | ||
|
|
216f034b6d | ||
|
|
b96edd8b9a | ||
|
|
27ee95106d | ||
|
|
dac3138fd1 | ||
|
|
e0a7637626 | ||
|
|
8c4481733f | ||
|
|
d20e62dcd3 | ||
|
|
7805a3c527 | ||
|
|
0df3978cc5 | ||
|
|
bd4a88cd3e | ||
|
|
2dc1236dca | ||
|
|
2528d97f52 | ||
|
|
241b257556 | ||
|
|
83a42afddf | ||
|
|
780f83a118 | ||
|
|
ec3651d216 | ||
|
|
6154fc7686 | ||
|
|
1924459abd | ||
|
|
f66576f366 | ||
|
|
7470fc7f24 | ||
|
|
0e041a3b64 | ||
|
|
c8ae04a96a | ||
|
|
c809b6f95e | ||
|
|
1577efa25e | ||
|
|
fb93ae2128 | ||
|
|
25c9e9ef93 | ||
|
|
812dc9e898 | ||
|
|
bf4b698573 | ||
|
|
5162c55e5d | ||
|
|
096619dbbe | ||
|
|
fa02a09107 | ||
|
|
51e2ef39c2 | ||
|
|
b19bbf5473 | ||
|
|
e5c66d94f2 | ||
|
|
2a32713dfc | ||
|
|
acf26d5c63 | ||
|
|
39b14b6b81 | ||
|
|
ac81a3a5ef | ||
|
|
ab628eb2a3 | ||
|
|
b8c5a91940 | ||
|
|
f7d2c99a3a | ||
|
|
32408ed6a3 | ||
|
|
515b054a6e | ||
|
|
cef77ce5bb | ||
|
|
1267d995ef | ||
|
|
ec8091a102 | ||
|
|
5536df51f5 | ||
|
|
f48b12ff52 | ||
|
|
415a8d1e01 | ||
|
|
2a840460dd | ||
|
|
12f114c4be | ||
|
|
b593c3a9b9 | ||
|
|
8fa26db1b3 | ||
|
|
ecae0b3d97 | ||
|
|
63423c8ee1 | ||
|
|
ed16660867 | ||
|
|
9c9d6363af | ||
|
|
3a43b1d85d | ||
|
|
76f07a7f97 | ||
|
|
4d219df04e | ||
|
|
01bfadaeaa | ||
|
|
670d12219b | ||
|
|
da2c0a22f9 | ||
|
|
953ac6f3c7 | ||
|
|
545219b839 | ||
|
|
985fb44424 | ||
|
|
17c5502330 | ||
|
|
aa88837a31 | ||
|
|
a3ec9f3940 | ||
|
|
8cd9a1e4fc | ||
|
|
f4d9d34bbc | ||
|
|
20b4fc9198 | ||
|
|
e40112b40d | ||
|
|
cc09f9a7a5 | ||
|
|
4b505948f0 | ||
|
|
3cf6f1f79c | ||
|
|
905374c86e | ||
|
|
30841d9470 | ||
|
|
7a4efcf67f | ||
|
|
6e0eb532a5 | ||
|
|
b6324246ff | ||
|
|
76e11b46b7 | ||
|
|
3dad4a9ff1 | ||
|
|
dbb0a0283f | ||
|
|
178b440f05 | ||
|
|
755dd67ec7 | ||
|
|
2e7606f569 | ||
|
|
c81f6b9f6f | ||
|
|
d0f0a99909 | ||
|
|
2793086c0d | ||
|
|
80d3a831f3 | ||
|
|
961539258b | ||
|
|
9749bbcedc | ||
|
|
aa5ac9dc3f | ||
|
|
0324bc5cf0 | ||
|
|
f6d7628254 | ||
|
|
e5f4d80bbe | ||
|
|
aa77b04860 | ||
|
|
5b479d63d6 | ||
|
|
8924f94d05 | ||
|
|
a873b7b6e8 | ||
|
|
7baa20d559 | ||
|
|
2b7f114c2d | ||
|
|
951bf5ec2e | ||
|
|
28a7458e48 | ||
|
|
a2a87fec54 | ||
|
|
d457f11717 | ||
|
|
bc5f73e6c3 | ||
|
|
1dc35db1fe | ||
|
|
427badcae9 | ||
|
|
e0b705fd54 | ||
|
|
854c23a751 | ||
|
|
fa48de33c2 | ||
|
|
fc7c4e64ff | ||
|
|
476116a972 | ||
|
|
f2dda646ec | ||
|
|
05ed20d336 | ||
|
|
47fc0c7958 | ||
|
|
688171d016 | ||
|
|
9a0dff08bc | ||
|
|
77dedf6648 | ||
|
|
212d8b6cfd | ||
|
|
9eb23a1208 | ||
|
|
ccfd028919 | ||
|
|
e5a919c32e | ||
|
|
eeaafe9f39 | ||
|
|
6430a232f8 | ||
|
|
24569a18db | ||
|
|
5c458e9111 | ||
|
|
0ef2622621 | ||
|
|
1ff9abe1b4 | ||
|
|
8e5948716e | ||
|
|
1e68d4fb75 | ||
|
|
1bec739195 | ||
|
|
025a7d2f0f | ||
|
|
ebf238be5d | ||
|
|
98484f0def | ||
|
|
892f061ad6 | ||
|
|
8bfb620a13 | ||
|
|
b6d425838f | ||
|
|
e963714ad6 | ||
|
|
6d4188f05e | ||
|
|
3e804757c1 | ||
|
|
cc43a49b6d | ||
|
|
b18b9464a4 | ||
|
|
71d4f65cb2 | ||
|
|
b5933e9d44 | ||
|
|
81b3c59711 | ||
|
|
410f5389ae | ||
|
|
a1183bf09a | ||
|
|
43055e0199 | ||
|
|
1789c3242a | ||
|
|
f41380de77 | ||
|
|
0e0a6f5f8d | ||
|
|
ef95c68b4f | ||
|
|
bdbbe00bdf | ||
|
|
86985b454f | ||
|
|
9d5d3a9468 | ||
|
|
7fc2b13fe6 | ||
|
|
d5d5d78e3a | ||
|
|
85e82e919e | ||
|
|
9b96fe66a6 | ||
|
|
11045b92fb | ||
|
|
4234c9a194 | ||
|
|
75b97cafb0 | ||
|
|
655290b022 | ||
|
|
b886a40471 | ||
|
|
cfbd2fc85c | ||
|
|
25aded6b9b | ||
|
|
8d6c2b5d4a | ||
|
|
7582802f03 | ||
|
|
f23bdde464 | ||
|
|
b4eb9f2a11 | ||
|
|
c1039977f1 | ||
|
|
380f65d309 | ||
|
|
316fee93f7 | ||
|
|
1523e116b9 | ||
|
|
90f2959076 | ||
|
|
6d4adfcedc | ||
|
|
cac6cef495 | ||
|
|
aab9766c53 | ||
|
|
66effbfe08 |
@@ -27,9 +27,9 @@ Software
|
||||
+ Register your own domain (for example at selfHOST) or a free subdomain (for example at freeDNS)
|
||||
+ Log on to your new debian (server)
|
||||
- apt-get install git
|
||||
- mkdir -p /var/www/html
|
||||
- cd /var/www/html
|
||||
- git clone https://github.com/redmatrix/hubzilla.git .
|
||||
- mkdir -p /var/www
|
||||
- cd /var/www
|
||||
- git clone https://github.com/redmatrix/hubzilla.git html
|
||||
- cp .homeinstall/hubzilla-config.txt.template .homeinstall/hubzilla-config.txt
|
||||
- nano .homeinstall/hubzilla-config.txt
|
||||
- Enter your values there: db pass, domain, values for dyn DNS
|
||||
|
||||
@@ -513,7 +513,7 @@ END
|
||||
fi
|
||||
# run letsencrypt.sh
|
||||
#
|
||||
./letsencrypt.sh --cron
|
||||
./letsencrypt.sh --cron --config $le_dir/config.sh
|
||||
}
|
||||
|
||||
function configure_apache_for_https {
|
||||
@@ -668,45 +668,6 @@ function rewrite_to_https {
|
||||
service apache2 restart
|
||||
}
|
||||
|
||||
|
||||
function install_owncloud {
|
||||
if [ -z "$owncloud" ]
|
||||
then
|
||||
print_info "Do not install owncloud"
|
||||
return 0
|
||||
fi
|
||||
if [ -f /etc/apt/sources.list.d/owncloud.list ]
|
||||
then
|
||||
print_info "owncloud is already installed and is left untouched"
|
||||
return 0
|
||||
fi
|
||||
print_info "installing owncloud..."
|
||||
# add the repository key to apt
|
||||
wget -nv https://download.owncloud.org/download/repositories/stable/Debian_8.0/Release.key -O Release.key
|
||||
apt-key add - < Release.key
|
||||
# add the repository and install from there
|
||||
sh -c "echo 'deb http://download.owncloud.org/download/repositories/stable/Debian_8.0/ /' >> /etc/apt/sources.list.d/owncloud.list"
|
||||
apt-get update
|
||||
nocheck_install "owncloud"
|
||||
chown -R www-data:www-data /var/www/owncloud/
|
||||
# set strong permissions
|
||||
ocpath='/var/www/owncloud'
|
||||
htuser='www-data'
|
||||
htgroup='www-data'
|
||||
rootuser='root' # On QNAP this is admin
|
||||
find ${ocpath}/ -type f -print0 | xargs -0 chmod 0640
|
||||
find ${ocpath}/ -type d -print0 | xargs -0 chmod 0750
|
||||
chown -R ${rootuser}:${htgroup} ${ocpath}/
|
||||
chown -R ${htuser}:${htgroup} ${ocpath}/apps/
|
||||
chown -R ${htuser}:${htgroup} ${ocpath}/config/
|
||||
chown -R ${htuser}:${htgroup} ${ocpath}/data/
|
||||
chown -R ${htuser}:${htgroup} ${ocpath}/themes/
|
||||
chown ${rootuser}:${htgroup} ${ocpath}/.htaccess
|
||||
chown ${rootuser}:${htgroup} ${ocpath}/data/.htaccess
|
||||
chmod 0644 ${ocpath}/.htaccess
|
||||
chmod 0644 ${ocpath}/data/.htaccess
|
||||
}
|
||||
|
||||
# This will allways overwrite both config files
|
||||
# - internal disk
|
||||
# - external disk (LUKS + ext4)
|
||||
@@ -769,11 +730,11 @@ echo "#" >> /var/www/$hubzilladaily
|
||||
echo "echo \" \"" >> /var/www/$hubzilladaily
|
||||
echo "echo \"+++ \$(date) +++\"" >> /var/www/$hubzilladaily
|
||||
echo "echo \" \"" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - renew certificat if 30 days old...\"" >> /var/www/$hubzilladaily
|
||||
echo "bash /var/www/letsencrypt/letsencrypt.sh --cron" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - renew certificat...\"" >> /var/www/$hubzilladaily
|
||||
echo "bash $le_dir/letsencrypt.sh --cron --config $le_dir/config.sh" >> /var/www/$hubzilladaily
|
||||
echo "#" >> /var/www/$hubzilladaily
|
||||
echo "# stop hubzilla" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - stoping apaache and mysql...\"" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - stoping apache and mysql...\"" >> /var/www/$hubzilladaily
|
||||
echo "service apache2 stop" >> /var/www/$hubzilladaily
|
||||
echo "/etc/init.d/mysql stop # to avoid inconsistancies" >> /var/www/$hubzilladaily
|
||||
echo "#" >> /var/www/$hubzilladaily
|
||||
@@ -939,7 +900,6 @@ configure_apache_for_https
|
||||
check_https
|
||||
install_hubzilla
|
||||
rewrite_to_https
|
||||
# install_owncloud # deprecated
|
||||
install_rsnapshot
|
||||
configure_cron_daily
|
||||
install_cryptosetup
|
||||
|
||||
66
CHANGELOG
66
CHANGELOG
@@ -1,3 +1,69 @@
|
||||
Hubzilla 1.12
|
||||
- extensible permissions so you can create a new permission rule such as "can write to my wiki" or "can see me naked".
|
||||
- guest access tokens can do anything you let them, including create posts and administer your channel
|
||||
- ACLs can be set on files and directories prior to creation.
|
||||
- ACL tool can now be used in multiple forms within a page
|
||||
- a myriad of new drag/drop features (drop files or photos into /cloud or a post, or drop link into a post or comment, etc.)
|
||||
- multiple file uploads
|
||||
- improvements to website import
|
||||
- UNO replaced with extensible server roles
|
||||
- select bbcode elements (such as baseurl) supported in wiki pages
|
||||
- addons:
|
||||
Diaspora Protocol - additional updates to maintain compatibility with 0.6.0.0 and stop showing likes as wall-to-wall comments (except when the liker does not have any Diaspora protocol ability)
|
||||
Cdav - continued improvements to the web UI
|
||||
Pong - the classic pong game
|
||||
Dfedfix - removed, no longer needed
|
||||
Openid - moved from core to addon
|
||||
- bugfixes
|
||||
unable to delete privacy groups
|
||||
weird display interaction with code blocks and escaped base64 content containing 8 - O
|
||||
workaround WordPress oembeds which are almost completely javascript and therefore filtered
|
||||
restrict oembed cache url to 254 chars to avoid spurious failures caching google map urls
|
||||
"Page not found" appeared twice
|
||||
birthdays weren't being automatically added to event calendar
|
||||
some iCal entries had malformed descriptions
|
||||
|
||||
Hubzilla 1.10
|
||||
Wiki:
|
||||
Lots of enhanced functionality, usability improvements, and bugfixes from v1.8
|
||||
Turned into an optional feature (default on) but disabled in UNO
|
||||
Sync:
|
||||
Items are now relocated (links patched) when syncing to clones
|
||||
Access Tokens:
|
||||
New feature - allows members to create access controlled guest logins and create/share 'dropbox' style links to protected resources.
|
||||
UI:
|
||||
Use icons instead of iconic text constructs
|
||||
Only request geolocation permission when creating a post, not on page load
|
||||
provide 'redeliver' option on Delivery Report page for when things really stuff up
|
||||
CalDAV/CardDAV management pages with heaps of functionality
|
||||
Lib:
|
||||
z_fetch_url() updated to accept different request methods and request bodies
|
||||
item_store(), item_store_update() now return the stored items
|
||||
vcard microformat changes to remain spec compliant
|
||||
microformat meta tags added to post/comments
|
||||
AbConfig API changed to use channel_id rather than channel_hash, which was overly complicated to use
|
||||
SuperCurl class added to provide a framework for re-use of obscure CURL options
|
||||
Allow absolute links to CSS/JS files on CDN
|
||||
Add Let'sEncrypt intermediate cert to lib in case you forget to install it on the server
|
||||
Update fullcalendar and jquery (3.1) libs
|
||||
Update sabre/dav to 3.2.0
|
||||
Change content export from a month/year system to begin/end
|
||||
Use streaming I/O for delivering large photos
|
||||
Allow multiple App description files in a single plugin directory
|
||||
optimise a couple of troublesome/inefficient SQL queries
|
||||
avoid sending clone sync packets to dead sites
|
||||
Resolved Issues:
|
||||
channel home page not providing content to clients with javascript disabled
|
||||
Replace '@' obfuscation with html entity rather than the unicode look-alike
|
||||
xchan_query() failing to detect duplicates, resulting in inefficient queries
|
||||
issues with 'use existing photo' for profile photo
|
||||
layout editor "list all layouts" returned empty
|
||||
oembed - better detect video file URLs so they aren't loaded into memory.
|
||||
handcrafted bbcode tables could end up with way too much whitespace due to CRLF translation
|
||||
refresh permissions whitescreen in 1.8
|
||||
force immediate profile photo update on local site
|
||||
regression: 'save bookmarks' post action missing
|
||||
|
||||
Hubzilla 1.8
|
||||
Administration:
|
||||
Cleanup and resolve some edge cases with addon repository manager
|
||||
|
||||
12
README.md
12
README.md
@@ -47,4 +47,16 @@ Possible website applications include
|
||||
<em><a href="https://github.com/redmatrix/hubzilla/blob/master/install/INSTALL.txt">Installing Hubzilla</a></em>
|
||||
</p>
|
||||
|
||||
**Who Are We and What Are Our Principles?**
|
||||
|
||||
The Hubzilla community is powered by passionate volunteers creating an open source **commons** of decentralised services which are highly integrated and can rival the feature set of centralised providers. We are open to sponsorship and donations to cover expenses and compensate for our time and energy, however the project core is basically non-profit and is not designed for the purpose of commercial gain or exploitation.
|
||||
|
||||
Some sites may include monetisation strategies such as subscriptions and *freemium* models where members pay for resources they consume beyond a basic level. The project community supports such monetisation initiatives (nobody should be forced to pay "out of pocket" to provide a service to others), but we maintain the **commons** to provide open and free access of the software to all.
|
||||
|
||||
The software is not designed for data collection of its members or providing advertising. We don't have a need or desire for these things and feel that software built around these goals is poorly designed and represents compromised principles and ethics.
|
||||
|
||||
As a project, we are inclusive of all beliefs and cultures and do what we are able to provide an environment that is free from hostility and harrassment. Whether or not we succeed in this endaevour requires constant vigilance and help from all members of the community, working together to build an inter-networking tool with amazing potential.
|
||||
|
||||
|
||||
|
||||
[](https://travis-ci.org/redmatrix/hubzilla)
|
||||
|
||||
36
Zotlabs/Access/PermissionLimits.php
Normal file
36
Zotlabs/Access/PermissionLimits.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Access;
|
||||
|
||||
use \Zotlabs\Lib as ZLib;
|
||||
|
||||
class PermissionLimits {
|
||||
|
||||
static public function Std_Limits() {
|
||||
$perms = Permissions::Perms();
|
||||
$limits = array();
|
||||
foreach($perms as $k => $v) {
|
||||
if(strstr($k,'view'))
|
||||
$limits[$k] = PERMS_PUBLIC;
|
||||
else
|
||||
$limits[$k] = PERMS_SPECIFIC;
|
||||
}
|
||||
return $limits;
|
||||
}
|
||||
|
||||
static public function Set($channel_id,$perm,$perm_limit) {
|
||||
ZLib\PConfig::Set($channel_id,'perm_limits',$perm,$perm_limit);
|
||||
}
|
||||
|
||||
static public function Get($channel_id,$perm = '') {
|
||||
if($perm) {
|
||||
return Zlib\PConfig::Get($channel_id,'perm_limits',$perm);
|
||||
}
|
||||
else {
|
||||
Zlib\PConfig::Load($channel_id);
|
||||
if(array_key_exists($channel_id,\App::$config) && array_key_exists('perm_limits',\App::$config[$channel_id]))
|
||||
return \App::$config[$channel_id]['perm_limits'];
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
215
Zotlabs/Access/PermissionRoles.php
Normal file
215
Zotlabs/Access/PermissionRoles.php
Normal file
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Zotlabs\Access;
|
||||
|
||||
use Zotlabs\Lib as Zlib;
|
||||
|
||||
class PermissionRoles {
|
||||
|
||||
|
||||
static function role_perms($role) {
|
||||
|
||||
$ret = array();
|
||||
|
||||
$ret['role'] = $role;
|
||||
|
||||
switch($role) {
|
||||
case 'social':
|
||||
$ret['perms_auto'] = false;
|
||||
$ret['default_collection'] = false;
|
||||
$ret['directory_publish'] = true;
|
||||
$ret['online'] = true;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'send_stream', 'post_wall', 'post_comments',
|
||||
'post_mail', 'chat', 'post_like', 'republish' ];
|
||||
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
break;
|
||||
|
||||
case 'social_restricted':
|
||||
$ret['perms_auto'] = false;
|
||||
$ret['default_collection'] = true;
|
||||
$ret['directory_publish'] = true;
|
||||
$ret['online'] = true;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'send_stream', 'post_wall', 'post_comments',
|
||||
'post_mail', 'chat', 'post_like' ];
|
||||
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
|
||||
break;
|
||||
|
||||
case 'social_private':
|
||||
$ret['perms_auto'] = false;
|
||||
$ret['default_collection'] = true;
|
||||
$ret['directory_publish'] = false;
|
||||
$ret['online'] = false;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'send_stream', 'post_wall', 'post_comments',
|
||||
'post_mail', 'post_like' ];
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
|
||||
$ret['limits']['view_storage'] = PERMS_SPECIFIC;
|
||||
|
||||
break;
|
||||
|
||||
case 'forum':
|
||||
$ret['perms_auto'] = true;
|
||||
$ret['default_collection'] = false;
|
||||
$ret['directory_publish'] = true;
|
||||
$ret['online'] = false;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'post_wall', 'post_comments', 'tag_deliver',
|
||||
'post_mail', 'post_like' , 'republish', 'chat' ];
|
||||
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
break;
|
||||
|
||||
case 'forum_restricted':
|
||||
$ret['perms_auto'] = false;
|
||||
$ret['default_collection'] = true;
|
||||
$ret['directory_publish'] = true;
|
||||
$ret['online'] = false;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'post_wall', 'post_comments', 'tag_deliver',
|
||||
'post_mail', 'post_like' , 'chat' ];
|
||||
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
|
||||
break;
|
||||
|
||||
case 'forum_private':
|
||||
$ret['perms_auto'] = false;
|
||||
$ret['default_collection'] = true;
|
||||
$ret['directory_publish'] = false;
|
||||
$ret['online'] = false;
|
||||
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'post_wall', 'post_comments',
|
||||
'post_mail', 'post_like' , 'chat' ];
|
||||
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
$ret['limits']['view_profile'] = PERMS_SPECIFIC;
|
||||
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
|
||||
$ret['limits']['view_storage'] = PERMS_SPECIFIC;
|
||||
$ret['limits']['view_pages'] = PERMS_SPECIFIC;
|
||||
|
||||
break;
|
||||
|
||||
case 'feed':
|
||||
$ret['perms_auto'] = true;
|
||||
$ret['default_collection'] = false;
|
||||
$ret['directory_publish'] = true;
|
||||
$ret['online'] = false;
|
||||
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'send_stream', 'post_wall', 'post_comments',
|
||||
'post_mail', 'post_like' , 'republish' ];
|
||||
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
|
||||
break;
|
||||
|
||||
case 'feed_restricted':
|
||||
$ret['perms_auto'] = false;
|
||||
$ret['default_collection'] = true;
|
||||
$ret['directory_publish'] = false;
|
||||
$ret['online'] = false;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'send_stream', 'post_wall', 'post_comments',
|
||||
'post_mail', 'post_like' , 'republish' ];
|
||||
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
|
||||
break;
|
||||
|
||||
case 'soapbox':
|
||||
$ret['perms_auto'] = true;
|
||||
$ret['default_collection'] = false;
|
||||
$ret['directory_publish'] = true;
|
||||
$ret['online'] = false;
|
||||
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'post_like' , 'republish' ];
|
||||
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
|
||||
break;
|
||||
|
||||
case 'repository':
|
||||
$ret['perms_auto'] = true;
|
||||
$ret['default_collection'] = false;
|
||||
$ret['directory_publish'] = true;
|
||||
$ret['online'] = false;
|
||||
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'write_storage', 'write_pages', 'post_wall', 'post_comments', 'tag_deliver',
|
||||
'post_mail', 'post_like' , 'republish', 'chat' ];
|
||||
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
$x = get_config('system','role_perms');
|
||||
// let system settings over-ride any or all
|
||||
if($x && is_array($x) && array_key_exists($role,$x))
|
||||
$ret = array_merge($ret,$x[$role]);
|
||||
|
||||
call_hooks('get_role_perms',$ret);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static public function roles() {
|
||||
$roles = [
|
||||
t('Social Networking') => [
|
||||
'social' => t('Social - Mostly Public'),
|
||||
'social_restricted' => t('Social - Restricted'),
|
||||
'social_private' => t('Social - Private')
|
||||
],
|
||||
|
||||
t('Community Forum') => [
|
||||
'forum' => t('Forum - Mostly Public'),
|
||||
'forum_restricted' => t('Forum - Restricted'),
|
||||
'forum_private' => t('Forum - Private')
|
||||
],
|
||||
|
||||
t('Feed Republish') => [
|
||||
'feed' => t('Feed - Mostly Public'),
|
||||
'feed_restricted' => t('Feed - Restricted')
|
||||
],
|
||||
|
||||
t('Special Purpose') => [
|
||||
'soapbox' => t('Special - Celebrity/Soapbox'),
|
||||
'repository' => t('Special - Group Repository')
|
||||
],
|
||||
|
||||
t('Other') => [
|
||||
'custom' => t('Custom/Expert Mode')
|
||||
]
|
||||
|
||||
];
|
||||
|
||||
return $roles;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
116
Zotlabs/Access/Permissions.php
Normal file
116
Zotlabs/Access/Permissions.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Zotlabs\Access;
|
||||
|
||||
use Zotlabs\Lib as Zlib;
|
||||
|
||||
class Permissions {
|
||||
|
||||
/**
|
||||
* Extensible permissions.
|
||||
* To add new permissions, add to the list of $perms below, with a simple description.
|
||||
* Also visit PermissionRoles.php and add to the $ret['perms_connect'] property for any role
|
||||
* if this permission should be granted to new connections.
|
||||
*
|
||||
* Permissions with 'view' in the name are considered read permissions. Anything
|
||||
* else requires authentication. Read permission limits are PERMS_PUBLIC and anything else
|
||||
* is given PERMS_SPECIFIC.
|
||||
*
|
||||
* PermissionLimits::Std_limits() retrieves the standard limits. A permission role
|
||||
* MAY alter an individual setting after retrieving the Std_limits if you require
|
||||
* something different for a specific permission within the given role.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
static public function Perms($filter = '') {
|
||||
|
||||
$perms = [
|
||||
'view_stream' => t('Can view my channel stream and posts'),
|
||||
'send_stream' => t('Can send me their channel stream and posts'),
|
||||
'view_profile' => t('Can view my default channel profile'),
|
||||
'view_contacts' => t('Can view my connections'),
|
||||
'view_storage' => t('Can view my file storage and photos'),
|
||||
'write_storage' => t('Can upload/modify my file storage and photos'),
|
||||
'view_pages' => t('Can view my channel webpages'),
|
||||
'write_pages' => t('Can create/edit my channel webpages'),
|
||||
'post_wall' => t('Can post on my channel (wall) page'),
|
||||
'post_comments' => t('Can comment on or like my posts'),
|
||||
'post_mail' => t('Can send me private mail messages'),
|
||||
'post_like' => t('Can like/dislike profiles and profile things'),
|
||||
'tag_deliver' => t('Can forward to all my channel connections via @+ mentions in posts'),
|
||||
'chat' => t('Can chat with me'),
|
||||
'republish' => t('Can source my public posts in derived channels'),
|
||||
'delegate' => t('Can administer my channel')
|
||||
];
|
||||
|
||||
$x = array('permissions' => $perms, 'filter' => $filter);
|
||||
call_hooks('permissions_list',$x);
|
||||
return($x['permissions']);
|
||||
|
||||
}
|
||||
|
||||
static public function BlockedAnonPerms() {
|
||||
|
||||
// Perms from the above list that are blocked from anonymous observers.
|
||||
// e.g. you must be authenticated.
|
||||
|
||||
$res = array();
|
||||
$perms = PermissionLimits::Std_limits();
|
||||
foreach($perms as $perm => $limit) {
|
||||
if($limit != PERMS_PUBLIC) {
|
||||
$res[] = $perm;
|
||||
}
|
||||
}
|
||||
|
||||
$x = array('permissions' => $res);
|
||||
call_hooks('write_perms',$x);
|
||||
return($x['permissions']);
|
||||
|
||||
}
|
||||
|
||||
// converts [ 0 => 'view_stream', ... ]
|
||||
// to [ 'view_stream' => 1 ]
|
||||
// for any permissions in $arr;
|
||||
// Undeclared permissions are set to 0
|
||||
|
||||
static public function FilledPerms($arr) {
|
||||
$everything = self::Perms();
|
||||
$ret = [];
|
||||
foreach($everything as $k => $v) {
|
||||
if(in_array($k,$arr))
|
||||
$ret[$k] = 1;
|
||||
else
|
||||
$ret[$k] = 0;
|
||||
}
|
||||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
static public function FilledAutoperms($channel_id) {
|
||||
if(! intval(get_pconfig($channel_id,'system','autoperms')))
|
||||
return false;
|
||||
|
||||
$arr = [];
|
||||
$r = q("select * from pconfig where uid = %d and cat = 'autoperms'",
|
||||
intval($channel_id)
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$arr[$rr['k']] = $arr[$rr['v']];
|
||||
}
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
static public function PermsCompare($p1,$p2) {
|
||||
foreach($p1 as $k => $v) {
|
||||
if(! array_key_exists($k,$p2))
|
||||
return false;
|
||||
if($p1[$k] != $p2[$k])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,6 @@ class Cron {
|
||||
require_once('include/sharedwithme.php');
|
||||
apply_updates();
|
||||
|
||||
|
||||
// expire any expired mail
|
||||
|
||||
q("delete from mail where expires != '%s' and expires < %s ",
|
||||
@@ -63,6 +62,19 @@ class Cron {
|
||||
}
|
||||
|
||||
|
||||
// delete expired access tokens
|
||||
|
||||
$r = q("select atoken_id from atoken where atoken_expires != '%s' && atoken_expires < %s",
|
||||
dbesc(NULL_DATE),
|
||||
db_utcnow()
|
||||
);
|
||||
if($r) {
|
||||
require_once('include/security.php');
|
||||
foreach($r as $rr) {
|
||||
atoken_delete($rr['atoken_id']);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that every channel pings a directory server once a month. This way we can discover
|
||||
// channels and sites that quietly vanished and prevent the directory from accumulating stale
|
||||
// or dead entries.
|
||||
@@ -93,6 +105,18 @@ class Cron {
|
||||
intval($rr['id'])
|
||||
);
|
||||
if($x) {
|
||||
$z = q("select * from item where id = %d",
|
||||
intval($message_id)
|
||||
);
|
||||
if($z) {
|
||||
xchan_query($z);
|
||||
$sync_item = fetch_post_tags($z);
|
||||
build_sync_packet($sync_item[0]['uid'],
|
||||
[
|
||||
'item' => [ encode_item($sync_item[0],true) ]
|
||||
]
|
||||
);
|
||||
}
|
||||
Master::Summon(array('Notifier','wall-new',$rr['id']));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ class Cron_weekly {
|
||||
|
||||
call_hooks('cron_weekly',datetime_convert());
|
||||
|
||||
|
||||
z_check_cert();
|
||||
|
||||
require_once('include/hubloc.php');
|
||||
|
||||
55
Zotlabs/Daemon/CurlAuth.php
Normal file
55
Zotlabs/Daemon/CurlAuth.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
// generate a curl compatible cookie file with an authenticated session for the given channel_id.
|
||||
// If this file is then used with curl and the destination url is sent through zid() or manually
|
||||
// manipulated to add a zid, it should allow curl to provide zot magic-auth across domains.
|
||||
|
||||
// Handles expiration of stale cookies currently by deleting them and rewriting the file.
|
||||
|
||||
class CurlAuth {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
if($argc != 2)
|
||||
killme();
|
||||
|
||||
\App::$session->start();
|
||||
|
||||
$_SESSION['authenticated'] = 1;
|
||||
$_SESSION['uid'] = $argv[1];
|
||||
|
||||
$x = session_id();
|
||||
|
||||
$f = 'store/[data]/cookie_' . $argv[1];
|
||||
$c = 'store/[data]/cookien_' . $argv[1];
|
||||
|
||||
$e = file_exists($f);
|
||||
|
||||
$output = '';
|
||||
|
||||
if($e) {
|
||||
$lines = file($f);
|
||||
if($lines) {
|
||||
foreach($lines as $line) {
|
||||
if(strlen($line) > 0 && $line[0] != '#' && substr_count($line, "\t") == 6) {
|
||||
$tokens = explode("\t", $line);
|
||||
$tokens = array_map('trim', $tokens);
|
||||
if($tokens[4] > time()) {
|
||||
$output .= $line . "\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
$output .= $line;
|
||||
}
|
||||
}
|
||||
}
|
||||
$t = time() + (24 * 3600);
|
||||
file_put_contents($f, $output . 'HttpOnly_' . \App::get_hostname() . "\tFALSE\t/\tTRUE\t$t\tPHPSESSID\t" . $x, (($e) ? FILE_APPEND : 0));
|
||||
|
||||
file_put_contents($c,$x);
|
||||
|
||||
killme();
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ class Expire {
|
||||
|
||||
logger('site_expire: ' . $site_expire);
|
||||
|
||||
$r = q("SELECT channel_id, channel_address, channel_pageflags, channel_expire_days from channel where true");
|
||||
$r = q("SELECT channel_id, channel_system, channel_address, channel_expire_days from channel where true");
|
||||
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
|
||||
@@ -102,7 +102,9 @@ class Onepoll {
|
||||
$fetch_feed = true;
|
||||
$x = null;
|
||||
|
||||
if(! ($contact['abook_their_perms'] & PERMS_R_STREAM ))
|
||||
$can_view_stream = intval(get_abconfig($importer_uid,$contact['abook_xchan'],'their_perms','view_stream'));
|
||||
|
||||
if(! $can_view_stream)
|
||||
$fetch_feed = false;
|
||||
|
||||
if($fetch_feed) {
|
||||
|
||||
43
Zotlabs/Daemon/README.md
Normal file
43
Zotlabs/Daemon/README.md
Normal file
@@ -0,0 +1,43 @@
|
||||
Daemon (background) Processes
|
||||
=============================
|
||||
|
||||
|
||||
This directory provides background tasks which are executed by a
|
||||
command-line process and detached from normal web processing.
|
||||
|
||||
Background tasks are invoked by calling
|
||||
|
||||
|
||||
Zotlabs\Daemon\Master::Summon([ $cmd, $arg1, $argn... ]);
|
||||
|
||||
The Master class loads the desired command file and passes the arguments.
|
||||
|
||||
|
||||
To create a background task 'Foo' use the following template.
|
||||
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
class Foo {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
// do something
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
The Master class "summons" the command by creating an executable script
|
||||
from the provided arguments, then it invokes "Release" to execute the script
|
||||
detached from web processing. This process calls the static::run() function
|
||||
with any command line arguments using the traditional argc, argv format.
|
||||
|
||||
Please note: These are *real* $argc, $argv variables passed from the command
|
||||
line, and not the parsed argc() and argv() functions/variables which were
|
||||
obtained from parsing path components of the request URL by web processes.
|
||||
|
||||
Background processes do not emit displayable output except through logs. They
|
||||
should also not make any assumptions about their HTML and web environment
|
||||
(as they do not have a web environment), particularly with respect to global
|
||||
variables such as $_SERVER, $_REQUEST, $_GET, $_POST, $_COOKIES, and $_SESSION.
|
||||
|
||||
@@ -5,18 +5,20 @@ namespace Zotlabs\Lib;
|
||||
|
||||
class AbConfig {
|
||||
|
||||
static public function Load($chash,$xhash) {
|
||||
$r = q("select * from abconfig where chan = '%s' and xchan = '%s'",
|
||||
dbesc($chash),
|
||||
static public function Load($chan,$xhash,$family = '') {
|
||||
if($family)
|
||||
$where = sprintf(" and cat = '%s' ",dbesc($family));
|
||||
$r = q("select * from abconfig where chan = %d and xchan = '%s' $where",
|
||||
intval($chan),
|
||||
dbesc($xhash)
|
||||
);
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
static public function Get($chash,$xhash,$family,$key) {
|
||||
$r = q("select * from abconfig where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' limit 1",
|
||||
dbesc($chash),
|
||||
static public function Get($chan,$xhash,$family,$key) {
|
||||
$r = q("select * from abconfig where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' limit 1",
|
||||
intval($chan),
|
||||
dbesc($xhash),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
@@ -28,14 +30,14 @@ class AbConfig {
|
||||
}
|
||||
|
||||
|
||||
static public function Set($chash,$xhash,$family,$key,$value) {
|
||||
static public function Set($chan,$xhash,$family,$key,$value) {
|
||||
|
||||
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
|
||||
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
|
||||
|
||||
if(self::Get($chash,$xhash,$family,$key) === false) {
|
||||
$r = q("insert into abconfig ( chan, xchan, cat, k, v ) values ( '%s', '%s', '%s', '%s', '%s' ) ",
|
||||
dbesc($chash),
|
||||
if(self::Get($chan,$xhash,$family,$key) === false) {
|
||||
$r = q("insert into abconfig ( chan, xchan, cat, k, v ) values ( %d, '%s', '%s', '%s', '%s' ) ",
|
||||
intval($chan),
|
||||
dbesc($xhash),
|
||||
dbesc($family),
|
||||
dbesc($key),
|
||||
@@ -43,9 +45,9 @@ class AbConfig {
|
||||
);
|
||||
}
|
||||
else {
|
||||
$r = q("update abconfig set v = '%s' where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' ",
|
||||
$r = q("update abconfig set v = '%s' where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' ",
|
||||
dbesc($dbvalue),
|
||||
dbesc($chash),
|
||||
dbesc($chan),
|
||||
dbesc($xhash),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
@@ -58,10 +60,10 @@ class AbConfig {
|
||||
}
|
||||
|
||||
|
||||
static public function Delete($chash,$xhash,$family,$key) {
|
||||
static public function Delete($chan,$xhash,$family,$key) {
|
||||
|
||||
$r = q("delete from abconfig where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' ",
|
||||
dbesc($chash),
|
||||
$r = q("delete from abconfig where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' ",
|
||||
intval($chan),
|
||||
dbesc($xhash),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
@@ -70,4 +72,4 @@ class AbConfig {
|
||||
return $r;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,9 @@ class Apps {
|
||||
$files = glob('addon/*/*.apd');
|
||||
if($files) {
|
||||
foreach($files as $f) {
|
||||
$n = basename($f,'.apd');
|
||||
if(plugin_is_installed($n)) {
|
||||
$path = explode('/',$f);
|
||||
$plugin = $path[1];
|
||||
if(plugin_is_installed($plugin)) {
|
||||
$x = self::parse_app_description($f,$translate);
|
||||
if($x) {
|
||||
$ret[] = $x;
|
||||
|
||||
51
Zotlabs/Lib/Cache.php
Normal file
51
Zotlabs/Lib/Cache.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
/**
|
||||
* cache api
|
||||
*/
|
||||
|
||||
class Cache {
|
||||
public static function get($key) {
|
||||
|
||||
$key = substr($key,0,254);
|
||||
|
||||
$r = q("SELECT v FROM cache WHERE k = '%s' limit 1",
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
if ($r)
|
||||
return $r[0]['v'];
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function set($key,$value) {
|
||||
|
||||
$key = substr($key,0,254);
|
||||
|
||||
$r = q("SELECT * FROM cache WHERE k = '%s' limit 1",
|
||||
dbesc($key)
|
||||
);
|
||||
if($r) {
|
||||
q("UPDATE cache SET v = '%s', updated = '%s' WHERE k = '%s'",
|
||||
dbesc($value),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($key));
|
||||
}
|
||||
else {
|
||||
q("INSERT INTO cache ( k, v, updated) VALUES ('%s','%s','%s')",
|
||||
dbesc($key),
|
||||
dbesc($value),
|
||||
dbesc(datetime_convert()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function clear() {
|
||||
q("DELETE FROM cache WHERE updated < '%s'",
|
||||
dbesc(datetime_convert('UTC','UTC',"now - 30 days")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,12 +17,20 @@ class PConfig {
|
||||
*/
|
||||
|
||||
static public function Load($uid) {
|
||||
if($uid === false)
|
||||
if(is_null($uid) || $uid === false)
|
||||
return false;
|
||||
|
||||
if(! array_key_exists($uid, \App::$config))
|
||||
\App::$config[$uid] = array();
|
||||
|
||||
if(! is_array(\App::$config)) {
|
||||
btlogger('App::$config not an array: ' . $uid);
|
||||
}
|
||||
|
||||
if(! is_array(\App::$config[$uid])) {
|
||||
btlogger('App::$config[$uid] not an array: ' . $uid);
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM pconfig WHERE uid = %d",
|
||||
intval($uid)
|
||||
);
|
||||
@@ -61,7 +69,7 @@ class PConfig {
|
||||
|
||||
static public function Get($uid,$family,$key,$instore = false) {
|
||||
|
||||
if($uid === false)
|
||||
if(is_null($uid) || $uid === false)
|
||||
return false;
|
||||
|
||||
if(! array_key_exists($uid, \App::$config))
|
||||
@@ -102,7 +110,7 @@ class PConfig {
|
||||
// we provide a function backtrace in the logs so that we can find
|
||||
// and fix the calling function.
|
||||
|
||||
if($uid === false) {
|
||||
if(is_null($uid) || $uid === false) {
|
||||
btlogger('UID is FALSE!', LOGGER_NORMAL, LOG_ERR);
|
||||
return;
|
||||
}
|
||||
@@ -172,6 +180,9 @@ class PConfig {
|
||||
|
||||
static public function Delete($uid, $family, $key) {
|
||||
|
||||
if(is_null($uid) || $uid === false)
|
||||
return false;
|
||||
|
||||
$ret = false;
|
||||
|
||||
if(array_key_exists($key, \App::$config[$uid][$family]))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
if(class_exists('PermissionDescription')) return;
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
require_once("include/permissions.php");
|
||||
require_once("include/language.php");
|
||||
@@ -78,22 +78,13 @@ class PermissionDescription {
|
||||
|
||||
$result = null;
|
||||
|
||||
$global_perms = get_perms();
|
||||
$global_perms = \Zotlabs\Access\Permissions::Perms();
|
||||
|
||||
if (array_key_exists($permname, $global_perms)) {
|
||||
|
||||
$permDetails = $global_perms[$permname];
|
||||
$channelPerm = \Zotlabs\Access\PermissionLimits::Get(\App::$channel['channel_id'],$permname);
|
||||
|
||||
// It should be OK to always just read the permissions from App::$channel
|
||||
//
|
||||
// App::$profile is a union of channel and profile fields.
|
||||
// The distinction is basically that App::$profile is pointing to the resource
|
||||
// being observed. App::$channel is referring to the current logged-in channel
|
||||
// member (if this is a local channel) e.g. the observer. We only show the ACL
|
||||
// widget to the page owner (observer and observed are the same) so in that case
|
||||
// I believe either may be safely used here.
|
||||
$channelPerm = \App::$channel[$permDetails[0]];
|
||||
$result = new PermissionDescription($permDetails[1], $channelPerm);
|
||||
$result = new PermissionDescription('', $channelPerm);
|
||||
} else {
|
||||
// The acl dialog can handle null arguments, but it shouldn't happen
|
||||
logger('null PermissionDescription from unknown global permission: ' . $permname ,LOGGER_DEBUG, LOG_ERROR);
|
||||
127
Zotlabs/Lib/SuperCurl.php
Normal file
127
Zotlabs/Lib/SuperCurl.php
Normal file
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
/**
|
||||
* @brief wrapper for z_fetch_url() which can be instantiated with several built-in parameters and
|
||||
* these can be modified and re-used. Useful for CalDAV and other processes which need to authenticate
|
||||
* and set lots of CURL options (many of which stay the same from one call to the next).
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
class SuperCurl {
|
||||
|
||||
|
||||
private $auth;
|
||||
private $url;
|
||||
|
||||
private $curlopt = array();
|
||||
|
||||
private $headers = null;
|
||||
public $filepos = 0;
|
||||
public $filehandle = 0;
|
||||
public $request_data = '';
|
||||
|
||||
private $request_method = 'GET';
|
||||
private $upload = false;
|
||||
private $cookies = false;
|
||||
|
||||
|
||||
private function set_data($s) {
|
||||
$this->request_data = $s;
|
||||
$this->filepos = 0;
|
||||
}
|
||||
|
||||
public function curl_read($ch,$fh,$size) {
|
||||
|
||||
if($this->filepos < 0) {
|
||||
unset($fh);
|
||||
return '';
|
||||
}
|
||||
|
||||
$s = substr($this->request_data,$this->filepos,$size);
|
||||
|
||||
if(strlen($s) < $size)
|
||||
$this->filepos = (-1);
|
||||
else
|
||||
$this->filepos = $this->filepos + $size;
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
||||
public function __construct($opts = array()) {
|
||||
$this->set($opts);
|
||||
}
|
||||
|
||||
private function set($opts = array()) {
|
||||
if($opts) {
|
||||
foreach($opts as $k => $v) {
|
||||
switch($k) {
|
||||
case 'http_auth':
|
||||
$this->auth = $v;
|
||||
break;
|
||||
case 'magicauth':
|
||||
// currently experimental
|
||||
$this->magicauth = $v;
|
||||
\Zotlabs\Daemon\Master::Summon([ 'CurlAuth', $v ]);
|
||||
break;
|
||||
case 'custom':
|
||||
$this->request_method = $v;
|
||||
break;
|
||||
case 'url':
|
||||
$this->url = $v;
|
||||
break;
|
||||
case 'data':
|
||||
$this->set_data($v);
|
||||
if($v) {
|
||||
$this->upload = true;
|
||||
}
|
||||
else {
|
||||
$this->upload = false;
|
||||
}
|
||||
break;
|
||||
case 'headers':
|
||||
$this->headers = $v;
|
||||
break;
|
||||
default:
|
||||
$this->curlopts[$k] = $v;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function exec() {
|
||||
$opts = $this->curlopts;
|
||||
$url = $this->url;
|
||||
if($this->auth)
|
||||
$opts['http_auth'] = $this->auth;
|
||||
if($this->magicauth) {
|
||||
$opts['cookiejar'] = 'store/[data]/cookie_' . $this->magicauth;
|
||||
$opts['cookiefile'] = 'store/[data]/cookie_' . $this->magicauth;
|
||||
$opts['cookie'] = 'PHPSESSID=' . trim(file_get_contents('store/[data]/cookien_' . $this->magicauth));
|
||||
$c = channelx_by_n($this->magicauth);
|
||||
if($c)
|
||||
$url = zid($this->url,$c['channel_address'] . '@' . \App::get_hostname());
|
||||
}
|
||||
if($this->custom)
|
||||
$opts['custom'] = $this->custom;
|
||||
if($this->headers)
|
||||
$opts['headers'] = $this->headers;
|
||||
if($this->upload) {
|
||||
$opts['upload'] = true;
|
||||
$opts['infile'] = $this->filehandle;
|
||||
$opts['infilesize'] = strlen($this->request_data);
|
||||
$opts['readfunc'] = [ $this, 'curl_read' ] ;
|
||||
}
|
||||
|
||||
$recurse = 0;
|
||||
return z_fetch_url($this->url,true,$recurse,(($opts) ? $opts : null));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -43,8 +43,8 @@ class System {
|
||||
|
||||
|
||||
static public function get_server_role() {
|
||||
if(UNO)
|
||||
return 'basic';
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['server_role'])
|
||||
return \App::$config['system']['server_role'];
|
||||
return 'pro';
|
||||
}
|
||||
|
||||
|
||||
@@ -245,10 +245,11 @@ class ThreadItem {
|
||||
);
|
||||
}
|
||||
|
||||
$server_role = get_config('system','server_role');
|
||||
$has_bookmarks = false;
|
||||
if(is_array($item['term'])) {
|
||||
foreach($item['term'] as $t) {
|
||||
if(!UNO && $t['type'] == TERM_BOOKMARK)
|
||||
if(($server_role != 'basic') && ($t['ttype'] == TERM_BOOKMARK))
|
||||
$has_bookmarks = true;
|
||||
}
|
||||
}
|
||||
@@ -418,7 +419,7 @@ class ThreadItem {
|
||||
if(($nb_children > $visible_comments) || ($thread_level > 1)) {
|
||||
$result['children'][0]['comment_firstcollapsed'] = true;
|
||||
$result['children'][0]['num_comments'] = $comment_count_txt;
|
||||
$result['children'][0]['hide_text'] = t('[+] show all');
|
||||
$result['children'][0]['hide_text'] = sprintf( t('%s show all'), '<i class="fa fa-chevron-down"></i>');
|
||||
if($thread_level > 1) {
|
||||
$result['children'][$nb_children - 1]['comment_lastcollapsed'] = true;
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ class XConfig {
|
||||
);
|
||||
}
|
||||
|
||||
App::$config[$xchan][$family][$key] = $value;
|
||||
\App::$config[$xchan][$family][$key] = $value;
|
||||
|
||||
if($ret)
|
||||
return $value;
|
||||
@@ -157,4 +157,4 @@ class XConfig {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ class Achievements extends \Zotlabs\Web\Controller {
|
||||
|
||||
$profile = 0;
|
||||
$profile = argv(1);
|
||||
profile_load($a,$which,$profile);
|
||||
profile_load($which,$profile);
|
||||
|
||||
$r = q("select channel_id from channel where channel_address = '%s'",
|
||||
dbesc($which)
|
||||
|
||||
@@ -1,7 +1,18 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
/* ACL selector json backend */
|
||||
/*
|
||||
* ACL selector json backend
|
||||
* This module provides JSON lists of connections and local/remote channels
|
||||
* (xchans) to populate various tools such as the ACL (AccessControlList) popup
|
||||
* and various auto-complete functions (such as email recipients, search, and
|
||||
* mention targets.
|
||||
* There are two primary output structural formats. One for the ACL widget and
|
||||
* the other for auto-completion.
|
||||
* Many of the behaviour variations are triggered on the use of single character keys
|
||||
* however this functionality has grown in an ad-hoc manner and has gotten quite messy over time.
|
||||
*/
|
||||
|
||||
require_once("include/acl_selectors.php");
|
||||
require_once("include/group.php");
|
||||
|
||||
@@ -10,40 +21,80 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init(){
|
||||
|
||||
// logger('mod_acl: ' . print_r($_REQUEST,true));
|
||||
// logger('mod_acl: ' . print_r($_REQUEST,true));
|
||||
|
||||
$start = (x($_REQUEST,'start')?$_REQUEST['start']:0);
|
||||
$count = (x($_REQUEST,'count')?$_REQUEST['count']:100);
|
||||
$search = (x($_REQUEST,'search')?$_REQUEST['search']:"");
|
||||
$type = (x($_REQUEST,'type')?$_REQUEST['type']:"");
|
||||
$noforums = (x($_REQUEST,'n') ? $_REQUEST['n'] : false);
|
||||
$start = (x($_REQUEST,'start') ? $_REQUEST['start'] : 0);
|
||||
$count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 500);
|
||||
$search = (x($_REQUEST,'search') ? $_REQUEST['search'] : '');
|
||||
$type = (x($_REQUEST,'type') ? $_REQUEST['type'] : '');
|
||||
$noforums = (x($_REQUEST,'n') ? $_REQUEST['n'] : false);
|
||||
|
||||
|
||||
// $type =
|
||||
// '' => standard ACL request
|
||||
// 'g' => Groups only ACL request
|
||||
// 'c' => Connections only ACL request or editor (textarea) mention request
|
||||
// $_REQUEST['search'] contains ACL search text.
|
||||
|
||||
|
||||
// $type =
|
||||
// 'm' => autocomplete private mail recipient (checks post_mail permission)
|
||||
// 'a' => autocomplete connections (mod_connections, mod_poke, mod_sources, mod_photos)
|
||||
// 'x' => nav search bar autocomplete (match any xchan)
|
||||
// $_REQUEST['query'] contains autocomplete search text.
|
||||
|
||||
// List of channels whose connections to also suggest, e.g. currently viewed channel or channels mentioned in a post
|
||||
// List of channels whose connections to also suggest,
|
||||
// e.g. currently viewed channel or channels mentioned in a post
|
||||
|
||||
$extra_channels = (x($_REQUEST,'extra_channels') ? $_REQUEST['extra_channels'] : array());
|
||||
|
||||
// For use with jquery.autocomplete for private mail completion
|
||||
// The different autocomplete libraries use different names for the search text
|
||||
// parameter. Internaly we'll use $search to represent the search text no matter
|
||||
// what request variable it was attached to.
|
||||
|
||||
if(x($_REQUEST,'query') && strlen($_REQUEST['query'])) {
|
||||
if(! $type)
|
||||
$type = 'm';
|
||||
if(array_key_exists('query',$_REQUEST)) {
|
||||
$search = $_REQUEST['query'];
|
||||
}
|
||||
|
||||
if(!(local_channel()))
|
||||
if(!($type == 'x' || $type == 'c'))
|
||||
killme();
|
||||
|
||||
if ($search != "") {
|
||||
if( (! local_channel()) && (! ($type == 'x' || $type == 'c')))
|
||||
killme();
|
||||
|
||||
$permitted = [];
|
||||
|
||||
if(in_array($type, [ 'm', 'a', 'c' ])) {
|
||||
|
||||
// These queries require permission checking. We'll create a simple array of xchan_hash for those with
|
||||
// the requisite permissions which we can check against.
|
||||
|
||||
$x = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = '%s' and v = 1",
|
||||
intval(local_channel()),
|
||||
dbesc(($type === 'm') ? 'post_mail' : 'tag_deliver')
|
||||
);
|
||||
|
||||
$permitted = ids_to_array($x,'xchan');
|
||||
|
||||
}
|
||||
|
||||
|
||||
if($search) {
|
||||
$sql_extra = " AND `name` LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " ";
|
||||
$sql_extra2 = "AND ( xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " OR xchan_addr LIKE " . protect_sprintf( "'%" . dbesc($search) . ((strpos($search,'@') === false) ? "%@%'" : "%'")) . ") ";
|
||||
|
||||
// This horrible mess is needed because position also returns 0 if nothing is found. W/ould be MUCH easier if it instead returned a very large value
|
||||
// Otherwise we could just order by LEAST(POSITION($search IN xchan_name),POSITION($search IN xchan_addr)).
|
||||
$order_extra2 = "CASE WHEN xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) ." then POSITION('".dbesc($search)."' IN xchan_name) else position('".dbesc($search)."' IN xchan_addr) end, ";
|
||||
// This horrible mess is needed because position also returns 0 if nothing is found.
|
||||
// Would be MUCH easier if it instead returned a very large value
|
||||
// Otherwise we could just
|
||||
// order by LEAST(POSITION($search IN xchan_name),POSITION($search IN xchan_addr)).
|
||||
|
||||
$order_extra2 = "CASE WHEN xchan_name LIKE "
|
||||
. protect_sprintf( "'%" . dbesc($search) . "%'" )
|
||||
. " then POSITION('" . dbesc($search)
|
||||
. "' IN xchan_name) else position('" . dbesc($search) . "' IN xchan_addr) end, ";
|
||||
|
||||
$col = ((strpos($search,'@') !== false) ? 'xchan_addr' : 'xchan_name' );
|
||||
$sql_extra3 = "AND $col like " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " ";
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$sql_extra = $sql_extra2 = $sql_extra3 = "";
|
||||
}
|
||||
|
||||
@@ -51,15 +102,15 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
$groups = array();
|
||||
$contacts = array();
|
||||
|
||||
if ($type=='' || $type=='g'){
|
||||
if($type == '' || $type == 'g') {
|
||||
|
||||
$r = q("SELECT `groups`.`id`, `groups`.`hash`, `groups`.`gname`
|
||||
FROM `groups`,`group_member`
|
||||
WHERE `groups`.`deleted` = 0 AND `groups`.`uid` = %d
|
||||
AND `group_member`.`gid`=`groups`.`id`
|
||||
$r = q("SELECT groups.id, groups.hash, groups.gname
|
||||
FROM groups,group_member
|
||||
WHERE groups.deleted = 0 AND groups.uid = %d
|
||||
AND group_member.gid=groups.id
|
||||
$sql_extra
|
||||
GROUP BY `groups`.`id`
|
||||
ORDER BY `groups`.`gname`
|
||||
GROUP BY groups.id
|
||||
ORDER BY groups.gname
|
||||
LIMIT %d OFFSET %d",
|
||||
intval(local_channel()),
|
||||
intval($count),
|
||||
@@ -82,7 +133,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
if ($type=='' || $type=='c') {
|
||||
if($type == '' || $type == 'c') {
|
||||
$extra_channels_sql = '';
|
||||
// Only include channels who allow the observer to view their permissions
|
||||
foreach($extra_channels as $channel) {
|
||||
@@ -96,13 +147,40 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
if(local_channel()) {
|
||||
if($extra_channels_sql != '')
|
||||
$extra_channels_sql = " OR (abook_channel IN ($extra_channels_sql)) and abook_hidden = 0 ";
|
||||
|
||||
$r2 = null;
|
||||
|
||||
$r1 = q("select * from atoken where atoken_uid = %d",
|
||||
intval(local_channel())
|
||||
);
|
||||
if($r1) {
|
||||
require_once('include/security.php');
|
||||
$r2 = array();
|
||||
foreach($r1 as $rr) {
|
||||
$x = atoken_xchan($rr);
|
||||
$r2[] = [
|
||||
'id' => 'a' . $rr['atoken_id'] ,
|
||||
'hash' => $x['xchan_hash'],
|
||||
'name' => $x['xchan_name'],
|
||||
'micro' => $x['xchan_photo_m'],
|
||||
'url' => z_root(),
|
||||
'nick' => $x['xchan_addr'],
|
||||
'abook_their_perms' => 0,
|
||||
'abook_flags' => 0,
|
||||
'abook_self' => 0
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$r = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, abook_flags, abook_self
|
||||
$r = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, xchan_pubforum, abook_flags, abook_self
|
||||
FROM abook left join xchan on abook_xchan = xchan_hash
|
||||
WHERE (abook_channel = %d $extra_channels_sql) AND abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc" ,
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
if($r2)
|
||||
$r = array_merge($r2,$r);
|
||||
|
||||
}
|
||||
else { // Visitors
|
||||
$r = q("SELECT xchan_hash as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self
|
||||
@@ -160,18 +238,26 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
elseif($type == 'm') {
|
||||
|
||||
$r = q("SELECT xchan_hash as id, xchan_name as name, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url
|
||||
|
||||
$r = array();
|
||||
$z = q("SELECT xchan_hash as hash, xchan_name as name, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url
|
||||
FROM abook left join xchan on abook_xchan = xchan_hash
|
||||
WHERE abook_channel = %d and ( (abook_their_perms = null) or (abook_their_perms & %d )>0)
|
||||
WHERE abook_channel = %d
|
||||
and xchan_deleted = 0
|
||||
$sql_extra3
|
||||
ORDER BY `xchan_name` ASC ",
|
||||
intval(local_channel()),
|
||||
intval(PERMS_W_MAIL)
|
||||
ORDER BY xchan_name ASC ",
|
||||
intval(local_channel())
|
||||
);
|
||||
if($z) {
|
||||
foreach($z as $zz) {
|
||||
if(in_array($zz['hash'],$permitted)) {
|
||||
$r[] = $zz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
elseif(($type == 'a') || ($type == 'p')) {
|
||||
elseif($type == 'a') {
|
||||
|
||||
$r = q("SELECT abook_id as id, xchan_name as name, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_network as network, xchan_url as url, xchan_addr as attag , abook_their_perms FROM abook left join xchan on abook_xchan = xchan_hash
|
||||
WHERE abook_channel = %d
|
||||
@@ -213,7 +299,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
if(strpos($g['hash'],'/') && $type != 'a')
|
||||
continue;
|
||||
|
||||
if(($g['abook_their_perms'] & PERMS_W_TAGWALL) && $type == 'c' && (! $noforums)) {
|
||||
if(in_array($g['hash'],$permitted) && $type == 'c' && (! $noforums)) {
|
||||
$contacts[] = array(
|
||||
"type" => "c",
|
||||
"photo" => "images/twopeople.png",
|
||||
@@ -296,7 +382,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
$url = $directory['url'] . '/dirsearch';
|
||||
}
|
||||
|
||||
$count = (x($_REQUEST,'count')?$_REQUEST['count']:100);
|
||||
$count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 100);
|
||||
if($url) {
|
||||
$query = $url . '?f=' ;
|
||||
$query .= '&name=' . urlencode($search) . "&limit=$count" . (($address) ? '&address=' . urlencode($search) : '');
|
||||
|
||||
@@ -12,7 +12,7 @@ class Block extends \Zotlabs\Web\Controller {
|
||||
|
||||
$which = argv(1);
|
||||
$profile = 0;
|
||||
profile_load($a,$which,$profile);
|
||||
profile_load($which,$profile);
|
||||
|
||||
if(\App::$profile['profile_uid'])
|
||||
head_set_icon(\App::$profile['thumb']);
|
||||
@@ -52,8 +52,8 @@ class Block extends \Zotlabs\Web\Controller {
|
||||
require_once('include/security.php');
|
||||
$sql_options = item_permissions_sql($u[0]['channel_id']);
|
||||
|
||||
$r = q("select item.* from item left join item_id on item.id = item_id.iid
|
||||
where item.uid = %d and sid = '%s' and service = 'BUILDBLOCK' and
|
||||
$r = q("select item.* from item left join iconfig on item.id = iconfig.iid
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and iconfig.k = 'BUILDBLOCK' and
|
||||
item_type = %d $sql_options $revision limit 1",
|
||||
intval($u[0]['channel_id']),
|
||||
dbesc($page_id),
|
||||
@@ -64,8 +64,8 @@ class Block extends \Zotlabs\Web\Controller {
|
||||
|
||||
// Check again with no permissions clause to see if it is a permissions issue
|
||||
|
||||
$x = q("select item.* from item left join item_id on item.id = item_id.iid
|
||||
where item.uid = %d and sid = '%s' and service = 'BUILDBLOCK' and
|
||||
$x = q("select item.* from item left join iconfig on item.id = iconfig.iid
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and iconfig.k = 'BUILDBLOCK' and
|
||||
item_type = %d $revision limit 1",
|
||||
intval($u[0]['channel_id']),
|
||||
dbesc($page_id),
|
||||
|
||||
@@ -22,12 +22,12 @@ class Blocks extends \Zotlabs\Web\Controller {
|
||||
else
|
||||
return;
|
||||
|
||||
profile_load($a,$which);
|
||||
profile_load($which);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function get() {
|
||||
function get() {
|
||||
|
||||
if(! \App::$profile) {
|
||||
notice( t('Requested profile is not available.') . EOL );
|
||||
@@ -111,8 +111,11 @@ class Blocks extends \Zotlabs\Web\Controller {
|
||||
|
||||
$editor = status_editor($a,$x);
|
||||
|
||||
$r = q("select iid, sid, mid, title, body, mimetype, created, edited from item_id left join item on item_id.iid = item.id
|
||||
where item_id.uid = %d and service = 'BUILDBLOCK' and item_type = %d order by item.created desc",
|
||||
|
||||
$r = q("select iconfig.iid, iconfig.k, iconfig.v, mid, title, body, mimetype, created, edited from iconfig
|
||||
left join item on iconfig.iid = item.id
|
||||
where uid = %d and iconfig.cat = 'system' and iconfig.k = 'BUILDBLOCK'
|
||||
and item_type = %d order by item.created desc",
|
||||
intval($owner),
|
||||
intval(ITEM_TYPE_BLOCK)
|
||||
);
|
||||
@@ -129,12 +132,12 @@ class Blocks extends \Zotlabs\Web\Controller {
|
||||
'created' => $rr['created'],
|
||||
'edited' => $rr['edited'],
|
||||
'mimetype' => $rr['mimetype'],
|
||||
'pagetitle' => $rr['sid'],
|
||||
'pagetitle' => $rr['v'],
|
||||
'mid' => $rr['mid']
|
||||
);
|
||||
$pages[$rr['iid']][] = array(
|
||||
'url' => $rr['iid'],
|
||||
'name' => $rr['sid'],
|
||||
'name' => $rr['v'],
|
||||
'title' => $rr['title'],
|
||||
'created' => $rr['created'],
|
||||
'edited' => $rr['edited'],
|
||||
|
||||
@@ -20,7 +20,7 @@ class Cal extends \Zotlabs\Web\Controller {
|
||||
if(argc() > 1) {
|
||||
$nick = argv(1);
|
||||
|
||||
profile_load($a,$nick);
|
||||
profile_load($nick);
|
||||
|
||||
$channelx = channelx_by_nick($nick);
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ require_once('include/security.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/permissions.php');
|
||||
require_once('include/PermissionDescription.php');
|
||||
|
||||
class Channel extends \Zotlabs\Web\Controller {
|
||||
|
||||
@@ -48,7 +47,7 @@ class Channel extends \Zotlabs\Web\Controller {
|
||||
// Run profile_load() here to make sure the theme is set before
|
||||
// we start loading content
|
||||
|
||||
profile_load($a,$which,$profile);
|
||||
profile_load($which,$profile);
|
||||
|
||||
}
|
||||
|
||||
@@ -133,7 +132,8 @@ class Channel extends \Zotlabs\Web\Controller {
|
||||
'default_location' => (($is_owner) ? \App::$profile['channel_location'] : ''),
|
||||
'nickname' => \App::$profile['channel_address'],
|
||||
'lockstate' => (((strlen(\App::$profile['channel_allow_cid'])) || (strlen(\App::$profile['channel_allow_gid'])) || (strlen(\App::$profile['channel_deny_cid'])) || (strlen(\App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'),
|
||||
'acl' => (($is_owner) ? populate_acl($channel_acl,true, \PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''),
|
||||
'acl' => (($is_owner) ? populate_acl($channel_acl,true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''),
|
||||
'permissions' => (($is_owner) ? $channel_acl : ''),
|
||||
'showacl' => (($is_owner) ? 'yes' : ''),
|
||||
'bang' => '',
|
||||
'visitor' => (($is_owner || $observer) ? true : false),
|
||||
@@ -364,4 +364,4 @@ class Channel extends \Zotlabs\Web\Controller {
|
||||
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ class Chat extends \Zotlabs\Web\Controller {
|
||||
// Run profile_load() here to make sure the theme is set before
|
||||
// we start loading content
|
||||
|
||||
profile_load($a,$which,$profile);
|
||||
profile_load($which,$profile);
|
||||
|
||||
}
|
||||
|
||||
@@ -218,14 +218,13 @@ class Chat extends \Zotlabs\Web\Controller {
|
||||
notice( t('Feature disabled.') . EOL);
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
|
||||
$acl = new \Zotlabs\Access\AccessList($channel);
|
||||
$channel_acl = $acl->get();
|
||||
|
||||
|
||||
$lockstate = (($channel_acl['allow_cid'] || $channel_acl['allow_gid'] || $channel_acl['deny_cid'] || $channel_acl['deny_gid']) ? 'lock' : 'unlock');
|
||||
require_once('include/acl_selectors.php');
|
||||
|
||||
|
||||
$chatroom_new = '';
|
||||
if(local_channel()) {
|
||||
$chatroom_new = replace_macros(get_markup_template('chatroom_new.tpl'),array(
|
||||
@@ -234,12 +233,16 @@ class Chat extends \Zotlabs\Web\Controller {
|
||||
'$chat_expire' => array('chat_expire',t('Expiration of chats (minutes)'),120,''),
|
||||
'$permissions' => t('Permissions'),
|
||||
'$acl' => populate_acl($channel_acl,false),
|
||||
'$allow_cid' => acl2json($channel_acl['allow_cid']),
|
||||
'$allow_gid' => acl2json($channel_acl['allow_gid']),
|
||||
'$deny_cid' => acl2json($channel_acl['deny_cid']),
|
||||
'$deny_gid' => acl2json($channel_acl['deny_gid']),
|
||||
'$lockstate' => $lockstate,
|
||||
'$submit' => t('Submit')
|
||||
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
$rooms = Zlib\Chatroom::roomlist(\App::$profile['profile_uid']);
|
||||
|
||||
$o .= replace_macros(get_markup_template('chatrooms.tpl'), array(
|
||||
|
||||
@@ -13,6 +13,9 @@ use \Zotlabs\Storage;
|
||||
// composer autoloader for SabreDAV
|
||||
require_once('vendor/autoload.php');
|
||||
|
||||
require_once('include/attach.php');
|
||||
|
||||
|
||||
/**
|
||||
* @brief Fires up the SabreDAV server.
|
||||
*
|
||||
@@ -23,7 +26,6 @@ require_once('vendor/autoload.php');
|
||||
class Cloud extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
require_once('include/reddav.php');
|
||||
|
||||
if (! is_dir('store'))
|
||||
os_mkdir('store', STORAGE_DEFAULT_PERMISSIONS, false);
|
||||
@@ -37,7 +39,7 @@ class Cloud extends \Zotlabs\Web\Controller {
|
||||
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which . '" />' . "\r\n";
|
||||
|
||||
if ($which)
|
||||
profile_load($a, $which, $profile);
|
||||
profile_load( $which, $profile);
|
||||
|
||||
$auth = new \Zotlabs\Storage\BasicAuth();
|
||||
|
||||
@@ -79,17 +81,6 @@ class Cloud extends \Zotlabs\Web\Controller {
|
||||
|
||||
$is_readable = false;
|
||||
|
||||
if($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
try {
|
||||
$x = RedFileData('/' . \App::$cmd, $auth);
|
||||
}
|
||||
catch(\Exception $e) {
|
||||
if($e instanceof Sabre\DAV\Exception\Forbidden) {
|
||||
http_status_exit(401, 'Permission denied.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// provide a directory view for the cloud in Hubzilla
|
||||
$browser = new \Zotlabs\Storage\Browser($auth);
|
||||
$auth->setBrowserPlugin($browser);
|
||||
|
||||
@@ -21,7 +21,7 @@ class Common extends \Zotlabs\Web\Controller {
|
||||
);
|
||||
|
||||
if($x)
|
||||
profile_load($a,$x[0]['channel_address'],0);
|
||||
profile_load($x[0]['channel_address'],0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ class Connect extends \Zotlabs\Web\Controller {
|
||||
if($r)
|
||||
\App::$data['channel'] = $r[0];
|
||||
|
||||
profile_load($a,$which,'');
|
||||
profile_load($which,'');
|
||||
}
|
||||
|
||||
function post() {
|
||||
|
||||
@@ -16,14 +16,14 @@ require_once('include/zot.php');
|
||||
require_once('include/widgets.php');
|
||||
require_once('include/photos.php');
|
||||
|
||||
/* @brief Initialize the connection-editor
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
class Connedit extends \Zotlabs\Web\Controller {
|
||||
|
||||
/* @brief Initialize the connection-editor
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
function init() {
|
||||
|
||||
if(! local_channel())
|
||||
@@ -51,7 +51,7 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
*
|
||||
*/
|
||||
|
||||
function post() {
|
||||
function post() {
|
||||
|
||||
if(! local_channel())
|
||||
return;
|
||||
@@ -126,22 +126,42 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
$rating = 10;
|
||||
|
||||
$rating_text = trim(escape_tags($_REQUEST['rating_text']));
|
||||
|
||||
$abook_my_perms = 0;
|
||||
|
||||
foreach($_POST as $k => $v) {
|
||||
if(strpos($k,'perms_') === 0) {
|
||||
$abook_my_perms += $v;
|
||||
|
||||
$all_perms = \Zotlabs\Access\Permissions::Perms();
|
||||
|
||||
if($all_perms) {
|
||||
foreach($all_perms as $perm => $desc) {
|
||||
if(array_key_exists('perms_' . $perm, $_POST)) {
|
||||
set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$perm,
|
||||
intval($_POST['perms_' . $perm]));
|
||||
if($autoperms) {
|
||||
set_pconfig($channel['channel_id'],'autoperms',$perm,intval($_POST['perms_' . $perm]));
|
||||
}
|
||||
}
|
||||
else {
|
||||
set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$perm,0);
|
||||
if($autoperms) {
|
||||
set_pconfig($channel['channel_id'],'autoperms',$perm,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(! is_null($autoperms))
|
||||
set_pconfig($channel['channel_id'],'system','autoperms',$autoperms);
|
||||
|
||||
$new_friend = false;
|
||||
|
||||
// only store a record and notify the directory if the rating changed
|
||||
|
||||
if(! $is_self) {
|
||||
|
||||
$signed = $orig_record[0]['abook_xchan'] . '.' . $rating . '.' . $rating_text;
|
||||
|
||||
$sig = base64url_encode(rsa_sign($signed,$channel['channel_prvkey']));
|
||||
|
||||
$rated = ((intval($rating) || strlen($rating_text)) ? true : false);
|
||||
|
||||
$record = 0;
|
||||
|
||||
$z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1",
|
||||
dbesc($channel['channel_hash']),
|
||||
@@ -149,17 +169,20 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
);
|
||||
|
||||
if($z) {
|
||||
$record = $z[0]['xlink_id'];
|
||||
$w = q("update xlink set xlink_rating = '%d', xlink_rating_text = '%s', xlink_sig = '%s', xlink_updated = '%s'
|
||||
where xlink_id = %d",
|
||||
intval($rating),
|
||||
dbesc($rating_text),
|
||||
dbesc($sig),
|
||||
dbesc(datetime_convert()),
|
||||
intval($record)
|
||||
);
|
||||
if(($z[0]['xlink_rating'] != $rating) || ($z[0]['xlink_rating_text'] != $rating_text)) {
|
||||
$record = $z[0]['xlink_id'];
|
||||
$w = q("update xlink set xlink_rating = '%d', xlink_rating_text = '%s', xlink_sig = '%s', xlink_updated = '%s'
|
||||
where xlink_id = %d",
|
||||
intval($rating),
|
||||
dbesc($rating_text),
|
||||
dbesc($sig),
|
||||
dbesc(datetime_convert()),
|
||||
intval($record)
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
elseif($rated) {
|
||||
// only create a record if there's something to save
|
||||
$w = q("insert into xlink ( xlink_xchan, xlink_link, xlink_rating, xlink_rating_text, xlink_sig, xlink_updated, xlink_static ) values ( '%s', '%s', %d, '%s', '%s', '%s', 1 ) ",
|
||||
dbesc($channel['channel_hash']),
|
||||
dbesc($orig_record[0]['abook_xchan']),
|
||||
@@ -194,19 +217,25 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
|
||||
$role = get_pconfig(local_channel(),'system','permissions_role');
|
||||
if($role) {
|
||||
$x = get_role_perms($role);
|
||||
if($x['perms_accept'])
|
||||
$abook_my_perms = $x['perms_accept'];
|
||||
$x = \Zotlabs\Access\PermissionRoles::role_perms($role);
|
||||
if($x['perms_connect']) {
|
||||
$abook_my_perms = $x['perms_connect'];
|
||||
}
|
||||
}
|
||||
|
||||
$filled_perms = \Zotlabs\Access\Permissions::FilledPerms($abook_my_perms);
|
||||
foreach($filled_perms as $k => $v) {
|
||||
set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$k,$v);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
$abook_pending = (($new_friend) ? 0 : $orig_record[0]['abook_pending']);
|
||||
|
||||
$r = q("UPDATE abook SET abook_profile = '%s', abook_my_perms = %d , abook_closeness = %d, abook_pending = %d,
|
||||
$r = q("UPDATE abook SET abook_profile = '%s', abook_closeness = %d, abook_pending = %d,
|
||||
abook_incl = '%s', abook_excl = '%s'
|
||||
where abook_id = %d AND abook_channel = %d",
|
||||
dbesc($profile_id),
|
||||
intval($abook_my_perms),
|
||||
intval($closeness),
|
||||
intval($abook_pending),
|
||||
dbesc($abook_incl),
|
||||
@@ -219,7 +248,7 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
//Update profile photo permissions
|
||||
|
||||
logger('A new profile was assigned - updating profile photos');
|
||||
profile_photo_set_profile_perms($profile_id);
|
||||
profile_photo_set_profile_perms(local_channel(),$profile_id);
|
||||
|
||||
}
|
||||
|
||||
@@ -227,10 +256,13 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
info( t('Connection updated.') . EOL);
|
||||
else
|
||||
notice( t('Failed to update connection record.') . EOL);
|
||||
|
||||
if(\App::$poi && \App::$poi['abook_my_perms'] != $abook_my_perms
|
||||
&& (! intval(\App::$poi['abook_self']))) {
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier', (($new_friend) ? 'permission_create' : 'permission_update'), $contact_id));
|
||||
|
||||
if(! intval(\App::$poi['abook_self'])) {
|
||||
\Zotlabs\Daemon\Master::Summon( [
|
||||
'Notifier',
|
||||
(($new_friend) ? 'permission_create' : 'permission_update'),
|
||||
$contact_id
|
||||
]);
|
||||
}
|
||||
|
||||
if($new_friend) {
|
||||
@@ -304,9 +336,6 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
call_hooks('accept_follow', $arr);
|
||||
}
|
||||
|
||||
if(! is_null($autoperms))
|
||||
set_pconfig(local_channel(),'system','autoperms',(($autoperms) ? $abook_my_perms : 0));
|
||||
|
||||
$this->connedit_clone($a);
|
||||
|
||||
if(($_REQUEST['pending']) && (!$_REQUEST['done']))
|
||||
@@ -345,7 +374,7 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
unset($clone['abook_account']);
|
||||
unset($clone['abook_channel']);
|
||||
|
||||
$abconfig = load_abconfig($channel['channel_hash'],$clone['abook_xchan']);
|
||||
$abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']);
|
||||
if($abconfig)
|
||||
$clone['abconfig'] = $abconfig;
|
||||
|
||||
@@ -357,7 +386,7 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
*
|
||||
*/
|
||||
|
||||
function get() {
|
||||
function get() {
|
||||
|
||||
$sort_type = 0;
|
||||
$o = '';
|
||||
@@ -371,9 +400,9 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
$my_perms = get_channel_default_perms(local_channel());
|
||||
$role = get_pconfig(local_channel(),'system','permissions_role');
|
||||
if($role) {
|
||||
$x = get_role_perms($role);
|
||||
if($x['perms_accept'])
|
||||
$my_perms = $x['perms_accept'];
|
||||
$x = \Zotlabs\Access\PermissionRoles::role_perms($role);
|
||||
if($x['perms_connect'])
|
||||
$my_perms = $x['perms_connect'];
|
||||
}
|
||||
|
||||
$yes_no = array(t('No'),t('Yes'));
|
||||
@@ -418,7 +447,13 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
goaway(z_root() . '/connedit/' . $contact_id);
|
||||
|
||||
}
|
||||
|
||||
if($cmd === 'resetphoto') {
|
||||
q("update xchan set xchan_photo_date = '2001-01-01 00:00:00' where xchan_hash = '%s' limit 1",
|
||||
dbesc($orig_record[0]['xchan_hash'])
|
||||
);
|
||||
$cmd = 'refresh';
|
||||
}
|
||||
|
||||
if($cmd === 'refresh') {
|
||||
if($orig_record[0]['xchan_network'] === 'zot') {
|
||||
if(! zot_refresh($orig_record[0],\App::get_channel()))
|
||||
@@ -427,7 +462,7 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
else {
|
||||
|
||||
// if you are on a different network we'll force a refresh of the connection basic info
|
||||
Zotlabs\Daemon\Master::Summon(array('Notifier','permission_update',$contact_id));
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier','permission_update',$contact_id));
|
||||
}
|
||||
goaway(z_root() . '/connedit/' . $contact_id);
|
||||
}
|
||||
@@ -648,7 +683,8 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
$perms = array();
|
||||
$channel = \App::get_channel();
|
||||
|
||||
$global_perms = get_perms();
|
||||
$global_perms = \Zotlabs\Access\Permissions::Perms();
|
||||
|
||||
$existing = get_all_perms(local_channel(),$contact['abook_xchan']);
|
||||
|
||||
$unapproved = array('pending', t('Approve this connection'), '', t('Accept connection to allow communication'), array(t('No'),('Yes')));
|
||||
@@ -664,16 +700,32 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
if($slide && $multiprofs)
|
||||
$affinity = t('Set Affinity & Profile');
|
||||
|
||||
$theirs = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'their_perms'",
|
||||
intval(local_channel()),
|
||||
dbesc($contact['abook_xchan'])
|
||||
);
|
||||
$their_perms = array();
|
||||
if($theirs) {
|
||||
foreach($theirs as $t) {
|
||||
$their_perms[$t['k']] = $t['v'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach($global_perms as $k => $v) {
|
||||
$thisperm = (($contact['abook_my_perms'] & $v[1]) ? "1" : '');
|
||||
$checkinherited = ((($channel[$v[0]]) && ($channel[$v[0]] != PERMS_SPECIFIC)) ? "1" : '');
|
||||
$thisperm = get_abconfig(local_channel(),$contact['abook_xchan'],'my_perms',$k);
|
||||
//fixme
|
||||
|
||||
$checkinherited = \Zotlabs\Access\PermissionLimits::Get(local_channel(),$k);
|
||||
|
||||
// For auto permissions (when $self is true) we don't want to look at existing
|
||||
// permissions because they are enabled for the channel owner
|
||||
if((! $self) && ($existing[$k]))
|
||||
$thisperm = "1";
|
||||
|
||||
|
||||
|
||||
|
||||
$perms[] = array('perms_' . $k, $v[3], (($contact['abook_their_perms'] & $v[1]) ? "1" : ""),$thisperm, $v[1], (($channel[$v[0]] == PERMS_SPECIFIC) ? '' : '1'), $v[4], $checkinherited);
|
||||
$perms[] = array('perms_' . $k, $v, ((array_key_exists($k,$their_perms)) ? intval($their_perms[$k]) : ''),$thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '' : '1'), '', $checkinherited);
|
||||
}
|
||||
|
||||
$locstr = '';
|
||||
|
||||
@@ -29,7 +29,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
$channel = \App::get_channel();
|
||||
profile_load($a,$channel['channel_address']);
|
||||
profile_load($channel['channel_address']);
|
||||
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
*
|
||||
*/
|
||||
|
||||
function post() {
|
||||
function post() {
|
||||
|
||||
if(! local_channel()) {
|
||||
return;
|
||||
@@ -50,7 +50,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
|
||||
check_form_security_token_redirectOnErr('/cover_photo', 'cover_photo');
|
||||
|
||||
if((x($_POST,'cropfinal')) && ($_POST['cropfinal'] == 1)) {
|
||||
if((array_key_exists('cropfinal',$_POST)) && ($_POST['cropfinal'] == 1)) {
|
||||
|
||||
// phase 2 - we have finished cropping
|
||||
|
||||
@@ -271,7 +271,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
*/
|
||||
|
||||
|
||||
function get() {
|
||||
function get() {
|
||||
|
||||
if(! local_channel()) {
|
||||
notice( t('Permission denied.') . EOL );
|
||||
|
||||
@@ -14,6 +14,7 @@ use \Zotlabs\Storage;
|
||||
// composer autoloader for SabreDAV
|
||||
require_once('vendor/autoload.php');
|
||||
|
||||
require_once('include/attach.php');
|
||||
|
||||
/**
|
||||
* @brief Fires up the SabreDAV server.
|
||||
@@ -44,60 +45,16 @@ class Dav extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
require_once('include/reddav.php');
|
||||
|
||||
if (! is_dir('store'))
|
||||
os_mkdir('store', STORAGE_DEFAULT_PERMISSIONS, false);
|
||||
|
||||
$which = null;
|
||||
if (argc() > 1)
|
||||
$which = argv(1);
|
||||
profile_load(argv(1),0);
|
||||
|
||||
$profile = 0;
|
||||
|
||||
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which . '" />' . "\r\n";
|
||||
|
||||
if ($which)
|
||||
profile_load($a, $which, $profile);
|
||||
|
||||
|
||||
|
||||
|
||||
$auth = new \Zotlabs\Storage\BasicAuth();
|
||||
$auth->setRealm(ucfirst(\Zotlabs\Lib\System::get_platform_name()) . 'WebDAV');
|
||||
$auth->setRealm(ucfirst(\Zotlabs\Lib\System::get_platform_name()) . ' ' . 'WebDAV');
|
||||
|
||||
// $authBackend = new \Sabre\DAV\Auth\Backend\BasicCallBack(function($userName,$password) {
|
||||
// if(account_verify_password($userName,$password))
|
||||
// return true;
|
||||
// return false;
|
||||
// });
|
||||
|
||||
// $ob_hash = get_observer_hash();
|
||||
|
||||
// if ($ob_hash) {
|
||||
// if (local_channel()) {
|
||||
// $channel = \App::get_channel();
|
||||
// $auth->setCurrentUser($channel['channel_address']);
|
||||
// $auth->channel_id = $channel['channel_id'];
|
||||
// $auth->channel_hash = $channel['channel_hash'];
|
||||
// $auth->channel_account_id = $channel['channel_account_id'];
|
||||
// if($channel['channel_timezone'])
|
||||
// $auth->setTimezone($channel['channel_timezone']);
|
||||
// }
|
||||
// $auth->observer = $ob_hash;
|
||||
// }
|
||||
|
||||
// if ($_GET['davguest'])
|
||||
// $_SESSION['davguest'] = true;
|
||||
|
||||
// $_SERVER['QUERY_STRING'] = str_replace(array('?f=', '&f='), array('', ''), $_SERVER['QUERY_STRING']);
|
||||
// $_SERVER['QUERY_STRING'] = strip_zids($_SERVER['QUERY_STRING']);
|
||||
// $_SERVER['QUERY_STRING'] = preg_replace('/[\?&]davguest=(.*?)([\?&]|$)/ism', '', $_SERVER['QUERY_STRING']);
|
||||
//
|
||||
// $_SERVER['REQUEST_URI'] = str_replace(array('?f=', '&f='), array('', ''), $_SERVER['REQUEST_URI']);
|
||||
// $_SERVER['REQUEST_URI'] = strip_zids($_SERVER['REQUEST_URI']);
|
||||
// $_SERVER['REQUEST_URI'] = preg_replace('/[\?&]davguest=(.*?)([\?&]|$)/ism', '', $_SERVER['REQUEST_URI']);
|
||||
|
||||
$rootDirectory = new \Zotlabs\Storage\Directory('/', $auth);
|
||||
|
||||
// A SabreDAV server-object
|
||||
@@ -114,48 +71,13 @@ class Dav extends \Zotlabs\Web\Controller {
|
||||
|
||||
$server->addPlugin($lockPlugin);
|
||||
|
||||
// The next section of code allows us to bypass prompting for http-auth if a
|
||||
// FILE is being accessed anonymously and permissions allow this. This way
|
||||
// one can create hotlinks to public media files in their cloud and anonymous
|
||||
// viewers won't get asked to login.
|
||||
// If a DIRECTORY is accessed or there are permission issues accessing the
|
||||
// file and we aren't previously authenticated via zot, prompt for HTTP-auth.
|
||||
// This will be the default case for mounting a DAV directory.
|
||||
// In order to avoid prompting for passwords for viewing a DIRECTORY, add
|
||||
// the URL query parameter 'davguest=1'.
|
||||
|
||||
// $isapublic_file = false;
|
||||
// $davguest = ((x($_SESSION, 'davguest')) ? true : false);
|
||||
|
||||
// if ((! $auth->observer) && ($_SERVER['REQUEST_METHOD'] === 'GET')) {
|
||||
// try {
|
||||
// $x = RedFileData('/' . \App::$cmd, $auth);
|
||||
// if($x instanceof \Zotlabs\Storage\File)
|
||||
// $isapublic_file = true;
|
||||
// }
|
||||
// catch (Exception $e) {
|
||||
// $isapublic_file = false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if ((! $auth->observer) && (! $isapublic_file) && (! $davguest)) {
|
||||
// try {
|
||||
// $auth->Authenticate($server, t('$Projectname channel'));
|
||||
// }
|
||||
// catch (Exception $e) {
|
||||
// logger('mod_cloud: auth exception' . $e->getMessage());
|
||||
// http_status_exit($e->getHTTPCode(), $e->getMessage());
|
||||
// }
|
||||
// }
|
||||
|
||||
// require_once('Zotlabs/Storage/Browser.php');
|
||||
// provide a directory view for the cloud in Hubzilla
|
||||
$browser = new \Zotlabs\Storage\Browser($auth);
|
||||
$auth->setBrowserPlugin($browser);
|
||||
|
||||
// Experimental QuotaPlugin
|
||||
// require_once('Zotlabs/Storage/QuotaPlugin.php');
|
||||
// $server->addPlugin(new \Zotlabs\Storage\QuotaPlugin($auth));
|
||||
// require_once('Zotlabs/Storage/QuotaPlugin.php');
|
||||
// $server->addPlugin(new \Zotlabs\Storage\QuotaPlugin($auth));
|
||||
|
||||
// All we need to do now, is to fire up the server
|
||||
$server->exec();
|
||||
|
||||
@@ -65,6 +65,7 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
'lockstate' => (($group || $cid || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
|
||||
|
||||
'acl' => populate_acl($channel_acl),
|
||||
'permissions' => $channel_acl,
|
||||
'bang' => '',
|
||||
'visitor' => true,
|
||||
'profile_uid' => local_channel(),
|
||||
@@ -106,12 +107,13 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
$x = q("select * from channel where channel_id = %d limit 1",
|
||||
intval($target_item['uid'])
|
||||
);
|
||||
$y = q("select * from item_id where uid = %d and service = 'WEBPAGE' and iid = %d limit 1",
|
||||
$y = q("select * from iconfig left join item on iconfig.iid = item.id
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'WEBPAGE' and item.id = %d limit 1",
|
||||
intval($target_item['uid']),
|
||||
intval($target_item['id'])
|
||||
);
|
||||
if($x && $y) {
|
||||
goaway(z_root() . '/page/' . $x[0]['channel_address'] . '/' . $y[0]['sid']);
|
||||
goaway(z_root() . '/page/' . $x[0]['channel_address'] . '/' . $y[0]['v']);
|
||||
}
|
||||
else {
|
||||
notice( t('Page not found.') . EOL);
|
||||
|
||||
@@ -16,7 +16,24 @@ class Dreport extends \Zotlabs\Web\Controller {
|
||||
$channel = \App::get_channel();
|
||||
|
||||
$mid = ((argc() > 1) ? argv(1) : '');
|
||||
|
||||
|
||||
if($mid === 'push') {
|
||||
$table = 'push';
|
||||
$mid = ((argc() > 2) ? argv(2) : '');
|
||||
if($mid) {
|
||||
$i = q("select id from item where mid = '%s' and author_xchan = '%s' and uid = %d",
|
||||
dbesc($mid),
|
||||
dbesc($channel['channel_hash']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if($i) {
|
||||
\Zotlabs\Daemon\Master::Summon([ 'Notifier', 'edit_post', $i[0]['id'] ]);
|
||||
}
|
||||
}
|
||||
sleep(3);
|
||||
goaway(z_root() . '/dreport/' . urlencode($mid));
|
||||
}
|
||||
|
||||
if($mid === 'mail') {
|
||||
$table = 'mail';
|
||||
$mid = ((argc() > 2) ? argv(2) : '');
|
||||
@@ -59,11 +76,7 @@ class Dreport extends \Zotlabs\Web\Controller {
|
||||
notice( t('no results') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$o .= '<div class="generic-content-wrapper-styled">';
|
||||
$o .= '<h2>' . sprintf( t('Delivery report for %1$s'),substr($mid,0,32)) . '...' . '</h2>';
|
||||
$o .= '<table>';
|
||||
|
||||
|
||||
for($x = 0; $x < count($r); $x++ ) {
|
||||
$r[$x]['name'] = escape_tags(substr($r[$x]['dreport_recip'],strpos($r[$x]['dreport_recip'],' ')));
|
||||
|
||||
@@ -119,13 +132,25 @@ class Dreport extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
usort($r,'self::dreport_gravity_sort');
|
||||
|
||||
|
||||
|
||||
$entries = array();
|
||||
foreach($r as $rr) {
|
||||
$o .= '<tr><td width="40%">' . $rr['name'] . '</td><td width="20%">' . escape_tags($rr['dreport_result']) . '</td><td width="20%">' . escape_tags($rr['dreport_time']) . '</td></tr>';
|
||||
$entries[] = [
|
||||
'name' => $rr['name'],
|
||||
'result' => escape_tags($rr['dreport_result']),
|
||||
'time' => escape_tags(datetime_convert('UTC',date_default_timezone_get(),$rr['dreport_time']))
|
||||
];
|
||||
}
|
||||
$o .= '</table>';
|
||||
$o .= '</div>';
|
||||
|
||||
$o = replace_macros(get_markup_template('dreport.tpl'), array(
|
||||
'$title' => sprintf( t('Delivery report for %1$s'),substr($mid,0,32)) . '...',
|
||||
'$table' => $table,
|
||||
'$mid' => urlencode($mid),
|
||||
'$options' => t('Options'),
|
||||
'$push' => t('Redeliver'),
|
||||
'$entries' => $entries
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ class Editblock extends \Zotlabs\Web\Controller {
|
||||
else
|
||||
return;
|
||||
|
||||
profile_load($a,$which);
|
||||
profile_load($which);
|
||||
|
||||
}
|
||||
|
||||
@@ -85,11 +85,11 @@ class Editblock extends \Zotlabs\Web\Controller {
|
||||
intval($owner)
|
||||
);
|
||||
if($itm) {
|
||||
$item_id = q("select * from item_id where service = 'BUILDBLOCK' and iid = %d limit 1",
|
||||
$item_id = q("select * from iconfig where cat = 'system' and k = 'BUILDBLOCK' and iid = %d limit 1",
|
||||
intval($itm[0]['id'])
|
||||
);
|
||||
if($item_id)
|
||||
$block_title = $item_id[0]['sid'];
|
||||
$block_title = $item_id[0]['v'];
|
||||
}
|
||||
else {
|
||||
notice( t('Item not found') . EOL);
|
||||
|
||||
@@ -21,7 +21,7 @@ class Editlayout extends \Zotlabs\Web\Controller {
|
||||
else
|
||||
return;
|
||||
|
||||
profile_load($a,$which);
|
||||
profile_load($which);
|
||||
|
||||
}
|
||||
|
||||
@@ -96,11 +96,12 @@ class Editlayout extends \Zotlabs\Web\Controller {
|
||||
intval($owner)
|
||||
);
|
||||
|
||||
$item_id = q("select * from item_id where service = 'PDL' and iid = %d limit 1",
|
||||
$item_id = q("select * from iconfig where cat = 'system' and k = 'PDL' and iid = %d limit 1",
|
||||
intval($itm[0]['id'])
|
||||
);
|
||||
if($item_id)
|
||||
$layout_title = $item_id[0]['sid'];
|
||||
$layout_title = $item_id[0]['v'];
|
||||
|
||||
|
||||
$rp = 'layouts/' . $which;
|
||||
|
||||
|
||||
@@ -47,9 +47,9 @@ class Editpost extends \Zotlabs\Web\Controller {
|
||||
if(intval($itm[0]['item_obscured'])) {
|
||||
$key = get_config('system','prvkey');
|
||||
if($itm[0]['title'])
|
||||
$itm[0]['title'] = crypto_unencapsulate(json_decode_plus($itm[0]['title']),$key);
|
||||
$itm[0]['title'] = crypto_unencapsulate(json_decode($itm[0]['title'],true),$key);
|
||||
if($itm[0]['body'])
|
||||
$itm[0]['body'] = crypto_unencapsulate(json_decode_plus($itm[0]['body']),$key);
|
||||
$itm[0]['body'] = crypto_unencapsulate(json_decode($itm[0]['body'],true),$key);
|
||||
}
|
||||
|
||||
$category = '';
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace Zotlabs\Module;
|
||||
require_once('include/channel.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/PermissionDescription.php');
|
||||
|
||||
|
||||
class Editwebpage extends \Zotlabs\Web\Controller {
|
||||
@@ -23,7 +22,7 @@ class Editwebpage extends \Zotlabs\Web\Controller {
|
||||
else
|
||||
return;
|
||||
|
||||
profile_load($a,$which);
|
||||
profile_load($which);
|
||||
|
||||
}
|
||||
|
||||
@@ -109,16 +108,16 @@ class Editwebpage extends \Zotlabs\Web\Controller {
|
||||
if(intval($itm[0]['item_obscured'])) {
|
||||
$key = get_config('system','prvkey');
|
||||
if($itm[0]['title'])
|
||||
$itm[0]['title'] = crypto_unencapsulate(json_decode_plus($itm[0]['title']),$key);
|
||||
$itm[0]['title'] = crypto_unencapsulate(json_decode($itm[0]['title'],true),$key);
|
||||
if($itm[0]['body'])
|
||||
$itm[0]['body'] = crypto_unencapsulate(json_decode_plus($itm[0]['body']),$key);
|
||||
$itm[0]['body'] = crypto_unencapsulate(json_decode($itm[0]['body'],true),$key);
|
||||
}
|
||||
|
||||
$item_id = q("select * from item_id where service = 'WEBPAGE' and iid = %d limit 1",
|
||||
$item_id = q("select * from iconfig where cat = 'system' and k = 'WEBPAGE' and iid = %d limit 1",
|
||||
intval($itm[0]['id'])
|
||||
);
|
||||
if($item_id)
|
||||
$page_title = $item_id[0]['sid'];
|
||||
$page_title = $item_id[0]['v'];
|
||||
|
||||
$mimetype = $itm[0]['mimetype'];
|
||||
|
||||
@@ -151,7 +150,8 @@ class Editwebpage extends \Zotlabs\Web\Controller {
|
||||
'body' => undo_post_tagging($itm[0]['body']),
|
||||
'post_id' => $post_id,
|
||||
'visitor' => ($is_owner) ? true : false,
|
||||
'acl' => populate_acl($itm[0],false,\PermissionDescription::fromGlobalPermission('view_pages')),
|
||||
'acl' => populate_acl($itm[0],false,\Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')),
|
||||
'permissions' => $itm[0],
|
||||
'showacl' => ($is_owner) ? true : false,
|
||||
'mimetype' => $mimetype,
|
||||
'mimeselect' => true,
|
||||
|
||||
182
Zotlabs/Module/Embedphotos.php
Normal file
182
Zotlabs/Module/Embedphotos.php
Normal file
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
/**
|
||||
*
|
||||
* This is the POST destination for the embedphotos button
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
class Embedphotos extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
}
|
||||
|
||||
function post() {
|
||||
|
||||
if (argc() > 1 && argv(1) === 'album') {
|
||||
// API: /embedphotos/album
|
||||
$name = (x($_POST,'name') ? $_POST['name'] : null );
|
||||
if (!$name) {
|
||||
json_return_and_die(array('errormsg' => 'Error retrieving album', 'status' => false));
|
||||
}
|
||||
$album = $this->embedphotos_widget_album(array('channel' => \App::get_channel(), 'album' => $name));
|
||||
json_return_and_die(array('status' => true, 'content' => $album));
|
||||
|
||||
}
|
||||
if (argc() > 1 && argv(1) === 'albumlist') {
|
||||
// API: /embedphotos/albumlist
|
||||
$album_list = $this->embedphotos_album_list($a);
|
||||
json_return_and_die(array('status' => true, 'albumlist' => $album_list));
|
||||
|
||||
}
|
||||
if (argc() > 1 && argv(1) === 'photolink') {
|
||||
// API: /embedphotos/photolink
|
||||
$href = (x($_POST,'href') ? $_POST['href'] : null );
|
||||
if (!$href) {
|
||||
json_return_and_die(array('errormsg' => 'Error retrieving link ' . $href, 'status' => false));
|
||||
}
|
||||
$resource_id = array_pop(explode("/", $href));
|
||||
$r = q("SELECT obj,body from item where resource_type = 'photo' and resource_id = '%s' limit 1",
|
||||
dbesc($resource_id)
|
||||
);
|
||||
if(!$r) {
|
||||
json_return_and_die(array('errormsg' => 'Error retrieving resource ' . $resource_id, 'status' => false));
|
||||
}
|
||||
$obj = json_decode($r[0]['obj'], true);
|
||||
if(x($obj,'body')) {
|
||||
$photolink = $obj['body'];
|
||||
} elseif (x($obj,'bbcode')) {
|
||||
$photolink = $obj['bbcode'];
|
||||
} elseif ($r[0]['body'] !== '') {
|
||||
$photolink = $r[0]['body'];
|
||||
} else {
|
||||
json_return_and_die(array('errormsg' => 'Error retrieving resource ' . $resource_id, 'status' => false));
|
||||
}
|
||||
json_return_and_die(array('status' => true, 'photolink' => $photolink));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copied from include/widgets.php::widget_album() with a modification to get the profile_uid from
|
||||
* the input array as in widget_item()
|
||||
* @param type $name
|
||||
* @return string
|
||||
*/
|
||||
function embedphotos_widget_album($args) {
|
||||
|
||||
$channel_id = 0;
|
||||
if(array_key_exists('channel',$args))
|
||||
$channel = $args['channel'];
|
||||
$channel_id = intval($channel['channel_id']);
|
||||
if(! $channel_id)
|
||||
$channel_id = \App::$profile_uid;
|
||||
if(! $channel_id)
|
||||
return '';
|
||||
$owner_uid = $channel_id;
|
||||
require_once('include/security.php');
|
||||
$sql_extra = permissions_sql($channel_id);
|
||||
|
||||
if(! perm_is_allowed($channel_id,get_observer_hash(),'view_storage'))
|
||||
return '';
|
||||
|
||||
if($args['album'])
|
||||
$album = (($args['album'] === '/') ? '' : $args['album'] );
|
||||
if($args['title'])
|
||||
$title = $args['title'];
|
||||
|
||||
/**
|
||||
* This may return incorrect permissions if you have multiple directories of the same name.
|
||||
* It is a limitation of the photo table using a name for a photo album instead of a folder hash
|
||||
*/
|
||||
|
||||
if($album) {
|
||||
$x = q("select hash from attach where filename = '%s' and uid = %d limit 1",
|
||||
dbesc($album),
|
||||
intval($owner_uid)
|
||||
);
|
||||
if($x) {
|
||||
$y = attach_can_view_folder($owner_uid,get_observer_hash(),$x[0]['hash']);
|
||||
if(! $y)
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
$order = 'DESC';
|
||||
|
||||
$r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.imgscale, p.description, p.created FROM photo p INNER JOIN
|
||||
(SELECT resource_id, max(imgscale) imgscale FROM photo WHERE uid = %d AND album = '%s' AND imgscale <= 4 AND photo_usage IN ( %d, %d ) $sql_extra GROUP BY resource_id) ph
|
||||
ON (p.resource_id = ph.resource_id AND p.imgscale = ph.imgscale)
|
||||
ORDER BY created $order",
|
||||
intval($owner_uid),
|
||||
dbesc($album),
|
||||
intval(PHOTO_NORMAL),
|
||||
intval(PHOTO_PROFILE)
|
||||
);
|
||||
|
||||
$photos = array();
|
||||
if(count($r)) {
|
||||
$twist = 'rotright';
|
||||
foreach($r as $rr) {
|
||||
|
||||
if($twist == 'rotright')
|
||||
$twist = 'rotleft';
|
||||
else
|
||||
$twist = 'rotright';
|
||||
|
||||
$ext = $phototypes[$rr['mimetype']];
|
||||
|
||||
$imgalt_e = $rr['filename'];
|
||||
$desc_e = $rr['description'];
|
||||
|
||||
$imagelink = (z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/image/' . $rr['resource_id']
|
||||
. (($_GET['order'] === 'posted') ? '?f=&order=posted' : ''));
|
||||
|
||||
$photos[] = array(
|
||||
'id' => $rr['id'],
|
||||
'twist' => ' ' . $twist . rand(2,4),
|
||||
'link' => $imagelink,
|
||||
'title' => t('View Photo'),
|
||||
'src' => z_root() . '/photo/' . $rr['resource_id'] . '-' . $rr['imgscale'] . '.' .$ext,
|
||||
'alt' => $imgalt_e,
|
||||
'desc'=> $desc_e,
|
||||
'ext' => $ext,
|
||||
'hash'=> $rr['resource_id'],
|
||||
'unknown' => t('Unknown')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$tpl = get_markup_template('photo_album.tpl');
|
||||
$o .= replace_macros($tpl, array(
|
||||
'$photos' => $photos,
|
||||
'$album' => (($title) ? $title : $album),
|
||||
'$album_id' => rand(),
|
||||
'$album_edit' => array(t('Edit Album'), $album_edit),
|
||||
'$can_post' => false,
|
||||
'$upload' => array(t('Upload'), z_root() . '/photos/' . \App::$profile['channel_address'] . '/upload/' . bin2hex($album)),
|
||||
'$order' => false,
|
||||
'$upload_form' => $upload_form,
|
||||
'$no_fullscreen_btn' => true
|
||||
));
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
function embedphotos_album_list($a) {
|
||||
$o = '';
|
||||
require_once('include/photos.php');
|
||||
$p = photos_albums_list(\App::get_channel(), \App::get_observer());
|
||||
if ($p['success']) {
|
||||
return $p['albums'];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,7 +6,6 @@ require_once('include/bbcode.php');
|
||||
require_once('include/datetime.php');
|
||||
require_once('include/event.php');
|
||||
require_once('include/items.php');
|
||||
require_once('include/PermissionDescription.php');
|
||||
|
||||
|
||||
class Events extends \Zotlabs\Web\Controller {
|
||||
@@ -436,6 +435,10 @@ class Events extends \Zotlabs\Web\Controller {
|
||||
|
||||
$acl = new \Zotlabs\Access\AccessList($channel);
|
||||
$perm_defaults = $acl->get();
|
||||
|
||||
$permissions = ((x($orig_event)) ? $orig_event : $perm_defaults);
|
||||
|
||||
//print_r(acl2json($permissions['allow_gid'])); killme();
|
||||
|
||||
$tpl = get_markup_template('event_form.tpl');
|
||||
|
||||
@@ -468,10 +471,16 @@ class Events extends \Zotlabs\Web\Controller {
|
||||
'$sh_checked' => $sh_checked,
|
||||
'$share' => array('share', t('Share this event'), $sh_checked, '', array(t('No'),t('Yes'))),
|
||||
'$preview' => t('Preview'),
|
||||
'$permissions' => t('Permission settings'),
|
||||
'$perms_label' => t('Permission settings'),
|
||||
// populating the acl dialog was a permission description from view_stream because Cal.php, which
|
||||
// displays events, says "since we don't currently have an event permission - use the stream permission"
|
||||
'$acl' => (($orig_event['event_xchan']) ? '' : populate_acl(((x($orig_event)) ? $orig_event : $perm_defaults), false, \PermissionDescription::fromGlobalPermission('view_stream'))),
|
||||
'$acl' => (($orig_event['event_xchan']) ? '' : populate_acl(((x($orig_event)) ? $orig_event : $perm_defaults), false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'))),
|
||||
|
||||
'$allow_cid' => acl2json($permissions['allow_cid']),
|
||||
'$allow_gid' => acl2json($permissions['allow_gid']),
|
||||
'$deny_cid' => acl2json($permissions['deny_cid']),
|
||||
'$deny_gid' => acl2json($permissions['deny_gid']),
|
||||
|
||||
'$submit' => t('Submit'),
|
||||
'$advanced' => t('Advanced Options')
|
||||
|
||||
@@ -668,8 +677,10 @@ class Events extends \Zotlabs\Web\Controller {
|
||||
'$export' => array(z_root()."/events/$y/$m/export",t('Export'),'',''),
|
||||
'$calendar' => cal($y,$m,$links, ' eventcal'),
|
||||
'$events' => $events,
|
||||
'$upload' => t('Import'),
|
||||
'$submit' => t('Submit'),
|
||||
'$view_label' => t('View'),
|
||||
'$month' => t('Month'),
|
||||
'$week' => t('Week'),
|
||||
'$day' => t('Day'),
|
||||
'$prev' => t('Previous'),
|
||||
'$next' => t('Next'),
|
||||
'$today' => t('Today'),
|
||||
|
||||
45
Zotlabs/Module/File_upload.php
Normal file
45
Zotlabs/Module/File_upload.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/attach.php');
|
||||
require_once('include/channel.php');
|
||||
require_once('include/photos.php');
|
||||
|
||||
|
||||
class File_upload extends \Zotlabs\Web\Controller {
|
||||
|
||||
function post() {
|
||||
|
||||
// logger('file upload: ' . print_r($_REQUEST,true));
|
||||
|
||||
$channel = (($_REQUEST['channick']) ? get_channel_by_nick($_REQUEST['channick']) : null);
|
||||
|
||||
if(! $channel) {
|
||||
logger('channel not found');
|
||||
killme();
|
||||
}
|
||||
|
||||
$_REQUEST['source'] = 'file_upload';
|
||||
|
||||
if($channel['channel_id'] != local_channel()) {
|
||||
$_REQUEST['contact_allow'] = expand_acl($channel['channel_allow_cid']);
|
||||
$_REQUEST['group_allow'] = expand_acl($channel['channel_allow_gid']);
|
||||
$_REQUEST['contact_deny'] = expand_acl($channel['channel_deny_cid']);
|
||||
$_REQUEST['group_deny'] = expand_acl($channel['channel_deny_gid']);
|
||||
}
|
||||
|
||||
if($_REQUEST['filename']) {
|
||||
$_REQUEST['allow_cid'] = perms2str($_REQUEST['contact_allow']);
|
||||
$_REQUEST['allow_gid'] = perms2str($_REQUEST['group_allow']);
|
||||
$_REQUEST['deny_cid'] = perms2str($_REQUEST['contact_deny']);
|
||||
$_REQUEST['deny_gid'] = perms2str($_REQUEST['group_deny']);
|
||||
$r = attach_mkdir($channel,get_observer_hash(),$_REQUEST);
|
||||
}
|
||||
else {
|
||||
$r = attach_store($channel,get_observer_hash(), '', $_REQUEST);
|
||||
}
|
||||
goaway(z_root() . '/' . $_REQUEST['return_url']);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,7 +6,6 @@ namespace Zotlabs\Module;
|
||||
*/
|
||||
|
||||
require_once('include/attach.php');
|
||||
require_once('include/PermissionDescription.php');
|
||||
|
||||
|
||||
/**
|
||||
@@ -134,7 +133,7 @@ class Filestorage extends \Zotlabs\Web\Controller {
|
||||
$cloudpath = get_cloudpath($f) . (intval($f['is_dir']) ? '?f=&davguest=1' : '');
|
||||
$parentpath = get_parent_cloudpath($channel['channel_id'], $channel['channel_address'], $f['hash']);
|
||||
|
||||
$aclselect_e = populate_acl($f, false, \PermissionDescription::fromGlobalPermission('view_storage'));
|
||||
$aclselect_e = populate_acl($f, false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_storage'));
|
||||
$is_a_dir = (intval($f['is_dir']) ? true : false);
|
||||
|
||||
$lockstate = (($f['allow_cid'] || $f['allow_gid'] || $f['deny_cid'] || $f['deny_gid']) ? 'lock' : 'unlock');
|
||||
@@ -142,7 +141,7 @@ class Filestorage extends \Zotlabs\Web\Controller {
|
||||
// Encode path that is used for link so it's a valid URL
|
||||
// Keep slashes as slashes, otherwise mod_rewrite doesn't work correctly
|
||||
$encoded_path = str_replace('%2F', '/', rawurlencode($cloudpath));
|
||||
|
||||
|
||||
$o = replace_macros(get_markup_template('attach_edit.tpl'), array(
|
||||
'$header' => t('Edit file permissions'),
|
||||
'$file' => $f,
|
||||
@@ -152,6 +151,10 @@ class Filestorage extends \Zotlabs\Web\Controller {
|
||||
'$channelnick' => $channel['channel_address'],
|
||||
'$permissions' => t('Permissions'),
|
||||
'$aclselect' => $aclselect_e,
|
||||
'$allow_cid' => acl2json($f['allow_cid']),
|
||||
'$allow_gid' => acl2json($f['allow_gid']),
|
||||
'$deny_cid' => acl2json($f['deny_cid']),
|
||||
'$deny_gid' => acl2json($f['deny_gid']),
|
||||
'$lockstate' => $lockstate,
|
||||
'$permset' => t('Set/edit permissions'),
|
||||
'$recurse' => array('recurse', t('Include all files and sub folders'), 0, '', array(t('No'), t('Yes'))),
|
||||
@@ -162,7 +165,7 @@ class Filestorage extends \Zotlabs\Web\Controller {
|
||||
'$submit' => t('Submit'),
|
||||
'$attach_btn_title' => t('Share this file'),
|
||||
'$link_btn_title' => t('Show URL to this file'),
|
||||
'$notify' => array('notify', t('Notify your contacts about this file'), 0, '', array(t('No'), t('Yes')))
|
||||
'$notify' => array('notify', t('Notify your contacts about this file'), 0, '', array(t('No'), t('Yes'))),
|
||||
));
|
||||
|
||||
echo $o;
|
||||
|
||||
@@ -43,16 +43,17 @@ class Follow extends \Zotlabs\Web\Controller {
|
||||
unset($clone['abook_account']);
|
||||
unset($clone['abook_channel']);
|
||||
|
||||
$abconfig = load_abconfig($channel['channel_hash'],$clone['abook_xchan']);
|
||||
$abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']);
|
||||
if($abconfig)
|
||||
$clone['abconfig'] = $abconfig;
|
||||
|
||||
build_sync_packet(0 /* use the current local_channel */, array('abook' => array($clone)));
|
||||
build_sync_packet(0 /* use the current local_channel */, array('abook' => array($clone)), true);
|
||||
|
||||
$can_view_stream = intval(get_abconfig($channel['channel_id'],$clone['abook_xchan'],'their_perms','view_stream'));
|
||||
|
||||
// If we can view their stream, pull in some posts
|
||||
|
||||
if(($result['abook']['abook_their_perms'] & PERMS_R_STREAM) || ($result['abook']['xchan_network'] === 'rss'))
|
||||
if(($can_view_stream) || ($result['abook']['xchan_network'] === 'rss'))
|
||||
\Zotlabs\Daemon\Master::Summon(array('Onepoll',$result['abook']['abook_id']));
|
||||
|
||||
goaway(z_root() . '/connedit/' . $result['abook']['abook_id'] . '?f=&follow=1');
|
||||
|
||||
@@ -101,7 +101,7 @@ class Group extends \Zotlabs\Web\Controller {
|
||||
check_form_security_token_redirectOnErr('/group', 'group_drop', 't');
|
||||
|
||||
if(intval(argv(2))) {
|
||||
$r = q("SELECT `name` FROM `groups` WHERE `id` = %d AND `uid` = %d LIMIT 1",
|
||||
$r = q("SELECT `gname` FROM `groups` WHERE `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval(argv(2)),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
@@ -40,7 +40,7 @@ class Hcard extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
profile_load($a,$which,$profile);
|
||||
profile_load($which,$profile);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -28,6 +28,19 @@ class Home extends \Zotlabs\Web\Controller {
|
||||
|
||||
goaway($dest);
|
||||
}
|
||||
|
||||
if(remote_channel() && (! $splash) && $_SESSION['atoken']) {
|
||||
$r = q("select * from atoken where atoken_id = %d",
|
||||
intval($_SESSION['atoken'])
|
||||
);
|
||||
if($r) {
|
||||
$x = channelx_by_n($r[0]['atoken_uid']);
|
||||
if($x) {
|
||||
goaway(z_root() . '/channel/' . $x['channel_address']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(get_account_id() && ! $splash) {
|
||||
goaway(z_root() . '/new_channel');
|
||||
|
||||
@@ -1,319 +0,0 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
/**
|
||||
* @file mod/id.php
|
||||
* @brief OpenID implementation
|
||||
*/
|
||||
|
||||
require 'library/openid/provider/provider.php';
|
||||
|
||||
|
||||
$attrMap = array(
|
||||
'namePerson/first' => t('First Name'),
|
||||
'namePerson/last' => t('Last Name'),
|
||||
'namePerson/friendly' => t('Nickname'),
|
||||
'namePerson' => t('Full Name'),
|
||||
'contact/internet/email' => t('Email'),
|
||||
'contact/email' => t('Email'),
|
||||
'media/image/aspect11' => t('Profile Photo'),
|
||||
'media/image' => t('Profile Photo'),
|
||||
'media/image/default' => t('Profile Photo'),
|
||||
'media/image/16x16' => t('Profile Photo 16px'),
|
||||
'media/image/32x32' => t('Profile Photo 32px'),
|
||||
'media/image/48x48' => t('Profile Photo 48px'),
|
||||
'media/image/64x64' => t('Profile Photo 64px'),
|
||||
'media/image/80x80' => t('Profile Photo 80px'),
|
||||
'media/image/128x128' => t('Profile Photo 128px'),
|
||||
'timezone' => t('Timezone'),
|
||||
'contact/web/default' => t('Homepage URL'),
|
||||
'language/pref' => t('Language'),
|
||||
'birthDate/birthYear' => t('Birth Year'),
|
||||
'birthDate/birthMonth' => t('Birth Month'),
|
||||
'birthDate/birthday' => t('Birth Day'),
|
||||
'birthDate' => t('Birthdate'),
|
||||
'gender' => t('Gender'),
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Entrypoint for the OpenID implementation.
|
||||
*
|
||||
* @param App &$a
|
||||
*/
|
||||
|
||||
class Id extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
logger('id: ' . print_r($_REQUEST, true));
|
||||
|
||||
if(argc() > 1) {
|
||||
$which = argv(1);
|
||||
} else {
|
||||
\App::$error = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
$profile = '';
|
||||
$channel = \App::get_channel();
|
||||
profile_load($a,$which,$profile);
|
||||
|
||||
$op = new MysqlProvider;
|
||||
$op->server();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns user data needed for OpenID.
|
||||
*
|
||||
* If no $handle is provided we will use local_channel() by default.
|
||||
*
|
||||
* @param string $handle (default null)
|
||||
* @return boolean|array
|
||||
*/
|
||||
static public function getUserData($handle = null) {
|
||||
if (! local_channel()) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
\App::$page['content'] = login();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// logger('handle: ' . $handle);
|
||||
|
||||
if ($handle) {
|
||||
$r = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_address = '%s' limit 1",
|
||||
dbesc($handle)
|
||||
);
|
||||
} else {
|
||||
$r = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d",
|
||||
intval(local_channel())
|
||||
);
|
||||
}
|
||||
|
||||
if (! r)
|
||||
return false;
|
||||
|
||||
$x = q("select * from account where account_id = %d limit 1",
|
||||
intval($r[0]['channel_account_id'])
|
||||
);
|
||||
if ($x)
|
||||
$r[0]['email'] = $x[0]['account_email'];
|
||||
|
||||
$p = q("select * from profile where is_default = 1 and uid = %d limit 1",
|
||||
intval($r[0]['channel_account_id'])
|
||||
);
|
||||
|
||||
$gender = '';
|
||||
if ($p[0]['gender'] == t('Male'))
|
||||
$gender = 'M';
|
||||
if ($p[0]['gender'] == t('Female'))
|
||||
$gender = 'F';
|
||||
|
||||
$r[0]['firstName'] = ((strpos($r[0]['channel_name'],' ')) ? substr($r[0]['channel_name'],0,strpos($r[0]['channel_name'],' ')) : $r[0]['channel_name']);
|
||||
$r[0]['lastName'] = ((strpos($r[0]['channel_name'],' ')) ? substr($r[0]['channel_name'],strpos($r[0]['channel_name'],' ')+1) : '');
|
||||
$r[0]['namePerson'] = $r[0]['channel_name'];
|
||||
$r[0]['pphoto'] = $r[0]['xchan_photo_l'];
|
||||
$r[0]['pphoto16'] = z_root() . '/photo/profile/16/' . $r[0]['channel_id'] . '.jpg';
|
||||
$r[0]['pphoto32'] = z_root() . '/photo/profile/32/' . $r[0]['channel_id'] . '.jpg';
|
||||
$r[0]['pphoto48'] = z_root() . '/photo/profile/48/' . $r[0]['channel_id'] . '.jpg';
|
||||
$r[0]['pphoto64'] = z_root() . '/photo/profile/64/' . $r[0]['channel_id'] . '.jpg';
|
||||
$r[0]['pphoto80'] = z_root() . '/photo/profile/80/' . $r[0]['channel_id'] . '.jpg';
|
||||
$r[0]['pphoto128'] = z_root() . '/photo/profile/128/' . $r[0]['channel_id'] . '.jpg';
|
||||
$r[0]['timezone'] = $r[0]['channel_timezone'];
|
||||
$r[0]['url'] = $r[0]['xchan_url'];
|
||||
$r[0]['language'] = (($x[0]['account_language']) ? $x[0]['account_language'] : 'en');
|
||||
$r[0]['birthyear'] = ((intval(substr($p[0]['dob'],0,4))) ? intval(substr($p[0]['dob'],0,4)) : '');
|
||||
$r[0]['birthmonth'] = ((intval(substr($p[0]['dob'],5,2))) ? intval(substr($p[0]['dob'],5,2)) : '');
|
||||
$r[0]['birthday'] = ((intval(substr($p[0]['dob'],8,2))) ? intval(substr($p[0]['dob'],8,2)) : '');
|
||||
$r[0]['birthdate'] = (($r[0]['birthyear'] && $r[0]['birthmonth'] && $r[0]['birthday']) ? $p[0]['dob'] : '');
|
||||
$r[0]['gender'] = $gender;
|
||||
|
||||
return $r[0];
|
||||
|
||||
/*
|
||||
* if(isset($_POST['login'],$_POST['password'])) {
|
||||
* $login = mysql_real_escape_string($_POST['login']);
|
||||
* $password = sha1($_POST['password']);
|
||||
* $q = mysql_query("SELECT * FROM Users WHERE login = '$login' AND password = '$password'");
|
||||
* if($data = mysql_fetch_assoc($q)) {
|
||||
* return $data;
|
||||
* }
|
||||
* if($handle) {
|
||||
* echo 'Wrong login/password.';
|
||||
* }
|
||||
* }
|
||||
* if($handle) {
|
||||
* ?>
|
||||
* <form action="" method="post">
|
||||
* <input type="hidden" name="openid.assoc_handle" value="<?php
|
||||
namespace Zotlabs\Module; echo $handle?>">
|
||||
* Login: <input type="text" name="login"><br>
|
||||
* Password: <input type="password" name="password"><br>
|
||||
* <button>Submit</button>
|
||||
* </form>
|
||||
* <?php
|
||||
namespace Zotlabs\Module;
|
||||
* die();
|
||||
* }
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MySQL provider for OpenID implementation.
|
||||
*
|
||||
*/
|
||||
class MysqlProvider extends \LightOpenIDProvider {
|
||||
|
||||
// See http://openid.net/specs/openid-attribute-properties-list-1_0-01.html
|
||||
// This list contains a few variations of these attributes to maintain
|
||||
// compatibility with legacy clients
|
||||
|
||||
private $attrFieldMap = array(
|
||||
'namePerson/first' => 'firstName',
|
||||
'namePerson/last' => 'lastName',
|
||||
'namePerson/friendly' => 'channel_address',
|
||||
'namePerson' => 'namePerson',
|
||||
'contact/internet/email' => 'email',
|
||||
'contact/email' => 'email',
|
||||
'media/image/aspect11' => 'pphoto',
|
||||
'media/image' => 'pphoto',
|
||||
'media/image/default' => 'pphoto',
|
||||
'media/image/16x16' => 'pphoto16',
|
||||
'media/image/32x32' => 'pphoto32',
|
||||
'media/image/48x48' => 'pphoto48',
|
||||
'media/image/64x64' => 'pphoto64',
|
||||
'media/image/80x80' => 'pphoto80',
|
||||
'media/image/128x128' => 'pphoto128',
|
||||
'timezone' => 'timezone',
|
||||
'contact/web/default' => 'url',
|
||||
'language/pref' => 'language',
|
||||
'birthDate/birthYear' => 'birthyear',
|
||||
'birthDate/birthMonth' => 'birthmonth',
|
||||
'birthDate/birthday' => 'birthday',
|
||||
'birthDate' => 'birthdate',
|
||||
'gender' => 'gender',
|
||||
);
|
||||
|
||||
function setup($identity, $realm, $assoc_handle, $attributes) {
|
||||
global $attrMap;
|
||||
|
||||
// logger('identity: ' . $identity);
|
||||
// logger('realm: ' . $realm);
|
||||
// logger('assoc_handle: ' . $assoc_handle);
|
||||
// logger('attributes: ' . print_r($attributes,true));
|
||||
|
||||
$data = \Zotlabs\Module\Id::getUserData($assoc_handle);
|
||||
|
||||
|
||||
/** @FIXME this needs to be a template with localised strings */
|
||||
|
||||
$o .= '<form action="" method="post">'
|
||||
. '<input type="hidden" name="openid.assoc_handle" value="' . $assoc_handle . '">'
|
||||
. '<input type="hidden" name="login" value="' . $_POST['login'] .'">'
|
||||
. '<input type="hidden" name="password" value="' . $_POST['password'] .'">'
|
||||
. "<b>$realm</b> wishes to authenticate you.";
|
||||
if($attributes['required'] || $attributes['optional']) {
|
||||
$o .= " It also requests following information (required fields marked with *):"
|
||||
. '<ul>';
|
||||
|
||||
foreach($attributes['required'] as $attr) {
|
||||
if(isset($this->attrMap[$attr])) {
|
||||
$o .= '<li>'
|
||||
. '<input type="checkbox" name="attributes[' . $attr . ']"> '
|
||||
. $this->attrMap[$attr] . ' <span class="required">*</span></li>';
|
||||
}
|
||||
}
|
||||
|
||||
foreach($attributes['optional'] as $attr) {
|
||||
if(isset($this->attrMap[$attr])) {
|
||||
$o .= '<li>'
|
||||
. '<input type="checkbox" name="attributes[' . $attr . ']"> '
|
||||
. $this->attrMap[$attr] . '</li>';
|
||||
}
|
||||
}
|
||||
$o .= '</ul>';
|
||||
}
|
||||
$o .= '<br>'
|
||||
. '<button name="once">Allow once</button> '
|
||||
. '<button name="always">Always allow</button> '
|
||||
. '<button name="cancel">cancel</button> '
|
||||
. '</form>';
|
||||
|
||||
\App::$page['content'] .= $o;
|
||||
}
|
||||
|
||||
function checkid($realm, &$attributes) {
|
||||
|
||||
logger('checkid: ' . $realm);
|
||||
logger('checkid attrs: ' . print_r($attributes,true));
|
||||
|
||||
if(isset($_POST['cancel'])) {
|
||||
$this->cancel();
|
||||
}
|
||||
|
||||
$data = \Zotlabs\Module\Id::getUserData();
|
||||
if(! $data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$q = get_pconfig(local_channel(), 'openid', $realm);
|
||||
|
||||
$attrs = array();
|
||||
if($q) {
|
||||
$attrs = $q;
|
||||
} elseif(isset($_POST['attributes'])) {
|
||||
$attrs = array_keys($_POST['attributes']);
|
||||
} elseif(!isset($_POST['once']) && !isset($_POST['always'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$attributes = array();
|
||||
foreach($attrs as $attr) {
|
||||
if(isset($this->attrFieldMap[$attr])) {
|
||||
$attributes[$attr] = $data[$this->attrFieldMap[$attr]];
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($_POST['always'])) {
|
||||
set_pconfig(local_channel(),'openid',$realm,array_keys($attributes));
|
||||
}
|
||||
|
||||
return z_root() . '/id/' . $data['channel_address'];
|
||||
}
|
||||
|
||||
function assoc_handle() {
|
||||
logger('assoc_handle');
|
||||
$channel = \App::get_channel();
|
||||
|
||||
return z_root() . '/channel/' . $channel['channel_address'];
|
||||
}
|
||||
|
||||
function setAssoc($handle, $data) {
|
||||
logger('setAssoc');
|
||||
$channel = channelx_by_nick(basename($handle));
|
||||
if($channel)
|
||||
set_pconfig($channel['channel_id'],'openid','associate',$data);
|
||||
}
|
||||
|
||||
function getAssoc($handle) {
|
||||
logger('getAssoc: ' . $handle);
|
||||
|
||||
$channel = channelx_by_nick(basename($handle));
|
||||
if($channel)
|
||||
return get_pconfig($channel['channel_id'], 'openid', 'associate');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function delAssoc($handle) {
|
||||
logger('delAssoc');
|
||||
$channel = channelx_by_nick(basename($handle));
|
||||
if($channel)
|
||||
return del_pconfig($channel['channel_id'], 'openid', 'associate');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,11 @@ class Impel extends \Zotlabs\Web\Controller {
|
||||
foreach($j['items'] as $it) {
|
||||
$mitem = array();
|
||||
|
||||
$mitem['mitem_link'] = str_replace('[channelurl]',z_root() . '/channel/' . $channel['channel_address'],$it['link']);
|
||||
$mitem['mitem_link'] = str_replace('[pageurl]',z_root() . '/page/' . $channel['channel_address'],$it['link']);
|
||||
$mitem['mitem_link'] = str_replace('[cloudurl]',z_root() . '/cloud/' . $channel['channel_address'],$it['link']);
|
||||
$mitem['mitem_link'] = str_replace('[baseurl]',z_root(),$it['link']);
|
||||
|
||||
$mitem['mitem_desc'] = escape_tags($it['desc']);
|
||||
$mitem['mitem_order'] = intval($it['order']);
|
||||
if(is_array($it['flags'])) {
|
||||
@@ -137,9 +141,7 @@ class Impel extends \Zotlabs\Web\Controller {
|
||||
require_once('library/urlify/URLify.php');
|
||||
$pagetitle = strtolower(\URLify::transliterate($j['pagetitle']));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Verify ability to use html or php!!!
|
||||
|
||||
$execflag = false;
|
||||
@@ -154,21 +156,14 @@ class Impel extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
$remote_id = 0;
|
||||
|
||||
$z = q("select * from item_id where sid = '%s' and service = '%s' and uid = %d limit 1",
|
||||
dbesc($pagetitle),
|
||||
dbesc($namespace),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
$i = q("select id, edited, item_deleted from item where mid = '%s' and uid = %d limit 1",
|
||||
dbesc($arr['mid']),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
\Zotlabs\Lib\IConfig::Set($arr,'system',$namespace,(($pagetitle) ? $pagetitle : substr($arr['mid'],0,16)),true);
|
||||
|
||||
if($z && $i) {
|
||||
$remote_id = $z[0]['id'];
|
||||
if($i) {
|
||||
$arr['id'] = $i[0]['id'];
|
||||
// don't update if it has the same timestamp as the original
|
||||
if($arr['edited'] > $i[0]['edited'])
|
||||
@@ -182,12 +177,12 @@ class Impel extends \Zotlabs\Web\Controller {
|
||||
intval(local_channel())
|
||||
);
|
||||
}
|
||||
$x = item_store($arr,$execflag);
|
||||
else
|
||||
$x = item_store($arr,$execflag);
|
||||
}
|
||||
|
||||
if($x['success']) {
|
||||
if($x && $x['success']) {
|
||||
$item_id = $x['item_id'];
|
||||
update_remote_id($channel,$item_id,$arr['item_type'],$pagetitle,$namespace,$remote_id,$arr['mid']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +194,8 @@ class Impel extends \Zotlabs\Web\Controller {
|
||||
notice( sprintf( t('%s element installation failed'), $installed_type));
|
||||
}
|
||||
|
||||
//??? should perhaps return ret?
|
||||
//??? should perhaps return ret?
|
||||
|
||||
json_return_and_die(true);
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace Zotlabs\Module;
|
||||
require_once('include/zot.php');
|
||||
require_once('include/channel.php');
|
||||
require_once('include/import.php');
|
||||
require_once('include/perm_upgrade.php');
|
||||
|
||||
|
||||
|
||||
@@ -131,6 +132,8 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
|
||||
// import channel
|
||||
|
||||
$relocate = ((array_key_exists('relocate',$data)) ? $data['relocate'] : null);
|
||||
|
||||
if(array_key_exists('channel',$data)) {
|
||||
|
||||
if($completed < 1) {
|
||||
@@ -337,6 +340,8 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
$abooks = $data['abook'];
|
||||
if($abooks) {
|
||||
foreach($abooks as $abook) {
|
||||
|
||||
$abook_copy = $abook;
|
||||
|
||||
$abconfig = null;
|
||||
if(array_key_exists('abconfig',$abook) && is_array($abook['abconfig']) && count($abook['abconfig']))
|
||||
@@ -345,6 +350,10 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
unset($abook['abook_id']);
|
||||
unset($abook['abook_rating']);
|
||||
unset($abook['abook_rating_text']);
|
||||
unset($abook['abconfig']);
|
||||
unset($abook['abook_their_perms']);
|
||||
unset($abook['abook_my_perms']);
|
||||
|
||||
$abook['abook_account'] = $account_id;
|
||||
$abook['abook_channel'] = $channel['channel_id'];
|
||||
if(! array_key_exists('abook_blocked',$abook)) {
|
||||
@@ -383,12 +392,13 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
$friends ++;
|
||||
if(intval($abook['abook_feed']))
|
||||
$feeds ++;
|
||||
|
||||
translate_abook_perms_inbound($channel,$abook_copy);
|
||||
|
||||
if($abconfig) {
|
||||
// @fixme does not handle sync of del_abconfig
|
||||
foreach($abconfig as $abc) {
|
||||
if($abc['chan'] === $channel['channel_hash'])
|
||||
set_abconfig($abc['chan'],$abc['xchan'],$abc['cat'],$abc['k'],$abc['v']);
|
||||
set_abconfig($channel['channel_id'],$abc['xchan'],$abc['cat'],$abc['k'],$abc['v']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,7 +485,7 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
import_events($channel,$data['event']);
|
||||
|
||||
if(is_array($data['event_item']))
|
||||
import_items($channel,$data['event_item']);
|
||||
import_items($channel,$data['event_item'],false,$relocate);
|
||||
|
||||
if(is_array($data['menu']))
|
||||
import_menus($channel,$data['menu']);
|
||||
@@ -486,7 +496,7 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
$saved_notification_flags = notifications_off($channel['channel_id']);
|
||||
|
||||
if($import_posts && array_key_exists('item',$data) && $data['item'])
|
||||
import_items($channel,$data['item']);
|
||||
import_items($channel,$data['item'],false,$relocate);
|
||||
|
||||
notifications_on($channel['channel_id'],$saved_notification_flags);
|
||||
|
||||
|
||||
@@ -78,6 +78,8 @@ class Import_items extends \Zotlabs\Web\Controller {
|
||||
// logger('import: data: ' . print_r($data,true));
|
||||
// print_r($data);
|
||||
|
||||
if(! is_array($data))
|
||||
return;
|
||||
|
||||
if(array_key_exists('compatibility',$data) && array_key_exists('database',$data['compatibility'])) {
|
||||
$v1 = substr($data['compatibility']['database'],-4);
|
||||
@@ -92,7 +94,7 @@ class Import_items extends \Zotlabs\Web\Controller {
|
||||
|
||||
|
||||
if(array_key_exists('item',$data) && $data['item']) {
|
||||
import_items($channel,$data['item']);
|
||||
import_items($channel,$data['item'],false,((array_key_exists('relocate',$data)) ? $data['relocate'] : null));
|
||||
}
|
||||
|
||||
if(array_key_exists('item_id',$data) && $data['item_id']) {
|
||||
@@ -106,7 +108,7 @@ class Import_items extends \Zotlabs\Web\Controller {
|
||||
|
||||
|
||||
|
||||
function get() {
|
||||
function get() {
|
||||
|
||||
if(! local_channel()) {
|
||||
notice( t('Permission denied') . EOL);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
/**
|
||||
@@ -92,7 +93,7 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
|
||||
$origin = (($api_source && array_key_exists('origin',$_REQUEST)) ? intval($_REQUEST['origin']) : 1);
|
||||
|
||||
// To represent message-ids on other networks - this will create an item_id record
|
||||
// To represent message-ids on other networks - this will create an iconfig record
|
||||
|
||||
$namespace = (($api_source && array_key_exists('namespace',$_REQUEST)) ? strip_tags($_REQUEST['namespace']) : '');
|
||||
$remote_id = (($api_source && array_key_exists('remote_id',$_REQUEST)) ? strip_tags($_REQUEST['remote_id']) : '');
|
||||
@@ -182,7 +183,9 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
// can_comment_on_post() needs info from the following xchan_query
|
||||
xchan_query($r);
|
||||
// This may be from the discover tab which means we need to correct the effective uid
|
||||
|
||||
xchan_query($r,true,(($r[0]['uid'] == local_channel()) ? 0 : local_channel()));
|
||||
|
||||
$parent_item = $r[0];
|
||||
$parent = $r[0]['id'];
|
||||
@@ -229,7 +232,7 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
|
||||
if($namespace && $remote_id) {
|
||||
// It wasn't an internally generated post - see if we've got an item matching this remote service id
|
||||
$i = q("select iid from item_id where service = '%s' and sid = '%s' limit 1",
|
||||
$i = q("select iid from iconfig where cat = 'system' and k = '%s' and v = '%s' limit 1",
|
||||
dbesc($namespace),
|
||||
dbesc($remote_id)
|
||||
);
|
||||
@@ -315,9 +318,11 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
$acl = new \Zotlabs\Access\AccessList($channel);
|
||||
|
||||
$view_policy = \Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'view_stream');
|
||||
$comment_policy = \Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'post_comments');
|
||||
|
||||
|
||||
$public_policy = ((x($_REQUEST,'public_policy')) ? escape_tags($_REQUEST['public_policy']) : map_scope($channel['channel_r_stream'],true));
|
||||
$public_policy = ((x($_REQUEST,'public_policy')) ? escape_tags($_REQUEST['public_policy']) : map_scope($view_policy,true));
|
||||
if($webpage)
|
||||
$public_policy = '';
|
||||
if($public_policy)
|
||||
@@ -525,16 +530,16 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
|
||||
|
||||
if((! $parent) && (get_pconfig($profile_uid,'system','tagifonlyrecip')) && (substr_count($str_contact_allow,'<') == 1) && ($str_group_allow == '') && ($str_contact_deny == '') && ($str_group_deny == '')) {
|
||||
$x = q("select abook_id, abook_their_perms from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
|
||||
$x = q("select abook_id, abconfig.v from abook left join abconfig on abook_xchan = abconfig.xchan and abook_channel = abconfig.chan and cat= 'their_perms' and abconfig.k = 'tag_deliver' and abconfig.v = 1 and abook_xchan = '%s' and abook_channel = %d limit 1",
|
||||
dbesc(str_replace(array('<','>'),array('',''),$str_contact_allow)),
|
||||
intval($profile_uid)
|
||||
);
|
||||
if($x && ($x[0]['abook_their_perms'] & PERMS_W_TAGWALL))
|
||||
if($x)
|
||||
$body .= "\n\n@group+" . $x[0]['abook_id'] . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* fix naked links by passing through a callback to see if this is a red site
|
||||
* fix naked links by passing through a callback to see if this is a hubzilla site
|
||||
* (already known to us) which will get a zrl, otherwise link with url, add bookmark tag to both.
|
||||
* First protect any url inside certain bbcode tags so we don't double link it.
|
||||
*/
|
||||
@@ -809,7 +814,7 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
|
||||
$datarray['layout_mid'] = $layout_mid;
|
||||
$datarray['public_policy'] = $public_policy;
|
||||
$datarray['comment_policy'] = map_scope($channel['channel_w_comment']);
|
||||
$datarray['comment_policy'] = map_scope($comment_policy);
|
||||
$datarray['term'] = $post_tags;
|
||||
$datarray['plink'] = $plink;
|
||||
$datarray['route'] = $route;
|
||||
@@ -833,21 +838,23 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
if($orig_post)
|
||||
$datarray['edit'] = true;
|
||||
|
||||
// suppress duplicates, *unless* you're editing an existing post. This could get picked up
|
||||
// as a duplicate if you're editing it very soon after posting it initially and you edited
|
||||
// some attribute besides the content, such as title or categories.
|
||||
|
||||
if(feature_enabled($profile_uid,'suppress_duplicates') && (! $orig_post)) {
|
||||
|
||||
$z = q("select created from item where uid = %d and body = '%s'",
|
||||
$z = q("select created from item where uid = %d and created > %s - INTERVAL %s and body = '%s' limit 1",
|
||||
intval($profile_uid),
|
||||
db_utcnow(),
|
||||
db_quoteinterval('2 MINUTE'),
|
||||
dbesc($body)
|
||||
);
|
||||
|
||||
if($z) {
|
||||
foreach($z as $zz) {
|
||||
if($zz['created'] > datetime_convert('UTC','UTC', 'now - 2 minutes')) {
|
||||
$datarray['cancel'] = 1;
|
||||
notice( t('Duplicate post suppressed.') . EOL);
|
||||
logger('Duplicate post. Faking plugin cancel.');
|
||||
}
|
||||
}
|
||||
$datarray['cancel'] = 1;
|
||||
notice( t('Duplicate post suppressed.') . EOL);
|
||||
logger('Duplicate post. Faking plugin cancel.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -880,13 +887,21 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
if($webpage) {
|
||||
Zlib\IConfig::Set($datarray,'system', webpage_to_namespace($webpage),
|
||||
(($pagetitle) ? $pagetitle : substr($datarray['mid'],0,16)),true);
|
||||
}
|
||||
elseif($namespace) {
|
||||
Zlib\IConfig::Set($datarray,'system', $namespace,
|
||||
(($remote_id) ? $remote_id : substr($datarray['mid'],0,16)),true);
|
||||
}
|
||||
|
||||
|
||||
if($orig_post) {
|
||||
$datarray['id'] = $post_id;
|
||||
|
||||
item_store_update($datarray,$execflag);
|
||||
|
||||
update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remote_id,$mid);
|
||||
|
||||
$x = item_store_update($datarray,$execflag);
|
||||
|
||||
if(! $parent) {
|
||||
$r = q("select * from item where id = %d",
|
||||
intval($post_id)
|
||||
@@ -894,10 +909,7 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
if($r) {
|
||||
xchan_query($r);
|
||||
$sync_item = fetch_post_tags($r);
|
||||
$rid = q("select * from item_id where iid = %d",
|
||||
intval($post_id)
|
||||
);
|
||||
build_sync_packet($uid,array('item' => array(encode_item($sync_item[0],true)),'item_id' => $rid));
|
||||
build_sync_packet($profile_uid,array('item' => array(encode_item($sync_item[0],true))));
|
||||
}
|
||||
}
|
||||
if(! $nopush)
|
||||
@@ -978,10 +990,7 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
goaway(z_root() . "/" . $return_path );
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
|
||||
update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remote_id,$mid);
|
||||
|
||||
|
||||
if(($parent) && ($parent != $post_id)) {
|
||||
// Store the comment signature information in case we need to relay to Diaspora
|
||||
//$ditem = $datarray;
|
||||
@@ -995,10 +1004,7 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
if($r) {
|
||||
xchan_query($r);
|
||||
$sync_item = fetch_post_tags($r);
|
||||
$rid = q("select * from item_id where iid = %d",
|
||||
intval($post_id)
|
||||
);
|
||||
build_sync_packet($uid,array('item' => array(encode_item($sync_item[0],true)),'item_id' => $rid));
|
||||
build_sync_packet($profile_uid,array('item' => array(encode_item($sync_item[0],true))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1012,11 +1018,6 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
|
||||
logger('post_complete');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// figure out how to return, depending on from whence we came
|
||||
|
||||
if($api_source)
|
||||
|
||||
@@ -21,7 +21,7 @@ class Layouts extends \Zotlabs\Web\Controller {
|
||||
else
|
||||
return;
|
||||
|
||||
profile_load($a,$which);
|
||||
profile_load($which);
|
||||
|
||||
}
|
||||
|
||||
@@ -90,13 +90,14 @@ class Layouts extends \Zotlabs\Web\Controller {
|
||||
return;
|
||||
}
|
||||
|
||||
//This feature is not exposed in redbasic ui since it is not clear why one would want to
|
||||
//download a json encoded pdl file - we dont have a possibility to import it.
|
||||
//Use the buildin share/install feature instead.
|
||||
// This feature is not exposed in redbasic ui since it is not clear why one would want to
|
||||
// download a json encoded pdl file - we dont have a possibility to import it.
|
||||
// Use the buildin share/install feature instead.
|
||||
|
||||
if((argc() > 3) && (argv(2) === 'share') && (argv(3))) {
|
||||
$r = q("select sid, service, mimetype, title, body from item_id
|
||||
left join item on item.id = item_id.iid
|
||||
where item_id.uid = %d and item.mid = '%s' and service = 'PDL' order by sid asc",
|
||||
$r = q("select iconfig.v, iconfig.k, mimetype, title, body from iconfig
|
||||
left join item on item.id = iconfig.iid
|
||||
where uid = %d and mid = '%s' and iconfig.cat = 'system' and iconfig.k = 'PDL' order by iconfig.v asc",
|
||||
intval($owner),
|
||||
dbesc(argv(3))
|
||||
);
|
||||
@@ -141,8 +142,9 @@ class Layouts extends \Zotlabs\Web\Controller {
|
||||
|
||||
$editor = status_editor($a,$x);
|
||||
|
||||
$r = q("select iid, sid, mid, title, body, mimetype, created, edited, item_type from item_id left join item on item_id.iid = item.id
|
||||
where item_id.uid = %d and service = 'PDL' and item_type = %d order by item.created desc",
|
||||
$r = q("select iconfig.iid, iconfig.v, mid, title, body, mimetype, created, edited, item_type from iconfig
|
||||
left join item on iconfig.iid = item.id
|
||||
where uid = %d and iconfig.cat = 'system' and iconfig.k = 'PDL' and item_type = %d order by item.created desc",
|
||||
intval($owner),
|
||||
intval(ITEM_TYPE_PDL)
|
||||
);
|
||||
@@ -164,7 +166,7 @@ class Layouts extends \Zotlabs\Web\Controller {
|
||||
);
|
||||
$pages[$rr['iid']][] = array(
|
||||
'url' => $rr['iid'],
|
||||
'title' => $rr['sid'],
|
||||
'title' => $rr['v'],
|
||||
'descr' => $rr['title'],
|
||||
'mid' => $rr['mid'],
|
||||
'created' => $rr['created'],
|
||||
|
||||
@@ -264,23 +264,22 @@ class Like extends \Zotlabs\Web\Controller {
|
||||
logger('like: no item ' . $item_id);
|
||||
killme();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
xchan_query($r,true,(($r[0]['uid'] == local_channel()) ? 0 : local_channel()));
|
||||
|
||||
$item = $r[0];
|
||||
$owner_uid = $item['uid'];
|
||||
$owner_aid = $item['aid'];
|
||||
|
||||
|
||||
$sys = get_sys_channel();
|
||||
|
||||
|
||||
// if this is a "discover" item, (item['uid'] is the sys channel),
|
||||
// fallback to the item comment policy, which should've been
|
||||
// respected when generating the conversation thread.
|
||||
// Even if the activity is rejected by the item owner, it should still get attached
|
||||
// to the local discover conversation on this site.
|
||||
|
||||
if(($owner_uid != $sys['channel_id']) && (! perm_is_allowed($owner_uid,$observer['xchan_hash'],'post_comments'))) {
|
||||
|
||||
$owner_uid = $r[0]['uid'];
|
||||
$owner_aid = $r[0]['aid'];
|
||||
|
||||
$can_comment = false;
|
||||
if((array_key_exists('owner',$item)) && intval($item['owner']['abook_self']))
|
||||
$can_comment = perm_is_allowed($item['uid'],$observer['xchan_hash'],'post_comments');
|
||||
else
|
||||
$can_comment = can_comment_on_post($observer['xchan_hash'],$item);
|
||||
|
||||
if(! $can_comment) {
|
||||
notice( t('Permission denied') . EOL);
|
||||
killme();
|
||||
}
|
||||
@@ -496,6 +495,8 @@ class Like extends \Zotlabs\Web\Controller {
|
||||
$arr['deny_gid'] = $deny_gid;
|
||||
$arr['item_private'] = $private;
|
||||
|
||||
call_hooks('post_local',$arr);
|
||||
|
||||
|
||||
$post = item_store($arr);
|
||||
$post_id = $post['item_id'];
|
||||
|
||||
@@ -1,17 +1,31 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
|
||||
require_once('include/security.php');
|
||||
|
||||
class Lockview extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
$atokens = array();
|
||||
|
||||
if(local_channel()) {
|
||||
$at = q("select * from atoken where atoken_uid = %d",
|
||||
intval(local_channel())
|
||||
);
|
||||
if($at) {
|
||||
foreach($at as $t) {
|
||||
$atokens[] = atoken_xchan($t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$type = ((argc() > 1) ? argv(1) : 0);
|
||||
if (is_numeric($type)) {
|
||||
$item_id = intval($type);
|
||||
$type='item';
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$item_id = ((argc() > 2) ? intval(argv(2)) : 0);
|
||||
}
|
||||
|
||||
@@ -98,6 +112,13 @@ class Lockview extends \Zotlabs\Web\Controller {
|
||||
if($r)
|
||||
foreach($r as $rr)
|
||||
$l[] = '<li>' . $rr['xchan_name'] . '</li>';
|
||||
if($atokens) {
|
||||
foreach($atokens as $at) {
|
||||
if(in_array("'" . $at['xchan_hash'] . "'",$allowed_users)) {
|
||||
$l[] = '<li>' . $at['xchan_name'] . '</li>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(count($deny_groups)) {
|
||||
$r = q("SELECT gname FROM `groups` WHERE hash IN ( " . implode(', ', $deny_groups) . " )");
|
||||
@@ -110,6 +131,16 @@ class Lockview extends \Zotlabs\Web\Controller {
|
||||
if($r)
|
||||
foreach($r as $rr)
|
||||
$l[] = '<li><strike>' . $rr['xchan_name'] . '</strike></li>';
|
||||
|
||||
if($atokens) {
|
||||
foreach($atokens as $at) {
|
||||
if(in_array("'" . $at['xchan_hash'] . "'",$deny_users)) {
|
||||
$l[] = '<li><strike>' . $at['xchan_name'] . '</strike></li>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
echo $o . implode($l);
|
||||
|
||||
@@ -7,6 +7,9 @@ class Login extends \Zotlabs\Web\Controller {
|
||||
function get() {
|
||||
if(local_channel())
|
||||
goaway(z_root());
|
||||
if(remote_channel() && $_SESSION['atoken'])
|
||||
goaway(z_root());
|
||||
|
||||
return login((\App::$config['system']['register_policy'] == REGISTER_CLOSED) ? false : true);
|
||||
}
|
||||
|
||||
|
||||
@@ -57,8 +57,6 @@ class Mail extends \Zotlabs\Web\Controller {
|
||||
|
||||
$their_perms = 0;
|
||||
|
||||
$global_perms = get_perms();
|
||||
|
||||
if($j['permissions']['data']) {
|
||||
$permissions = crypto_unencapsulate($j['permissions'],$channel['channel_prvkey']);
|
||||
if($permissions)
|
||||
@@ -68,13 +66,7 @@ class Mail extends \Zotlabs\Web\Controller {
|
||||
else
|
||||
$permissions = $j['permissions'];
|
||||
|
||||
foreach($permissions as $k => $v) {
|
||||
if($v) {
|
||||
$their_perms = $their_perms | intval($global_perms[$k][1]);
|
||||
}
|
||||
}
|
||||
|
||||
if(! ($their_perms & PERMS_W_MAIL)) {
|
||||
if(! ($permissions['post_mail'])) {
|
||||
notice( t('Selected channel has private message restrictions. Send failed.'));
|
||||
// reported issue: let's still save the message and continue. We'll just tell them
|
||||
// that nothing useful is likely to happen. They might have spent hours on it.
|
||||
@@ -120,7 +112,7 @@ class Mail extends \Zotlabs\Web\Controller {
|
||||
|
||||
}
|
||||
|
||||
function get() {
|
||||
function get() {
|
||||
|
||||
$o = '';
|
||||
nav_set_selected('messages');
|
||||
|
||||
@@ -143,9 +143,9 @@ class Manage extends \Zotlabs\Web\Controller {
|
||||
$create = array( 'new_channel', t('Create a new channel'), t('Create New'));
|
||||
|
||||
$delegates = q("select * from abook left join xchan on abook_xchan = xchan_hash where
|
||||
abook_channel = %d and (abook_their_perms & %d) > 0",
|
||||
abook_channel = %d and abook_xchan in ( select xchan from abconfig where chan = %d and cat = 'their_perms' and k = 'delegate' and v = 1 )",
|
||||
intval(local_channel()),
|
||||
intval(PERMS_A_DELEGATE)
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
if($delegates) {
|
||||
|
||||
@@ -65,7 +65,7 @@ class Menu extends \Zotlabs\Web\Controller {
|
||||
|
||||
|
||||
|
||||
function get() {
|
||||
function get() {
|
||||
|
||||
$uid = local_channel();
|
||||
|
||||
@@ -81,7 +81,7 @@ class Menu extends \Zotlabs\Web\Controller {
|
||||
|
||||
if(argc() == 1) {
|
||||
|
||||
|
||||
$channel = (($sys) ? $sys : \App::get_channel());
|
||||
|
||||
// list menus
|
||||
$x = menu_list($uid);
|
||||
@@ -89,7 +89,7 @@ class Menu extends \Zotlabs\Web\Controller {
|
||||
for($y = 0; $y < count($x); $y ++) {
|
||||
$m = menu_fetch($x[$y]['menu_name'],$uid,get_observer_hash());
|
||||
if($m)
|
||||
$x[$y]['element'] = '[element]' . base64url_encode(json_encode(menu_element($m))) . '[/element]';
|
||||
$x[$y]['element'] = '[element]' . base64url_encode(json_encode(menu_element($channel,$m))) . '[/element]';
|
||||
$x[$y]['bookmark'] = (($x[$y]['menu_flags'] & MENU_BOOKMARK) ? true : false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,12 +147,16 @@ class Mitem extends \Zotlabs\Web\Controller {
|
||||
else {
|
||||
$display = (($r) ? 'none' : 'block');
|
||||
}
|
||||
|
||||
|
||||
$create = replace_macros(get_markup_template('mitemedit.tpl'), array(
|
||||
'$menu_id' => \App::$data['menu']['menu_id'],
|
||||
'$permissions' => t('Menu Item Permissions'),
|
||||
'$permdesc' => t("\x28click to open/close\x29"),
|
||||
'$aclselect' => populate_acl($acl->get(),false),
|
||||
'$allow_cid' => acl2json($acl->get()['allow_cid']),
|
||||
'$allow_gid' => acl2json($acl->get()['allow_gid']),
|
||||
'$deny_cid' => acl2json($acl->get()['deny_cid']),
|
||||
'$deny_gid' => acl2json($acl->get()['deny_gid']),
|
||||
'$mitem_desc' => array('mitem_desc', t('Link Name'), '', 'Visible name of the link','*'),
|
||||
'$mitem_link' => array('mitem_link', t('Link or Submenu Target'), '', t('Enter URL of the link or select a menu name to create a submenu'), '*', 'list="menu-names"'),
|
||||
'$usezid' => array('usezid', t('Use magic-auth if available'), true, '', array(t('No'), t('Yes'))),
|
||||
@@ -226,6 +230,10 @@ class Mitem extends \Zotlabs\Web\Controller {
|
||||
'$permissions' => t('Menu Item Permissions'),
|
||||
'$permdesc' => t("\x28click to open/close\x29"),
|
||||
'$aclselect' => populate_acl($mitem,false),
|
||||
'$allow_cid' => acl2json($mitem['allow_cid']),
|
||||
'$allow_gid' => acl2json($mitem['allow_gid']),
|
||||
'$deny_cid' => acl2json($mitem['deny_cid']),
|
||||
'$deny_gid' => acl2json($mitem['deny_gid']),
|
||||
'$mitem_id' => intval(argv(2)),
|
||||
'$mitem_desc' => array('mitem_desc', t('Link text'), $mitem['mitem_desc'], '','*'),
|
||||
'$mitem_link' => array('mitem_link', t('Link or Submenu Target'), $mitem['mitem_link'], 'Enter URL of the link or select a menu name to create a submenu', '*', 'list="menu-names"'),
|
||||
|
||||
@@ -6,8 +6,6 @@ require_once('include/group.php');
|
||||
require_once('include/contact_widgets.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/PermissionDescription.php');
|
||||
|
||||
|
||||
|
||||
class Network extends \Zotlabs\Web\Controller {
|
||||
@@ -171,7 +169,8 @@ class Network extends \Zotlabs\Web\Controller {
|
||||
'default_location' => $channel['channel_location'],
|
||||
'nickname' => $channel['channel_address'],
|
||||
'lockstate' => (($private_editing || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
|
||||
'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, \PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
|
||||
'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
|
||||
'permissions' => (($private_editing) ? $def_acl : $channel_acl),
|
||||
'bang' => (($private_editing) ? '!' : ''),
|
||||
'visitor' => true,
|
||||
'profile_uid' => local_channel(),
|
||||
|
||||
@@ -62,7 +62,7 @@ class New_channel extends \Zotlabs\Web\Controller {
|
||||
|
||||
}
|
||||
|
||||
function post() {
|
||||
function post() {
|
||||
|
||||
$arr = $_POST;
|
||||
|
||||
@@ -96,7 +96,7 @@ class New_channel extends \Zotlabs\Web\Controller {
|
||||
|
||||
}
|
||||
|
||||
function get() {
|
||||
function get() {
|
||||
|
||||
$acc = \App::get_account();
|
||||
|
||||
@@ -125,9 +125,9 @@ class New_channel extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
$name = array('name', t('Name or caption'), ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''), t('Examples: "Bob Jameson", "Lisa and her Horses", "Soccer", "Aviation Group"'));
|
||||
$name = array('name', t('Name or caption'), ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''), t('Examples: "Bob Jameson", "Lisa and her Horses", "Soccer", "Aviation Group"'), "*");
|
||||
$nickhub = '@' . \App::get_hostname();
|
||||
$nickname = array('nickname', t('Choose a short nickname'), ((x($_REQUEST,'nickname')) ? $_REQUEST['nickname'] : ''), sprintf( t('Your nickname will be used to create an easy to remember channel address e.g. nickname%s'), $nickhub));
|
||||
$nickname = array('nickname', t('Choose a short nickname'), ((x($_REQUEST,'nickname')) ? $_REQUEST['nickname'] : ''), sprintf( t('Your nickname will be used to create an easy to remember channel address e.g. nickname%s'), $nickhub), "*");
|
||||
$privacy_role = ((x($_REQUEST,'permissions_role')) ? $_REQUEST['permissions_role'] : "" );
|
||||
$role = array('permissions_role' , t('Channel role and privacy'), ($privacy_role) ? $privacy_role : 'social', t('Select a channel role with your privacy requirements.') . ' <a href="help/roles" target="_blank">' . t('Read more about roles') . '</a>',get_roles());
|
||||
|
||||
|
||||
@@ -1,198 +0,0 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
|
||||
require_once('library/openid/openid.php');
|
||||
require_once('include/auth.php');
|
||||
|
||||
|
||||
class Openid extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
$noid = get_config('system','disable_openid');
|
||||
if($noid)
|
||||
goaway(z_root());
|
||||
|
||||
logger('mod_openid ' . print_r($_REQUEST,true), LOGGER_DATA);
|
||||
|
||||
if(x($_REQUEST,'openid_mode')) {
|
||||
|
||||
$openid = new LightOpenID(z_root());
|
||||
|
||||
if($openid->validate()) {
|
||||
|
||||
logger('openid: validate');
|
||||
|
||||
$authid = normalise_openid($_REQUEST['openid_identity']);
|
||||
|
||||
if(! strlen($authid)) {
|
||||
logger( t('OpenID protocol error. No ID returned.') . EOL);
|
||||
goaway(z_root());
|
||||
}
|
||||
|
||||
$x = match_openid($authid);
|
||||
if($x) {
|
||||
|
||||
$r = q("select * from channel where channel_id = %d limit 1",
|
||||
intval($x)
|
||||
);
|
||||
if($r) {
|
||||
$y = q("select * from account where account_id = %d limit 1",
|
||||
intval($r[0]['channel_account_id'])
|
||||
);
|
||||
if($y) {
|
||||
foreach($y as $record) {
|
||||
if(($record['account_flags'] == ACCOUNT_OK) || ($record['account_flags'] == ACCOUNT_UNVERIFIED)) {
|
||||
logger('mod_openid: openid success for ' . $x[0]['channel_name']);
|
||||
$_SESSION['uid'] = $r[0]['channel_id'];
|
||||
$_SESSION['account_id'] = $r[0]['channel_account_id'];
|
||||
$_SESSION['authenticated'] = true;
|
||||
authenticate_success($record,true,true,true,true);
|
||||
goaway(z_root());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Successful OpenID login - but we can't match it to an existing account.
|
||||
// See if they've got an xchan
|
||||
|
||||
$r = q("select * from xconfig left join xchan on xchan_hash = xconfig.xchan where cat = 'system' and k = 'openid' and v = '%s' limit 1",
|
||||
dbesc($authid)
|
||||
);
|
||||
|
||||
if($r) {
|
||||
$_SESSION['authenticated'] = 1;
|
||||
$_SESSION['visitor_id'] = $r[0]['xchan_hash'];
|
||||
$_SESSION['my_url'] = $r[0]['xchan_url'];
|
||||
$_SESSION['my_address'] = $r[0]['xchan_addr'];
|
||||
$arr = array('xchan' => $r[0], 'session' => $_SESSION);
|
||||
call_hooks('magic_auth_openid_success',$arr);
|
||||
\App::set_observer($r[0]);
|
||||
require_once('include/security.php');
|
||||
\App::set_groups(init_groups_visitor($_SESSION['visitor_id']));
|
||||
info(sprintf( t('Welcome %s. Remote authentication successful.'),$r[0]['xchan_name']));
|
||||
logger('mod_openid: remote auth success from ' . $r[0]['xchan_addr']);
|
||||
if($_SESSION['return_url'])
|
||||
goaway($_SESSION['return_url']);
|
||||
goaway(z_root());
|
||||
}
|
||||
|
||||
// no xchan...
|
||||
// create one.
|
||||
// We should probably probe the openid url and figure out if they have any kind of social presence we might be able to
|
||||
// scrape some identifying info from.
|
||||
|
||||
$name = $authid;
|
||||
$url = trim($_REQUEST['openid_identity'],'/');
|
||||
if(strpos($url,'http') === false)
|
||||
$url = 'https://' . $url;
|
||||
$pphoto = z_root() . '/' . get_default_profile_photo();
|
||||
$parsed = @parse_url($url);
|
||||
if($parsed) {
|
||||
$host = $parsed['host'];
|
||||
}
|
||||
|
||||
$attr = $openid->getAttributes();
|
||||
|
||||
if(is_array($attr) && count($attr)) {
|
||||
foreach($attr as $k => $v) {
|
||||
if($k === 'namePerson/friendly')
|
||||
$nick = notags(trim($v));
|
||||
if($k === 'namePerson/first')
|
||||
$first = notags(trim($v));
|
||||
if($k === 'namePerson')
|
||||
$name = notags(trim($v));
|
||||
if($k === 'contact/email')
|
||||
$addr = notags(trim($v));
|
||||
if($k === 'media/image/aspect11')
|
||||
$photosq = trim($v);
|
||||
if($k === 'media/image/default')
|
||||
$photo_other = trim($v);
|
||||
}
|
||||
}
|
||||
if(! $nick) {
|
||||
if($first)
|
||||
$nick = $first;
|
||||
else
|
||||
$nick = $name;
|
||||
}
|
||||
|
||||
require_once('library/urlify/URLify.php');
|
||||
$x = strtolower(\URLify::transliterate($nick));
|
||||
if($nick & $host)
|
||||
$addr = $nick . '@' . $host;
|
||||
$network = 'unknown';
|
||||
|
||||
if($photosq)
|
||||
$pphoto = $photosq;
|
||||
elseif($photo_other)
|
||||
$pphoto = $photo_other;
|
||||
|
||||
$mimetype = guess_image_type($pphoto);
|
||||
|
||||
$x = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_mimetype,
|
||||
xchan_photo_l, xchan_addr, xchan_url, xchan_connurl, xchan_follow, xchan_connpage, xchan_name, xchan_network, xchan_photo_date,
|
||||
xchan_name_date, xchan_hidden)
|
||||
values ( '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', 1) ",
|
||||
dbesc($url),
|
||||
dbesc(''),
|
||||
dbesc(''),
|
||||
dbesc(''),
|
||||
dbesc($mimetype),
|
||||
dbesc($pphoto),
|
||||
dbesc($addr),
|
||||
dbesc($url),
|
||||
dbesc(''),
|
||||
dbesc(''),
|
||||
dbesc(''),
|
||||
dbesc($name),
|
||||
dbesc($network),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert())
|
||||
);
|
||||
if($x) {
|
||||
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
|
||||
dbesc($url)
|
||||
);
|
||||
if($r) {
|
||||
|
||||
$photos = import_xchan_photo($pphoto,$url);
|
||||
if($photos) {
|
||||
$z = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s',
|
||||
xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($photos[0]),
|
||||
dbesc($photos[1]),
|
||||
dbesc($photos[2]),
|
||||
dbesc($photos[3]),
|
||||
dbesc($url)
|
||||
);
|
||||
}
|
||||
|
||||
set_xconfig($url,'system','openid',$authid);
|
||||
$_SESSION['authenticated'] = 1;
|
||||
$_SESSION['visitor_id'] = $r[0]['xchan_hash'];
|
||||
$_SESSION['my_url'] = $r[0]['xchan_url'];
|
||||
$_SESSION['my_address'] = $r[0]['xchan_addr'];
|
||||
$arr = array('xchan' => $r[0], 'session' => $_SESSION);
|
||||
call_hooks('magic_auth_openid_success',$arr);
|
||||
\App::set_observer($r[0]);
|
||||
info(sprintf( t('Welcome %s. Remote authentication successful.'),$r[0]['xchan_name']));
|
||||
logger('mod_openid: remote auth success from ' . $r[0]['xchan_addr']);
|
||||
if($_SESSION['return_url'])
|
||||
goaway($_SESSION['return_url']);
|
||||
goaway(z_root());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
notice( t('Login failed.') . EOL);
|
||||
goaway(z_root());
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,7 +13,7 @@ class Page extends \Zotlabs\Web\Controller {
|
||||
|
||||
$which = argv(1);
|
||||
$profile = 0;
|
||||
profile_load($a,$which,$profile);
|
||||
profile_load($which,$profile);
|
||||
|
||||
|
||||
|
||||
@@ -65,9 +65,10 @@ class Page extends \Zotlabs\Web\Controller {
|
||||
require_once('include/security.php');
|
||||
$sql_options = item_permissions_sql($u[0]['channel_id']);
|
||||
|
||||
$r = q("select item.* from item left join item_id on item.id = item_id.iid
|
||||
where item.uid = %d and sid = '%s' and item.item_delayed = 0 and (( service = 'WEBPAGE' and item_type = %d )
|
||||
OR ( service = 'PDL' AND item_type = %d )) $sql_options $revision limit 1",
|
||||
$r = q("select item.* from item left join iconfig on item.id = iconfig.iid
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and item.item_delayed = 0
|
||||
and (( iconfig.k = 'WEBPAGE' and item_type = %d )
|
||||
OR ( iconfig.k = 'PDL' AND item_type = %d )) $sql_options $revision limit 1",
|
||||
intval($u[0]['channel_id']),
|
||||
dbesc($page_id),
|
||||
intval(ITEM_TYPE_WEBPAGE),
|
||||
@@ -77,9 +78,9 @@ class Page extends \Zotlabs\Web\Controller {
|
||||
|
||||
// Check again with no permissions clause to see if it is a permissions issue
|
||||
|
||||
$x = q("select item.* from item left join item_id on item.id = item_id.iid
|
||||
where item.uid = %d and sid = '%s' and item.item_delayed = 0 and service = 'WEBPAGE' and
|
||||
item_type = %d $revision limit 1",
|
||||
$x = q("select item.* from item left join iconfig on item.id = iconfig.iid
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and item.item_delayed = 0
|
||||
and iconfig.k = 'WEBPAGE' and item_type = %d $revision limit 1",
|
||||
intval($u[0]['channel_id']),
|
||||
dbesc($page_id),
|
||||
intval(ITEM_TYPE_WEBPAGE)
|
||||
@@ -119,11 +120,8 @@ class Page extends \Zotlabs\Web\Controller {
|
||||
\App::$data['webpage'] = $r;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
function get() {
|
||||
|
||||
$r = \App::$data['webpage'];
|
||||
if(! $r)
|
||||
|
||||
@@ -20,7 +20,7 @@ class Pdledit extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
|
||||
function get() {
|
||||
function get() {
|
||||
|
||||
if(! local_channel()) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
@@ -32,18 +32,18 @@ class Pdledit extends \Zotlabs\Web\Controller {
|
||||
else {
|
||||
$o .= '<div class="generic-content-wrapper-styled">';
|
||||
$o .= '<h1>' . t('Edit System Page Description') . '</h1>';
|
||||
$files = glob('mod/*');
|
||||
$files = glob('Zotlabs/Module/*.php');
|
||||
if($files) {
|
||||
foreach($files as $f) {
|
||||
$name = basename($f,'.php');
|
||||
$name = lcfirst(basename($f,'.php'));
|
||||
$x = theme_include('mod_' . $name . '.pdl');
|
||||
if($x) {
|
||||
$o .= '<a href="pdledit/' . $name . '" >' . $name . '</a><br />';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$o .= '</div>';
|
||||
|
||||
$o .= '</div>';
|
||||
|
||||
// list module pdl files
|
||||
return $o;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/security.php');
|
||||
require_once('include/attach.php');
|
||||
require_once('include/photo/photo_driver.php');
|
||||
|
||||
|
||||
@@ -10,6 +11,8 @@ class Photo extends \Zotlabs\Web\Controller {
|
||||
function init() {
|
||||
|
||||
$prvcachecontrol = false;
|
||||
$streaming = null;
|
||||
$channel = null;
|
||||
|
||||
switch(argc()) {
|
||||
case 4:
|
||||
@@ -62,7 +65,7 @@ class Photo extends \Zotlabs\Web\Controller {
|
||||
intval($uid),
|
||||
intval(PHOTO_PROFILE)
|
||||
);
|
||||
if(count($r)) {
|
||||
if($r) {
|
||||
$data = dbunescbin($r[0]['content']);
|
||||
$mimetype = $r[0]['mimetype'];
|
||||
}
|
||||
@@ -79,7 +82,7 @@ class Photo extends \Zotlabs\Web\Controller {
|
||||
* Other photos
|
||||
*/
|
||||
|
||||
/* Check for a cookie to indicate display pixel density, in order to detect high-resolution
|
||||
/* Check for a cookie to indicate display pixel density, in order to detect high-resolution
|
||||
displays. This procedure was derived from the "Retina Images" by Jeremey Worboys,
|
||||
used in accordance with the Creative Commons Attribution 3.0 Unported License.
|
||||
Project link: https://github.com/Retina-Images/Retina-Images
|
||||
@@ -131,6 +134,8 @@ class Photo extends \Zotlabs\Web\Controller {
|
||||
|
||||
$sql_extra = permissions_sql($r[0]['uid']);
|
||||
|
||||
$channel = channelx_by_n($r[0]['uid']);
|
||||
|
||||
// Now we'll see if we can access the photo
|
||||
|
||||
$r = q("SELECT * FROM photo WHERE resource_id = '%s' AND imgscale = %d $sql_extra LIMIT 1",
|
||||
@@ -141,8 +146,9 @@ class Photo extends \Zotlabs\Web\Controller {
|
||||
if($r && $allowed) {
|
||||
$data = dbunescbin($r[0]['content']);
|
||||
$mimetype = $r[0]['mimetype'];
|
||||
if(intval($r[0]['os_storage']))
|
||||
$data = file_get_contents($data);
|
||||
if(intval($r[0]['os_storage'])) {
|
||||
$streaming = $data;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -242,7 +248,25 @@ class Photo extends \Zotlabs\Web\Controller {
|
||||
header("Cache-Control: max-age=" . $cache);
|
||||
|
||||
}
|
||||
echo $data;
|
||||
|
||||
// If it's a file resource, stream it.
|
||||
|
||||
if($streaming && $channel) {
|
||||
if(strpos($streaming,'store') !== false)
|
||||
$istream = fopen($streaming,'rb');
|
||||
else
|
||||
$istream = fopen('store/' . $channel['channel_address'] . '/' . $streaming,'rb');
|
||||
$ostream = fopen('php://output','wb');
|
||||
if($istream && $ostream) {
|
||||
pipe_streams($istream,$ostream);
|
||||
fclose($istream);
|
||||
fclose($ostream);
|
||||
}
|
||||
}
|
||||
else {
|
||||
echo $data;
|
||||
}
|
||||
|
||||
killme();
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
@@ -9,8 +9,6 @@ require_once('include/bbcode.php');
|
||||
require_once('include/security.php');
|
||||
require_once('include/attach.php');
|
||||
require_once('include/text.php');
|
||||
require_once('include/PermissionDescription.php');
|
||||
|
||||
|
||||
|
||||
class Photos extends \Zotlabs\Web\Controller {
|
||||
@@ -27,7 +25,7 @@ class Photos extends \Zotlabs\Web\Controller {
|
||||
if(argc() > 1) {
|
||||
$nick = argv(1);
|
||||
|
||||
profile_load($a,$nick);
|
||||
profile_load($nick);
|
||||
|
||||
$channelx = channelx_by_nick($nick);
|
||||
|
||||
@@ -633,7 +631,7 @@ class Photos extends \Zotlabs\Web\Controller {
|
||||
$lockstate = (($acl->is_private()) ? 'lock' : 'unlock');
|
||||
}
|
||||
|
||||
$aclselect = (($_is_owner) ? populate_acl($channel_acl,false, \PermissionDescription::fromGlobalPermission('view_storage')) : '');
|
||||
$aclselect = (($_is_owner) ? populate_acl($channel_acl,false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_storage')) : '');
|
||||
|
||||
// this is wrong but is to work around an issue with js_upload wherein it chokes if these variables
|
||||
// don't exist. They really should be set to a parseable representation of the channel's default permissions
|
||||
@@ -670,6 +668,10 @@ class Photos extends \Zotlabs\Web\Controller {
|
||||
'$selname' => $selname,
|
||||
'$permissions' => t('Permissions'),
|
||||
'$aclselect' => $aclselect,
|
||||
'$allow_cid' => acl2json($channel_acl['allow_cid']),
|
||||
'$allow_gid' => acl2json($channel_acl['allow_gid']),
|
||||
'$deny_cid' => acl2json($channel_acl['deny_cid']),
|
||||
'$deny_gid' => acl2json($channel_acl['deny_gid']),
|
||||
'$lockstate' => $lockstate,
|
||||
'$uploader' => $ret['addon_text'],
|
||||
'$default' => (($ret['default_upload']) ? true : false),
|
||||
@@ -1018,12 +1020,12 @@ class Photos extends \Zotlabs\Web\Controller {
|
||||
// FIXME - remove this when we move to conversation module
|
||||
|
||||
$r = $r[0]['children'];
|
||||
|
||||
|
||||
$edit = null;
|
||||
if($can_post) {
|
||||
$album_e = $ph[0]['album'];
|
||||
$caption_e = $ph[0]['description'];
|
||||
$aclselect_e = (($_is_owner) ? populate_acl($ph[0], true, \PermissionDescription::fromGlobalPermission('view_storage')) : '');
|
||||
$aclselect_e = (($_is_owner) ? populate_acl($ph[0], true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_storage')) : '');
|
||||
$albums = ((array_key_exists('albums', \App::$data)) ? \App::$data['albums'] : photos_albums_list(\App::$data['channel'],\App::$data['observer']));
|
||||
|
||||
$_SESSION['album_return'] = bin2hex($ph[0]['album']);
|
||||
@@ -1044,6 +1046,10 @@ class Photos extends \Zotlabs\Web\Controller {
|
||||
'tag_label' => t('Add a Tag'),
|
||||
'permissions' => t('Permissions'),
|
||||
'aclselect' => $aclselect_e,
|
||||
'allow_cid' => acl2json($ph[0]['allow_cid']),
|
||||
'allow_gid' => acl2json($ph[0]['allow_gid']),
|
||||
'deny_cid' => acl2json($ph[0]['deny_cid']),
|
||||
'deny_gid' => acl2json($ph[0]['deny_gid']),
|
||||
'lockstate' => $lockstate[0],
|
||||
'help_tags' => t('Example: @bob, @Barbara_Jensen, @jim@example.com'),
|
||||
'item_id' => ((count($linked_items)) ? $link_item['id'] : 0),
|
||||
|
||||
@@ -173,7 +173,7 @@ class Ping extends \Zotlabs\Web\Controller {
|
||||
);
|
||||
break;
|
||||
case 'all_events':
|
||||
$r = q("update event set `dimissed` = 1 where `dismissed` = 0 and uid = %d AND dtstart < '%s' AND dtstart > '%s' ",
|
||||
$r = q("update event set `dismissed` = 1 where `dismissed` = 0 and uid = %d AND dtstart < '%s' AND dtstart > '%s' ",
|
||||
intval(local_channel()),
|
||||
dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now + ' . intval($evdays) . ' days')),
|
||||
dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now - 1 days'))
|
||||
|
||||
@@ -23,8 +23,6 @@ class Probe extends \Zotlabs\Web\Controller {
|
||||
|
||||
$j = \Zotlabs\Zot\Finger::run($addr,$channel,false);
|
||||
|
||||
// $res = zot_finger($addr,$channel,false);
|
||||
|
||||
$o .= '<pre>';
|
||||
if(! $j['success']) {
|
||||
$o .= sprintf( t('Fetching URL returns error: %1$s'),$res['error'] . "\r\n\r\n");
|
||||
|
||||
@@ -48,7 +48,7 @@ class Profile extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
profile_load($a,$which,$profile);
|
||||
profile_load($which,$profile);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -23,19 +23,18 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
|
||||
/* @brief Initalize the profile-photo edit view
|
||||
*
|
||||
* @param $a Current application
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
function init() {
|
||||
function init() {
|
||||
|
||||
if(! local_channel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = \App::get_channel();
|
||||
profile_load($a,$channel['channel_address']);
|
||||
profile_load($channel['channel_address']);
|
||||
|
||||
}
|
||||
|
||||
@@ -46,7 +45,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
*
|
||||
*/
|
||||
|
||||
function post() {
|
||||
function post() {
|
||||
|
||||
if(! local_channel()) {
|
||||
return;
|
||||
@@ -54,24 +53,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
|
||||
check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo');
|
||||
|
||||
if((x($_POST,'cropfinal')) && ($_POST['cropfinal'] == 1)) {
|
||||
|
||||
// unless proven otherwise
|
||||
$is_default_profile = 1;
|
||||
|
||||
if($_REQUEST['profile']) {
|
||||
$r = q("select id, profile_guid, is_default, gender from profile where id = %d and uid = %d limit 1",
|
||||
intval($_REQUEST['profile']),
|
||||
intval(local_channel())
|
||||
);
|
||||
if($r) {
|
||||
$profile = $r[0];
|
||||
if(! intval($profile['is_default']))
|
||||
$is_default_profile = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if((array_key_exists('cropfinal',$_POST)) && (intval($_POST['cropfinal']) == 1)) {
|
||||
|
||||
// phase 2 - we have finished cropping
|
||||
|
||||
@@ -86,18 +68,33 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
$scale = substr($image_id,-1,1);
|
||||
$image_id = substr($image_id,0,-2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// unless proven otherwise
|
||||
$is_default_profile = 1;
|
||||
|
||||
if($_REQUEST['profile']) {
|
||||
$r = q("select id, profile_guid, is_default, gender from profile where id = %d and uid = %d limit 1",
|
||||
intval($_REQUEST['profile']),
|
||||
intval(local_channel())
|
||||
);
|
||||
if($r) {
|
||||
$profile = $r[0];
|
||||
if(! intval($profile['is_default']))
|
||||
$is_default_profile = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$srcX = $_POST['xstart'];
|
||||
$srcY = $_POST['ystart'];
|
||||
$srcW = $_POST['xfinal'] - $srcX;
|
||||
$srcH = $_POST['yfinal'] - $srcY;
|
||||
|
||||
|
||||
$r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale = %d LIMIT 1",
|
||||
dbesc($image_id),
|
||||
dbesc(local_channel()),
|
||||
intval($scale));
|
||||
|
||||
if($r) {
|
||||
|
||||
$base_image = $r[0];
|
||||
@@ -110,30 +107,38 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
|
||||
$aid = get_account_id();
|
||||
|
||||
$p = array('aid' => $aid, 'uid' => local_channel(), 'resource_id' => $base_image['resource_id'],
|
||||
'filename' => $base_image['filename'], 'album' => t('Profile Photos'));
|
||||
$p = [
|
||||
'aid' => $aid,
|
||||
'uid' => local_channel(),
|
||||
'resource_id' => $base_image['resource_id'],
|
||||
'filename' => $base_image['filename'],
|
||||
'album' => t('Profile Photos')
|
||||
];
|
||||
|
||||
$p['imgscale'] = 4;
|
||||
$p['imgscale'] = PHOTO_RES_PROFILE_300;
|
||||
$p['photo_usage'] = (($is_default_profile) ? PHOTO_PROFILE : PHOTO_NORMAL);
|
||||
|
||||
$r1 = $im->save($p);
|
||||
|
||||
$im->scaleImage(80);
|
||||
$p['imgscale'] = 5;
|
||||
$p['imgscale'] = PHOTO_RES_PROFILE_80;
|
||||
|
||||
$r2 = $im->save($p);
|
||||
|
||||
$im->scaleImage(48);
|
||||
$p['imgscale'] = 6;
|
||||
$p['imgscale'] = PHOTO_RES_PROFILE_48;
|
||||
|
||||
$r3 = $im->save($p);
|
||||
|
||||
if($r1 === false || $r2 === false || $r3 === false) {
|
||||
// if one failed, delete them all so we can start over.
|
||||
notice( t('Image resize failed.') . EOL );
|
||||
$x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale >= 4 ",
|
||||
$x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale in ( %d, %d, %d ) ",
|
||||
dbesc($base_image['resource_id']),
|
||||
local_channel()
|
||||
local_channel(),
|
||||
intval(PHOTO_RES_PROFILE_300),
|
||||
intval(PHOTO_RES_PROFILE_80),
|
||||
intval(PHOTO_RES_PROFILE_48)
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -175,6 +180,8 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($channel['xchan_hash'])
|
||||
);
|
||||
// Similarly, tell the nav bar to bypass the cache and update the avater image.
|
||||
$_SESSION['reload_avatar'] = true;
|
||||
|
||||
info( t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL);
|
||||
|
||||
@@ -183,10 +190,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
|
||||
// Now copy profile-permissions to pictures, to prevent privacyleaks by automatically created folder 'Profile Pictures'
|
||||
|
||||
profile_photo_set_profile_perms($_REQUEST['profile']);
|
||||
|
||||
|
||||
|
||||
profile_photo_set_profile_perms(local_channel(),$_REQUEST['profile']);
|
||||
}
|
||||
else
|
||||
notice( t('Unable to process image') . EOL);
|
||||
@@ -196,7 +200,9 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
return; // NOTREACHED
|
||||
}
|
||||
|
||||
|
||||
// A new photo was uploaded. Store it and save some important details
|
||||
// in App::$data for use in the cropping function
|
||||
|
||||
|
||||
$hash = photo_new_resource();
|
||||
$smallest = 0;
|
||||
@@ -220,7 +226,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
$os_storage = false;
|
||||
|
||||
foreach($i as $ii) {
|
||||
if(intval($ii['imgscale']) < 2) {
|
||||
if(intval($ii['imgscale']) < PHOTO_RES_640) {
|
||||
$smallest = intval($ii['imgscale']);
|
||||
$os_storage = intval($ii['os_storage']);
|
||||
$imagedata = $ii['content'];
|
||||
@@ -238,7 +244,10 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
return $this->profile_photo_crop_ui_head($a, $ph, $hash, $smallest);
|
||||
|
||||
|
||||
// This will "fall through" to the get() method, and since
|
||||
// App::$data['imagecrop'] is set, it will proceed to cropping
|
||||
// rather than present the upload form
|
||||
}
|
||||
|
||||
|
||||
@@ -269,11 +278,19 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
notice( t('Permission denied.') . EOL );
|
||||
return;
|
||||
};
|
||||
|
||||
// check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo');
|
||||
|
||||
|
||||
$resource_id = argv(2);
|
||||
|
||||
// When using an existing photo, we don't have a dialogue to offer a choice of profiles,
|
||||
// so it gets attached to the default
|
||||
|
||||
$p = q("select id from profile where is_default = 1 and uid = %d",
|
||||
intval(local_channel())
|
||||
);
|
||||
if($p) {
|
||||
$_REQUEST['profile'] = $p[0]['id'];
|
||||
}
|
||||
|
||||
|
||||
$r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY imgscale ASC",
|
||||
intval(local_channel()),
|
||||
@@ -285,11 +302,11 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
$havescale = false;
|
||||
foreach($r as $rr) {
|
||||
if($rr['imgscale'] == 5)
|
||||
if($rr['imgscale'] == PHOTO_RES_PROFILE_80)
|
||||
$havescale = true;
|
||||
}
|
||||
|
||||
// set an already loaded photo as profile photo
|
||||
// set an already loaded and cropped photo as profile photo
|
||||
|
||||
if(($r[0]['album'] == t('Profile Photos')) && ($havescale)) {
|
||||
// unset any existing profile photos
|
||||
@@ -310,7 +327,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
dbesc($channel['xchan_hash'])
|
||||
);
|
||||
|
||||
profile_photo_set_profile_perms(); //Reset default photo permissions to public
|
||||
profile_photo_set_profile_perms(local_channel()); // Reset default photo permissions to public
|
||||
\Zotlabs\Daemon\Master::Summon(array('Directory',local_channel()));
|
||||
goaway(z_root() . '/profiles');
|
||||
}
|
||||
@@ -342,17 +359,22 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
if($i) {
|
||||
$hash = $i[0]['resource_id'];
|
||||
foreach($i as $ii) {
|
||||
if(intval($ii['imgscale']) < 2) {
|
||||
if(intval($ii['imgscale']) < PHOTO_RES_640) {
|
||||
$smallest = intval($ii['imgscale']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
profile_photo_crop_ui_head($a, $ph, $hash, $smallest);
|
||||
$this->profile_photo_crop_ui_head($a, $ph, $hash, $smallest);
|
||||
|
||||
// falls through with App::$data['imagecrop'] set so we go straight to the cropping section
|
||||
}
|
||||
|
||||
$profiles = q("select id, profile_name as name, is_default from profile where uid = %d",
|
||||
|
||||
// present an upload form
|
||||
|
||||
$profiles = q("select id, profile_name as name, is_default from profile where uid = %d order by id asc",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
@@ -379,6 +401,9 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
return $o;
|
||||
}
|
||||
else {
|
||||
|
||||
// present a cropping form
|
||||
|
||||
$filename = \App::$data['imagecrop'] . '-' . \App::$data['imagecrop_resolution'];
|
||||
$resolution = \App::$data['imagecrop_resolution'];
|
||||
$tpl = get_markup_template("cropbody.tpl");
|
||||
@@ -416,13 +441,13 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
if($max_length > 0)
|
||||
$ph->scaleImage($max_length);
|
||||
|
||||
$width = $ph->getWidth();
|
||||
$height = $ph->getHeight();
|
||||
\App::$data['width'] = $ph->getWidth();
|
||||
\App::$data['height'] = $ph->getHeight();
|
||||
|
||||
if($width < 500 || $height < 500) {
|
||||
if(\App::$data['width'] < 500 || \App::$data['height'] < 500) {
|
||||
$ph->scaleImageUp(400);
|
||||
$width = $ph->getWidth();
|
||||
$height = $ph->getHeight();
|
||||
\App::$data['width'] = $ph->getWidth();
|
||||
\App::$data['height'] = $ph->getHeight();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -193,7 +193,7 @@ class Profiles extends \Zotlabs\Web\Controller {
|
||||
|
||||
$chan = \App::get_channel();
|
||||
|
||||
profile_load($a,$chan['channel_address'],$r[0]['id']);
|
||||
profile_load($chan['channel_address'],$r[0]['id']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -584,7 +584,7 @@ class Profiles extends \Zotlabs\Web\Controller {
|
||||
|
||||
if($is_default) {
|
||||
// reload the info for the sidebar widget - why does this not work?
|
||||
profile_load($a,$channel['channel_address']);
|
||||
profile_load($channel['channel_address']);
|
||||
\Zotlabs\Daemon\Master::Summon(array('Directory',local_channel()));
|
||||
}
|
||||
}
|
||||
@@ -708,7 +708,7 @@ class Profiles extends \Zotlabs\Web\Controller {
|
||||
'$profile_id' => $r[0]['id'],
|
||||
'$profile_name' => array('profile_name', t('Profile name'), $r[0]['profile_name'], t('Required'), '*'),
|
||||
'$is_default' => $is_default,
|
||||
'$default' => t('This is your default profile.') . EOL . translate_scope(map_scope($channel['channel_r_profile'])),
|
||||
'$default' => t('This is your default profile.') . EOL . translate_scope(map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'view_profile'))),
|
||||
'$advanced' => $advanced,
|
||||
'$name' => array('name', t('Your full name'), $r[0]['fullname'], t('Required'), '*'),
|
||||
'$pdesc' => array('pdesc', t('Title/Description'), $r[0]['pdesc']),
|
||||
@@ -767,7 +767,7 @@ class Profiles extends \Zotlabs\Web\Controller {
|
||||
'$alt' => t('Profile Image'),
|
||||
'$profile_name' => $rr['profile_name'],
|
||||
'$visible' => (($rr['is_default'])
|
||||
? '<strong>' . translate_scope(map_scope($channel['channel_r_profile'])) . '</strong>'
|
||||
? '<strong>' . translate_scope(map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'view_profile'))) . '</strong>'
|
||||
: '<a href="' . z_root() . '/profperm/' . $rr['id'] . '" />' . t('Edit visibility') . '</a>')
|
||||
));
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class Profperm extends \Zotlabs\Web\Controller {
|
||||
|
||||
$profile = \App::$argv[1];
|
||||
|
||||
profile_load($a,$which,$profile);
|
||||
profile_load($which,$profile);
|
||||
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ class Profperm extends \Zotlabs\Web\Controller {
|
||||
|
||||
//Time to update the permissions on the profile-pictures as well
|
||||
|
||||
profile_photo_set_profile_perms($profile['id']);
|
||||
profile_photo_set_profile_perms(local_channel(),$profile['id']);
|
||||
|
||||
$r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d AND abook_profile = '%s'",
|
||||
intval(local_channel()),
|
||||
|
||||
80
Zotlabs/Module/README.md
Normal file
80
Zotlabs/Module/README.md
Normal file
@@ -0,0 +1,80 @@
|
||||
Zotlabs/Module
|
||||
==============
|
||||
|
||||
|
||||
This directory contains controller modules for handling web requests. The
|
||||
lowercase class name indicates the head of the URL path which this module
|
||||
handles. There are other methods of attaching (routing) URL paths to
|
||||
controllers, but this is the primary method used in this project.
|
||||
|
||||
Module controllers MUST reside in this directory and namespace to be
|
||||
autoloaded (unless other specific routing methods are employed). They
|
||||
typically use and extend the class definition in Zotlabs/Web/Controller
|
||||
as a template.
|
||||
|
||||
Template:
|
||||
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Web;
|
||||
|
||||
|
||||
class Controller {
|
||||
|
||||
function init() {}
|
||||
function post() {}
|
||||
function get() {}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Typical Module declaration for the '/foo' URL route:
|
||||
|
||||
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
class Foo extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
// init() handler goes here
|
||||
}
|
||||
|
||||
function post() {
|
||||
// post handler goes here
|
||||
}
|
||||
|
||||
function get() {
|
||||
return 'Hello world.' . EOL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
This model provides callbacks for public functions named init(), post(),
|
||||
and get(). init() is always called. post() is called if $_POST variables
|
||||
are present, and get() is called if none of the prior functions terminated
|
||||
the handler. The get() method typically retuns a string which represents
|
||||
the contents of the content region of the resulting page. Modules which emit
|
||||
json, xml or other machine-readable formats typically emit their contents
|
||||
inside the init() function and call 'killme()' to terminate the Module.
|
||||
|
||||
Modules are passed the URL path as argc,argv arguments. For a path such as
|
||||
|
||||
https://mysite.something/foo/bar/baz
|
||||
|
||||
The app will typically invoke the Module class 'Foo' and pass it
|
||||
|
||||
$x = argc(); // $x = 3
|
||||
|
||||
$x = argv(0); // $x = 'foo'
|
||||
$x = argv(1); // $x = 'bar'
|
||||
$x = argv(2); // $x = 'baz'
|
||||
|
||||
These are handled in a similar fashion to their counterparts in the Unix shell
|
||||
or C/C++ languages. Do not confuse the argc(),argv() functions with the
|
||||
global variables $argc,$argv which are passed to command line programs. These
|
||||
are handled separately by command line and Zotlabs/Daemon class functions.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ class Rate extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
|
||||
function post() {
|
||||
function post() {
|
||||
|
||||
if(! local_channel())
|
||||
return;
|
||||
|
||||
@@ -58,7 +58,9 @@ class Ratingsearch extends \Zotlabs\Web\Controller {
|
||||
$ret['success'] = true;
|
||||
|
||||
$r = q("select * from xlink left join xchan on xlink_xchan = xchan_hash
|
||||
where xlink_link = '%s' and xlink_rating != 0 and xlink_static = 1 order by xchan_name asc",
|
||||
where xlink_link = '%s' and xlink_rating != 0 and xlink_static = 1
|
||||
and xchan_hidden = 0 and xchan_orphan = 0 and xchan_deleted = 0
|
||||
order by xchan_name asc",
|
||||
dbesc($target)
|
||||
);
|
||||
|
||||
|
||||
@@ -146,12 +146,12 @@ class Register extends \Zotlabs\Web\Controller {
|
||||
goaway(z_root());
|
||||
}
|
||||
|
||||
authenticate_success($result['account'],true,false,true);
|
||||
authenticate_success($result['account'],null,true,false,true);
|
||||
|
||||
$new_channel = false;
|
||||
$next_page = 'new_channel';
|
||||
|
||||
if(get_config('system','auto_channel_create') || UNO) {
|
||||
if(get_config('system','auto_channel_create') || get_config('system','server_role') == 'basic') {
|
||||
$new_channel = auto_channel_create($result['account']['account_id']);
|
||||
if($new_channel['success']) {
|
||||
$channel_id = $new_channel['channel']['channel_id'];
|
||||
@@ -234,9 +234,12 @@ class Register extends \Zotlabs\Web\Controller {
|
||||
$privacy_role = ((x($_REQUEST,'permissions_role')) ? $_REQUEST['permissions_role'] : "");
|
||||
$role = array('permissions_role' , t('Channel role and privacy'), ($privacy_role) ? $privacy_role : 'social', t('Select a channel role with your privacy requirements.') . ' <a href="help/roles" target="_blank">' . t('Read more about roles') . '</a>',get_roles());
|
||||
$tos = array('tos', $label_tos, '', '', array(t('no'),t('yes')));
|
||||
|
||||
$auto_create = ((UNO) || (get_config('system','auto_channel_create')) ? true : false);
|
||||
$default_role = ((UNO) ? 'social' : get_config('system','default_permissions_role'));
|
||||
|
||||
$server_role = get_config('system','server_role');
|
||||
|
||||
|
||||
$auto_create = (($server_role == 'basic') || (get_config('system','auto_channel_create')) ? true : false);
|
||||
$default_role = (($server_role == 'basic') ? 'social' : get_config('system','default_permissions_role'));
|
||||
|
||||
require_once('include/bbcode.php');
|
||||
|
||||
@@ -259,7 +262,8 @@ class Register extends \Zotlabs\Web\Controller {
|
||||
'$email' => $email,
|
||||
'$pass1' => $password,
|
||||
'$pass2' => $password2,
|
||||
'$submit' => ((UNO || $auto_create || $registration_is) ? t('Register') : t('Proceed to create your first channel'))
|
||||
'$submit' => t('Register'),
|
||||
'$verify_note' => t('This site may require email verification after submitting this form. If you are returned to a login page, please check your email for instructions.')
|
||||
));
|
||||
|
||||
return $o;
|
||||
|
||||
@@ -25,7 +25,8 @@ class Removeaccount extends \Zotlabs\Web\Controller {
|
||||
$account = \App::get_account();
|
||||
$account_id = get_account_id();
|
||||
|
||||
if(! account_verify_password($account['account_email'],$_POST['qxz_password']))
|
||||
$x = account_verify_password($account['account_email'],$_POST['qxz_password']);
|
||||
if(! ($x && $x['account']))
|
||||
return;
|
||||
|
||||
if($account['account_password_changed'] != NULL_DATE) {
|
||||
|
||||
@@ -24,7 +24,9 @@ class Removeme extends \Zotlabs\Web\Controller {
|
||||
|
||||
$account = \App::get_account();
|
||||
|
||||
if(! account_verify_password($account['account_email'],$_POST['qxz_password']))
|
||||
|
||||
$x = account_verify_password($account['account_email'],$_POST['qxz_password']);
|
||||
if(! ($x && $x['account']))
|
||||
return;
|
||||
|
||||
if($account['account_password_changed'] != NULL_DATE) {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
|
||||
|
||||
class Rmagic extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
@@ -32,18 +31,6 @@ class Rmagic extends \Zotlabs\Web\Controller {
|
||||
$arr = array('address' => $address);
|
||||
call_hooks('reverse_magic_auth', $arr);
|
||||
|
||||
try {
|
||||
require_once('library/openid/openid.php');
|
||||
$openid = new \LightOpenID(z_root());
|
||||
$openid->identity = $address;
|
||||
$openid->returnUrl = z_root() . '/openid';
|
||||
$openid->required = array('namePerson/friendly', 'namePerson');
|
||||
$openid->optional = array('namePerson/first','media/image/aspect11','media/image/default');
|
||||
goaway($openid->authUrl());
|
||||
} catch (\Exception $e) {
|
||||
notice( t('We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.').'<br /><br >'. t('The error message was:').' '.$e->getMessage());
|
||||
}
|
||||
|
||||
// if they're still here...
|
||||
notice( t('Authentication failed.') . EOL);
|
||||
return;
|
||||
|
||||
@@ -7,7 +7,6 @@ require_once('include/items.php');
|
||||
require_once('include/taxonomy.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/zot.php');
|
||||
require_once('include/PermissionDescription.php');
|
||||
|
||||
/**
|
||||
* remote post
|
||||
@@ -116,7 +115,8 @@ class Rpost extends \Zotlabs\Web\Controller {
|
||||
'default_location' => $channel['channel_location'],
|
||||
'nickname' => $channel['channel_address'],
|
||||
'lockstate' => (($acl->is_private()) ? 'lock' : 'unlock'),
|
||||
'acl' => populate_acl($channel_acl, true, \PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
|
||||
'acl' => populate_acl($channel_acl, true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
|
||||
'permissions' => $channel_acl,
|
||||
'bang' => '',
|
||||
'visitor' => true,
|
||||
'profile_uid' => local_channel(),
|
||||
@@ -126,6 +126,7 @@ class Rpost extends \Zotlabs\Web\Controller {
|
||||
'source' => ((x($_REQUEST,'source')) ? strip_tags($_REQUEST['source']) : ''),
|
||||
'return_path' => 'rpost/return',
|
||||
'bbco_autocomplete' => 'bbcode',
|
||||
'editor_autocomplete'=> true,
|
||||
'bbcode' => true
|
||||
);
|
||||
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
namespace Zotlabs\Module; /** @file */
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/PermissionDescription.php');
|
||||
|
||||
|
||||
require_once('include/security.php');
|
||||
|
||||
class Settings extends \Zotlabs\Web\Controller {
|
||||
|
||||
@@ -23,14 +21,11 @@ class Settings extends \Zotlabs\Web\Controller {
|
||||
// We are setting these values - don't use the argc(), argv() functions here
|
||||
\App::$argc = 2;
|
||||
\App::$argv[] = 'channel';
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function post() {
|
||||
function post() {
|
||||
|
||||
if(! local_channel())
|
||||
return;
|
||||
@@ -40,7 +35,7 @@ class Settings extends \Zotlabs\Web\Controller {
|
||||
|
||||
$channel = \App::get_channel();
|
||||
|
||||
logger('mod_settings: ' . print_r($_REQUEST,true));
|
||||
// logger('mod_settings: ' . print_r($_REQUEST,true));
|
||||
|
||||
|
||||
if((argc() > 1) && (argv(1) === 'oauth') && x($_POST,'remove')){
|
||||
@@ -119,6 +114,76 @@ class Settings extends \Zotlabs\Web\Controller {
|
||||
build_sync_packet();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if((argc() > 1) && (argv(1) == 'tokens')) {
|
||||
check_form_security_token_redirectOnErr('/settings/tokens', 'settings_tokens');
|
||||
$token_errs = 0;
|
||||
if(array_key_exists('token',$_POST)) {
|
||||
$atoken_id = (($_POST['atoken_id']) ? intval($_POST['atoken_id']) : 0);
|
||||
$name = trim(escape_tags($_POST['name']));
|
||||
$token = trim($_POST['token']);
|
||||
if((! $name) || (! $token))
|
||||
$token_errs ++;
|
||||
if(trim($_POST['expires']))
|
||||
$expires = datetime_convert(date_default_timezone_get(),'UTC',$_POST['expires']);
|
||||
else
|
||||
$expires = NULL_DATE;
|
||||
$max_atokens = service_class_fetch(local_channel(),'access_tokens');
|
||||
if($max_atokens) {
|
||||
$r = q("select count(atoken_id) as total where atoken_uid = %d",
|
||||
intval(local_channel())
|
||||
);
|
||||
if($r && intval($r[0]['total']) >= $max_tokens) {
|
||||
notice( sprintf( t('This channel is limited to %d tokens'), $max_tokens) . EOL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if($token_errs) {
|
||||
notice( t('Name and Password are required.') . EOL);
|
||||
return;
|
||||
}
|
||||
if($atoken_id) {
|
||||
$r = q("update atoken set atoken_name = '%s', atoken_token = '%s', atoken_expires = '%s'
|
||||
where atoken_id = %d and atoken_uid = %d",
|
||||
dbesc($name),
|
||||
dbesc($token),
|
||||
dbesc($expires),
|
||||
intval($atoken_id),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
}
|
||||
else {
|
||||
$r = q("insert into atoken ( atoken_aid, atoken_uid, atoken_name, atoken_token, atoken_expires )
|
||||
values ( %d, %d, '%s', '%s', '%s' ) ",
|
||||
intval($channel['channel_account_id']),
|
||||
intval($channel['channel_id']),
|
||||
dbesc($name),
|
||||
dbesc($token),
|
||||
dbesc($expires)
|
||||
);
|
||||
}
|
||||
|
||||
$atoken_xchan = substr($channel['channel_hash'],0,16) . '.' . $name;
|
||||
|
||||
$all_perms = \Zotlabs\Access\Permissions::Perms();
|
||||
|
||||
if($all_perms) {
|
||||
foreach($all_perms as $perm => $desc) {
|
||||
if(array_key_exists('perms_' . $perm, $_POST)) {
|
||||
set_abconfig($channel['channel_id'],$atoken_xchan,'my_perms',$perm,intval($_POST['perms_' . $perm]));
|
||||
}
|
||||
else {
|
||||
set_abconfig($channel['channel_id'],$atoken_xchan,'my_perms',$perm,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
info( t('Token saved.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -221,7 +286,7 @@ class Settings extends \Zotlabs\Web\Controller {
|
||||
$email = ((x($_POST,'email')) ? trim(notags($_POST['email'])) : '');
|
||||
$account = \App::get_account();
|
||||
if($email != $account['account_email']) {
|
||||
if(! valid_email($email))
|
||||
if(! valid_email($email))
|
||||
$errs[] = t('Not valid email.');
|
||||
$adm = trim(get_config('system','admin_email'));
|
||||
if(($adm) && (strcasecmp($email,$adm) == 0)) {
|
||||
@@ -311,10 +376,10 @@ class Settings extends \Zotlabs\Web\Controller {
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
$global_perms = get_perms();
|
||||
$global_perms = \Zotlabs\Access\Permissions::Perms();
|
||||
|
||||
foreach($global_perms as $k => $v) {
|
||||
$set_perms .= ', ' . $v[0] . ' = ' . intval($_POST[$k]) . ' ';
|
||||
\Zotlabs\Access\PermissionLimits::Set(local_channel(),$k,intval($_POST[$k]));
|
||||
}
|
||||
$acl = new \Zotlabs\Access\AccessList($channel);
|
||||
$acl->set_from_array($_POST);
|
||||
@@ -329,8 +394,8 @@ class Settings extends \Zotlabs\Web\Controller {
|
||||
intval(local_channel())
|
||||
);
|
||||
}
|
||||
else {
|
||||
$role_permissions = get_role_perms($_POST['permissions_role']);
|
||||
else {
|
||||
$role_permissions = \Zotlabs\Access\PermissionRoles::role_perms($_POST['permissions_role']);
|
||||
if(! $role_permissions) {
|
||||
notice('Permissions category could not be found.');
|
||||
return;
|
||||
@@ -370,19 +435,24 @@ class Settings extends \Zotlabs\Web\Controller {
|
||||
);
|
||||
}
|
||||
|
||||
$r = q("update abook set abook_my_perms = %d where abook_channel = %d and abook_self = 1",
|
||||
intval((array_key_exists('perms_accept',$role_permissions)) ? $role_permissions['perms_accept'] : 0),
|
||||
intval(local_channel())
|
||||
);
|
||||
set_pconfig(local_channel(),'system','autoperms',(($role_permissions['perms_auto']) ? intval($role_permissions['perms_accept']) : 0));
|
||||
|
||||
foreach($role_permissions as $p => $v) {
|
||||
if(strpos($p,'channel_') !== false) {
|
||||
$set_perms .= ', ' . $p . ' = ' . intval($v) . ' ';
|
||||
$x = \Zotlabs\Access\Permissions::FilledPerms($role_permissions['perms_connect']);
|
||||
foreach($x as $k => $v) {
|
||||
set_abconfig(local_channel(),$channel['channel_hash'],'my_perms',$k, $v);
|
||||
if($role_permissions['perms_auto']) {
|
||||
set_pconfig(local_channel(),'autoperms',$k,$v);
|
||||
}
|
||||
if($p === 'directory_publish') {
|
||||
$publish = intval($v);
|
||||
else {
|
||||
del_pconfig(local_channel(),'autoperms',$k);
|
||||
}
|
||||
}
|
||||
|
||||
if($role_permissions['limits']) {
|
||||
foreach($role_permissions['limits'] as $k => $v) {
|
||||
\Zotlabs\Access\PermissionLimits::Set(local_channel(),$k,$v);
|
||||
}
|
||||
}
|
||||
if(array_key_exists('directory_publish',$role_permissions)) {
|
||||
$publish = intval($role_permissions['directory_publish']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -708,6 +778,95 @@ class Settings extends \Zotlabs\Web\Controller {
|
||||
));
|
||||
return $o;
|
||||
}
|
||||
|
||||
if((argc() > 1) && (argv(1) === 'tokens')) {
|
||||
$atoken = null;
|
||||
$atoken_xchan = '';
|
||||
|
||||
if(argc() > 2) {
|
||||
$id = argv(2);
|
||||
|
||||
$atoken = q("select * from atoken where atoken_id = %d and atoken_uid = %d",
|
||||
intval($id),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
if($atoken) {
|
||||
$atoken = $atoken[0];
|
||||
$atoken_xchan = substr($channel['channel_hash'],0,16) . '.' . $atoken['atoken_name'];
|
||||
}
|
||||
|
||||
if($atoken && argc() > 3 && argv(3) === 'drop') {
|
||||
atoken_delete($id);
|
||||
$atoken = null;
|
||||
$atoken_xchan = '';
|
||||
}
|
||||
}
|
||||
|
||||
$t = q("select * from atoken where atoken_uid = %d",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
$desc = t('Use this form to create temporary access identifiers to share things with non-members. These identities may be used in Access Control Lists and visitors may login using these credentials to access private content.');
|
||||
|
||||
$desc2 = t('You may also provide <em>dropbox</em> style access links to friends and associates by adding the Login Password to any specific site URL as shown. Examples:');
|
||||
|
||||
$global_perms = \Zotlabs\Access\Permissions::Perms();
|
||||
|
||||
$existing = get_all_perms(local_channel(),(($atoken_xchan) ? $atoken_xchan : ''));
|
||||
|
||||
if($atoken_xchan) {
|
||||
$theirs = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'their_perms'",
|
||||
intval(local_channel()),
|
||||
dbesc($atoken_xchan)
|
||||
);
|
||||
$their_perms = array();
|
||||
if($theirs) {
|
||||
foreach($theirs as $t) {
|
||||
$their_perms[$t['k']] = $t['v'];
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach($global_perms as $k => $v) {
|
||||
$thisperm = get_abconfig(local_channel(),$contact['abook_xchan'],'my_perms',$k);
|
||||
//fixme
|
||||
|
||||
$checkinherited = \Zotlabs\Access\PermissionLimits::Get(local_channel(),$k);
|
||||
|
||||
if($existing[$k])
|
||||
$thisperm = "1";
|
||||
|
||||
$perms[] = array('perms_' . $k, $v, ((array_key_exists($k,$their_perms)) ? intval($their_perms[$k]) : ''),$thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '' : '1'), '', $checkinherited);
|
||||
}
|
||||
|
||||
|
||||
|
||||
$tpl = get_markup_template("settings_tokens.tpl");
|
||||
$o .= replace_macros($tpl, array(
|
||||
'$form_security_token' => get_form_security_token("settings_tokens"),
|
||||
'$title' => t('Guest Access Tokens'),
|
||||
'$desc' => $desc,
|
||||
'$desc2' => $desc2,
|
||||
'$tokens' => $t,
|
||||
'$atoken' => $atoken,
|
||||
'$url1' => z_root() . '/channel/' . $channel['channel_address'],
|
||||
'$url2' => z_root() . '/photos/' . $channel['channel_address'],
|
||||
'$name' => array('name', t('Login Name') . ' <span class="required">*</span>', (($atoken) ? $atoken['atoken_name'] : ''),''),
|
||||
'$token'=> array('token', t('Login Password') . ' <span class="required">*</span>',(($atoken) ? $atoken['atoken_token'] : autoname(8)), ''),
|
||||
'$expires'=> array('expires', t('Expires (yyyy-mm-dd)'), (($atoken['atoken_expires'] && $atoken['atoken_expires'] != NULL_DATE) ? datetime_convert('UTC',date_default_timezone_get(),$atoken['atoken_expires']) : ''), ''),
|
||||
'$them' => t('Their Settings'),
|
||||
'$me' => t('My Settings'),
|
||||
'$perms' => $perms,
|
||||
'$inherited' => t('inherited'),
|
||||
'$notself' => '1',
|
||||
'$permlbl' => t('Individual Permissions'),
|
||||
'$permnote' => t('Some permissions may be inherited from your channel\'s <a href="settings"><strong>privacy settings</strong></a>, which have higher priority than individual settings. You can <strong>not</strong> change those settings here.'),
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -864,11 +1023,7 @@ class Settings extends \Zotlabs\Web\Controller {
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if(argv(1) === 'channel') {
|
||||
|
||||
require_once('include/acl_selectors.php');
|
||||
@@ -885,9 +1040,8 @@ class Settings extends \Zotlabs\Web\Controller {
|
||||
|
||||
$channel = \App::get_channel();
|
||||
|
||||
|
||||
$global_perms = get_perms();
|
||||
|
||||
$global_perms = \Zotlabs\Access\Permissions::Perms();
|
||||
|
||||
$permiss = array();
|
||||
|
||||
$perm_opts = array(
|
||||
@@ -901,19 +1055,18 @@ class Settings extends \Zotlabs\Web\Controller {
|
||||
array( t('Anybody on the internet'), PERMS_PUBLIC)
|
||||
);
|
||||
|
||||
$limits = \Zotlabs\Access\PermissionLimits::Get(local_channel());
|
||||
|
||||
foreach($global_perms as $k => $perm) {
|
||||
$options = array();
|
||||
foreach($perm_opts as $opt) {
|
||||
if((! $perm[2]) && $opt[1] == PERMS_PUBLIC)
|
||||
continue;
|
||||
$options[$opt[1]] = $opt[0];
|
||||
}
|
||||
$permiss[] = array($k,$perm[3],$channel[$perm[0]],$perm[4],$options);
|
||||
$permiss[] = array($k,$perm,$limits[$k],'',$options);
|
||||
}
|
||||
|
||||
|
||||
// logger('permiss: ' . print_r($permiss,true));
|
||||
//logger('permiss: ' . print_r($permiss,true));
|
||||
|
||||
|
||||
|
||||
@@ -1066,7 +1219,11 @@ class Settings extends \Zotlabs\Web\Controller {
|
||||
'$maxreq' => array('maxreq', t('Maximum Friend Requests/Day:'), intval($channel['channel_max_friend_req']) , t('May reduce spam activity')),
|
||||
'$permissions' => t('Default Post and Publish Permissions'),
|
||||
'$permdesc' => t("\x28click to open/close\x29"),
|
||||
'$aclselect' => populate_acl($perm_defaults, false, \PermissionDescription::fromDescription(t('Use my default audience setting for the type of object published'))),
|
||||
'$aclselect' => populate_acl($perm_defaults, false, \Zotlabs\Lib\PermissionDescription::fromDescription(t('Use my default audience setting for the type of object published'))),
|
||||
'$allow_cid' => acl2json($perm_defaults['allow_cid']),
|
||||
'$allow_gid' => acl2json($perm_defaults['allow_gid']),
|
||||
'$deny_cid' => acl2json($perm_defaults['deny_cid']),
|
||||
'$deny_gid' => acl2json($perm_defaults['deny_gid']),
|
||||
'$suggestme' => $suggestme,
|
||||
'$group_select' => $group_select,
|
||||
'$role' => array('permissions_role' , t('Channel permissions category:'), $permissions_role, '', get_roles()),
|
||||
@@ -1129,7 +1286,7 @@ class Settings extends \Zotlabs\Web\Controller {
|
||||
|
||||
call_hooks('settings_form',$o);
|
||||
|
||||
$o .= '</form>' . "\r\n";
|
||||
//$o .= '</form>' . "\r\n";
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
$timezone = notags(trim($_POST['timezone']));
|
||||
$adminmail = notags(trim($_POST['adminmail']));
|
||||
$siteurl = notags(trim($_POST['siteurl']));
|
||||
$advanced = ((intval($_POST['advanced'])) ? 1 : 0);
|
||||
$advanced = ((intval($_POST['advanced'])) ? 'pro' : 'basic');
|
||||
|
||||
if($siteurl != z_root()) {
|
||||
$test = z_fetch_url($siteurl."/setup/testrewrite");
|
||||
@@ -124,17 +124,17 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
|
||||
$tpl = get_intltext_template('htconfig.tpl');
|
||||
$txt = replace_macros($tpl,array(
|
||||
'$dbhost' => $dbhost,
|
||||
'$dbport' => $dbport,
|
||||
'$dbuser' => $dbuser,
|
||||
'$dbpass' => $dbpass,
|
||||
'$dbdata' => $dbdata,
|
||||
'$dbtype' => $dbtype,
|
||||
'$uno' => 1 - $advanced,
|
||||
'$timezone' => $timezone,
|
||||
'$siteurl' => $siteurl,
|
||||
'$site_id' => random_string(),
|
||||
'$phpath' => $phpath,
|
||||
'$dbhost' => $dbhost,
|
||||
'$dbport' => $dbport,
|
||||
'$dbuser' => $dbuser,
|
||||
'$dbpass' => $dbpass,
|
||||
'$dbdata' => $dbdata,
|
||||
'$dbtype' => $dbtype,
|
||||
'$server_role' => $advanced,
|
||||
'$timezone' => $timezone,
|
||||
'$siteurl' => $siteurl,
|
||||
'$site_id' => random_string(),
|
||||
'$phpath' => $phpath,
|
||||
'$adminmail' => $adminmail
|
||||
));
|
||||
|
||||
@@ -493,7 +493,6 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
$this->check_add($ck_funcs, t('OpenSSL PHP module'), true, true);
|
||||
$this->check_add($ck_funcs, t('mysqli or postgres PHP module'), true, true);
|
||||
$this->check_add($ck_funcs, t('mb_string PHP module'), true, true);
|
||||
$this->check_add($ck_funcs, t('mcrypt PHP module'), true, true);
|
||||
$this->check_add($ck_funcs, t('xml PHP module'), true, true);
|
||||
|
||||
if(function_exists('apache_get_modules')){
|
||||
@@ -530,10 +529,6 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
$ck_funcs[4]['status'] = false;
|
||||
$ck_funcs[4]['help'] = t('Error: mb_string PHP module required but not installed.');
|
||||
}
|
||||
if(! function_exists('mcrypt_encrypt')) {
|
||||
$ck_funcs[5]['status'] = false;
|
||||
$ck_funcs[5]['help'] = t('Error: mcrypt PHP module required but not installed.');
|
||||
}
|
||||
if(! extension_loaded('xml')) {
|
||||
$ck_funcs[6]['status'] = false;
|
||||
$ck_funcs[6]['help'] = t('Error: xml PHP module required for DAV but not installed.');
|
||||
@@ -596,7 +591,7 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
|
||||
if(! is_writable('store')) {
|
||||
$status = false;
|
||||
$help = t('Red uses the store directory to save uploaded files. The web server needs to have write access to the store directory under the Red top level folder') . EOL;
|
||||
$help = t('This software uses the store directory to save uploaded files. The web server needs to have write access to the store directory under the Red top level folder') . EOL;
|
||||
$help .= t('Please ensure that the user that your web server runs as (e.g. www-data) has write access to this folder.').EOL;
|
||||
}
|
||||
|
||||
@@ -639,6 +634,9 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
$help .= t('If your certificate is not recognized, members of other sites (who may themselves have valid certificates) will get a warning message on their own site complaining about security issues.') . EOL;
|
||||
$help .= t('This can cause usability issues elsewhere (not just on your own site) so we must insist on this requirement.') .EOL;
|
||||
$help .= t('Providers are available that issue free certificates which are browser-valid.'). EOL;
|
||||
|
||||
$help .= t('If you are confident that the certificate is valid and signed by a trusted authority, check to see if you have failed to install an intermediate cert. These are not normally required by browsers, but are required for server-to-server communications.') . EOL;
|
||||
|
||||
|
||||
$this->check_add($checks, t('SSL certificate validation'), false, true, $help);
|
||||
}
|
||||
@@ -695,6 +693,7 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
// install the standard theme
|
||||
set_config('system', 'allowed_themes', 'redbasic');
|
||||
|
||||
|
||||
// Set a lenient list of ciphers if using openssl. Other ssl engines
|
||||
// (e.g. NSS used in RedHat) require different syntax, so hopefully
|
||||
// the default curl cipher list will work for most sites. If not,
|
||||
@@ -704,7 +703,9 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
// z_fetch_url() is also used to import shared links and other content
|
||||
// so in theory most any cipher could show up and we should do our best
|
||||
// to make the content available rather than tell folks that there's a
|
||||
// weird SSL error which they can't do anything about.
|
||||
// weird SSL error which they can't do anything about. This does not affect
|
||||
// the SSL server, but is only a client negotiation to find something workable.
|
||||
// Hence it will not make your system susceptible to POODL or other nasties.
|
||||
|
||||
$x = curl_version();
|
||||
if(stristr($x['ssl_version'],'openssl'))
|
||||
|
||||
@@ -27,28 +27,11 @@ class Siteinfo extends \Zotlabs\Web\Controller {
|
||||
else {
|
||||
$version = $commit = '';
|
||||
}
|
||||
$visible_plugins = array();
|
||||
if(is_array(\App::$plugins) && count(\App::$plugins)) {
|
||||
$r = q("select * from addon where hidden = 0");
|
||||
if(count($r))
|
||||
foreach($r as $rr)
|
||||
$visible_plugins[] = $rr['name'];
|
||||
}
|
||||
|
||||
$plugins_list = '';
|
||||
if(count($visible_plugins)) {
|
||||
$plugins_text = t('Installed plugins/addons/apps:');
|
||||
$sorted = $visible_plugins;
|
||||
$s = '';
|
||||
sort($sorted);
|
||||
foreach($sorted as $p) {
|
||||
if(strlen($p)) {
|
||||
if(strlen($s)) $s .= ', ';
|
||||
$s .= $p;
|
||||
}
|
||||
}
|
||||
$plugins_list .= $s;
|
||||
}
|
||||
|
||||
$plugins_list = implode(', ',visible_plugin_list());
|
||||
|
||||
if($plugins_list)
|
||||
$plugins_text = t('Installed plugins/addons/apps:');
|
||||
else
|
||||
$plugins_text = t('No installed plugins/addons/apps');
|
||||
|
||||
|
||||
@@ -30,7 +30,20 @@ class Starred extends \Zotlabs\Web\Controller {
|
||||
intval(local_channel()),
|
||||
intval($message_id)
|
||||
);
|
||||
|
||||
|
||||
$r = q("select * from item where id = %d",
|
||||
intval($message_id)
|
||||
);
|
||||
if($r) {
|
||||
xchan_query($r);
|
||||
$sync_item = fetch_post_tags($r);
|
||||
build_sync_packet(local_channel(),[
|
||||
'item' => [
|
||||
encode_item($sync_item[0],true)
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
header('Content-type: application/json');
|
||||
echo json_encode(array('result' => $item_starred));
|
||||
killme();
|
||||
|
||||
@@ -129,9 +129,14 @@ class Tagger extends \Zotlabs\Web\Controller {
|
||||
|
||||
store_item_tag($item['uid'],$item['id'],TERM_OBJ_POST,TERM_COMMUNITYTAG,$term,$tagid);
|
||||
$ret = post_activity_item($arr);
|
||||
|
||||
if($ret['success'])
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier','tag',$ret['activity']['id']));
|
||||
|
||||
if($ret['success']) {
|
||||
build_sync_packet(local_channel(),
|
||||
[
|
||||
'item' => [ encode_item($ret['activity'],true) ]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
killme();
|
||||
|
||||
|
||||
@@ -312,6 +312,10 @@ class Thing extends \Zotlabs\Web\Controller {
|
||||
'$imgurl' => $r[0]['obj_imgurl'],
|
||||
'$permissions' => t('Permissions'),
|
||||
'$aclselect' => populate_acl($channel_acl,false),
|
||||
'$allow_cid' => acl2json($channel_acl['allow_cid']),
|
||||
'$allow_gid' => acl2json($channel_acl['allow_gid']),
|
||||
'$deny_cid' => acl2json($channel_acl['deny_cid']),
|
||||
'$deny_gid' => acl2json($channel_acl['deny_gid']),
|
||||
'$lockstate' => $lockstate,
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
@@ -358,6 +362,10 @@ class Thing extends \Zotlabs\Web\Controller {
|
||||
'$img_lbl' => t('URL for photo of thing (optional)'),
|
||||
'$permissions' => t('Permissions'),
|
||||
'$aclselect' => populate_acl($channel_acl,false),
|
||||
'$allow_cid' => acl2json($channel_acl['allow_cid']),
|
||||
'$allow_gid' => acl2json($channel_acl['allow_gid']),
|
||||
'$deny_cid' => acl2json($channel_acl['deny_cid']),
|
||||
'$deny_gid' => acl2json($channel_acl['deny_gid']),
|
||||
'$lockstate' => $lockstate,
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
|
||||
@@ -44,7 +44,7 @@ class Uexport extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
function get() {
|
||||
function get() {
|
||||
|
||||
$y = datetime_convert('UTC',date_default_timezone_get(),'now','Y');
|
||||
|
||||
|
||||
@@ -10,8 +10,11 @@ class Viewconnections extends \Zotlabs\Web\Controller {
|
||||
if(observer_prohibited()) {
|
||||
return;
|
||||
}
|
||||
if(argc() > 1)
|
||||
profile_load($a,argv(1));
|
||||
|
||||
if(argc() > 1) {
|
||||
profile_load(argv(1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function get() {
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace Zotlabs\Module;
|
||||
require_once('include/channel.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/PermissionDescription.php');
|
||||
|
||||
|
||||
class Webpages extends \Zotlabs\Web\Controller {
|
||||
@@ -23,12 +22,12 @@ class Webpages extends \Zotlabs\Web\Controller {
|
||||
else
|
||||
return;
|
||||
|
||||
profile_load($a,$which);
|
||||
profile_load($which);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function get() {
|
||||
function get() {
|
||||
|
||||
if(! \App::$profile) {
|
||||
notice( t('Requested profile is not available.') . EOL );
|
||||
@@ -46,7 +45,29 @@ class Webpages extends \Zotlabs\Web\Controller {
|
||||
$observer = \App::get_observer();
|
||||
|
||||
$channel = \App::get_channel();
|
||||
|
||||
|
||||
switch ($_SESSION['action']) {
|
||||
case 'import':
|
||||
$_SESSION['action'] = null;
|
||||
$o .= replace_macros(get_markup_template('webpage_import.tpl'), array(
|
||||
'$title' => t('Import Webpage Elements'),
|
||||
'$importbtn' => t('Import selected'),
|
||||
'$action' => 'import',
|
||||
'$pages' => $_SESSION['pages'],
|
||||
'$layouts' => $_SESSION['layouts'],
|
||||
'$blocks' => $_SESSION['blocks'],
|
||||
));
|
||||
return $o;
|
||||
|
||||
case 'importselected':
|
||||
$_SESSION['action'] = null;
|
||||
break;
|
||||
default :
|
||||
$_SESSION['action'] = null;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(\App::$is_sys && is_site_admin()) {
|
||||
$sys = get_sys_channel();
|
||||
if($sys && intval($sys['channel_id'])) {
|
||||
@@ -105,7 +126,8 @@ class Webpages extends \Zotlabs\Web\Controller {
|
||||
'is_owner' => true,
|
||||
'nickname' => \App::$profile['channel_address'],
|
||||
'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
|
||||
'acl' => (($is_owner) ? populate_acl($channel_acl,false, \PermissionDescription::fromGlobalPermission('view_pages')) : ''),
|
||||
'acl' => (($is_owner) ? populate_acl($channel_acl,false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')) : ''),
|
||||
'permissions' => (($is_owner) ? $channel_acl : ''),
|
||||
'showacl' => (($is_owner) ? true : false),
|
||||
'visitor' => true,
|
||||
'hide_location' => true,
|
||||
@@ -138,11 +160,19 @@ class Webpages extends \Zotlabs\Web\Controller {
|
||||
|
||||
$sql_extra = item_permissions_sql($owner);
|
||||
|
||||
$r = q("select * from item_id left join item on item_id.iid = item.id
|
||||
where item_id.uid = %d and service = 'WEBPAGE' and item_type = %d $sql_extra order by item.created desc",
|
||||
|
||||
$r = q("select * from iconfig left join item on iconfig.iid = item.id
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'WEBPAGE' and item_type = %d
|
||||
$sql_extra order by item.created desc",
|
||||
intval($owner),
|
||||
intval(ITEM_TYPE_WEBPAGE)
|
||||
);
|
||||
|
||||
// $r = q("select * from item_id left join item on item_id.iid = item.id
|
||||
// where item_id.uid = %d and service = 'WEBPAGE' and item_type = %d $sql_extra order by item.created desc",
|
||||
// intval($owner),
|
||||
// intval(ITEM_TYPE_WEBPAGE)
|
||||
// );
|
||||
|
||||
$pages = null;
|
||||
|
||||
@@ -160,13 +190,13 @@ class Webpages extends \Zotlabs\Web\Controller {
|
||||
'created' => $rr['created'],
|
||||
'edited' => $rr['edited'],
|
||||
'mimetype' => $rr['mimetype'],
|
||||
'pagetitle' => $rr['sid'],
|
||||
'pagetitle' => $rr['v'],
|
||||
'mid' => $rr['mid'],
|
||||
'layout_mid' => $rr['layout_mid']
|
||||
);
|
||||
$pages[$rr['iid']][] = array(
|
||||
'url' => $rr['iid'],
|
||||
'pagetitle' => $rr['sid'],
|
||||
'pagetitle' => $rr['v'],
|
||||
'title' => $rr['title'],
|
||||
'created' => datetime_convert('UTC',date_default_timezone_get(),$rr['created']),
|
||||
'edited' => datetime_convert('UTC',date_default_timezone_get(),$rr['edited']),
|
||||
@@ -202,4 +232,165 @@ class Webpages extends \Zotlabs\Web\Controller {
|
||||
return $o;
|
||||
}
|
||||
|
||||
function post() {
|
||||
|
||||
$action = $_REQUEST['action'];
|
||||
if( $action ){
|
||||
switch ($action) {
|
||||
case 'scan':
|
||||
|
||||
// the state of this variable tracks whether website files have been scanned (null, true, false)
|
||||
$cloud = null;
|
||||
|
||||
// Website files are to be imported from an uploaded zip file
|
||||
if(($_FILES) && array_key_exists('zip_file',$_FILES) && isset($_POST['w_upload'])) {
|
||||
$source = $_FILES["zip_file"]["tmp_name"];
|
||||
$type = $_FILES["zip_file"]["type"];
|
||||
$okay = false;
|
||||
$accepted_types = array('application/zip', 'application/x-zip-compressed', 'multipart/x-zip', 'application/x-compressed');
|
||||
foreach ($accepted_types as $mime_type) {
|
||||
if ($mime_type == $type) {
|
||||
$okay = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!$okay) {
|
||||
notice( t('Invalid file type.') . EOL);
|
||||
return;
|
||||
}
|
||||
$zip = new \ZipArchive();
|
||||
if ($zip->open($source) === true) {
|
||||
$tmp_folder_name = random_string(5);
|
||||
$website = dirname($source) . '/' . $tmp_folder_name;
|
||||
$zip->extractTo($website); // change this to the correct site path
|
||||
$zip->close();
|
||||
@unlink($source); // delete the compressed file now that the content has been extracted
|
||||
$cloud = false;
|
||||
} else {
|
||||
notice( t('Error opening zip file') . EOL);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Website files are to be imported from the channel cloud files
|
||||
if (($_POST) && array_key_exists('path',$_POST) && isset($_POST['cloudsubmit'])) {
|
||||
|
||||
$channel = \App::get_channel();
|
||||
$dirpath = get_dirpath_by_cloudpath($channel, $_POST['path']);
|
||||
if(!$dirpath) {
|
||||
notice( t('Invalid folder path.') . EOL);
|
||||
return null;
|
||||
}
|
||||
$cloud = true;
|
||||
|
||||
}
|
||||
|
||||
// If the website files were uploaded or specified in the cloud files, then $cloud
|
||||
// should be either true or false
|
||||
if ($cloud !== null) {
|
||||
require_once('include/import.php');
|
||||
$elements = [];
|
||||
if($cloud) {
|
||||
$path = $_POST['path'];
|
||||
} else {
|
||||
$path = $website;
|
||||
}
|
||||
$elements['pages'] = scan_webpage_elements($path, 'page', $cloud);
|
||||
$elements['layouts'] = scan_webpage_elements($path, 'layout', $cloud);
|
||||
$elements['blocks'] = scan_webpage_elements($path, 'block', $cloud);
|
||||
$_SESSION['blocks'] = $elements['blocks'];
|
||||
$_SESSION['layouts'] = $elements['layouts'];
|
||||
$_SESSION['pages'] = $elements['pages'];
|
||||
if(!(empty($elements['pages']) && empty($elements['blocks']) && empty($elements['layouts']))) {
|
||||
//info( t('Webpages elements detected.') . EOL);
|
||||
$_SESSION['action'] = 'import';
|
||||
} else {
|
||||
notice( t('No webpage elements detected.') . EOL);
|
||||
$_SESSION['action'] = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If the website elements were imported from a zip file, delete the temporary decompressed files
|
||||
if ($cloud === false && $website && $elements) {
|
||||
rrmdir($website); // Delete the temporary decompressed files
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'importselected':
|
||||
require_once('include/import.php');
|
||||
$channel = \App::get_channel();
|
||||
|
||||
// Import layout first so that pages that reference new layouts will find
|
||||
// the mid of layout items in the database
|
||||
|
||||
// Obtain the user-selected layouts to import and import them
|
||||
$checkedlayouts = $_POST['layout'];
|
||||
$layouts = [];
|
||||
if (!empty($checkedlayouts)) {
|
||||
foreach ($checkedlayouts as $name) {
|
||||
foreach ($_SESSION['layouts'] as &$layout) {
|
||||
if ($layout['name'] === $name) {
|
||||
$layout['import'] = 1;
|
||||
$layoutstoimport[] = $layout;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($layoutstoimport as $elementtoimport) {
|
||||
$layouts[] = import_webpage_element($elementtoimport, $channel, 'layout');
|
||||
}
|
||||
}
|
||||
$_SESSION['import_layouts'] = $layouts;
|
||||
|
||||
// Obtain the user-selected blocks to import and import them
|
||||
$checkedblocks = $_POST['block'];
|
||||
$blocks = [];
|
||||
if (!empty($checkedblocks)) {
|
||||
foreach ($checkedblocks as $name) {
|
||||
foreach ($_SESSION['blocks'] as &$block) {
|
||||
if ($block['name'] === $name) {
|
||||
$block['import'] = 1;
|
||||
$blockstoimport[] = $block;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($blockstoimport as $elementtoimport) {
|
||||
$blocks[] = import_webpage_element($elementtoimport, $channel, 'block');
|
||||
}
|
||||
}
|
||||
$_SESSION['import_blocks'] = $blocks;
|
||||
|
||||
// Obtain the user-selected pages to import and import them
|
||||
$checkedpages = $_POST['page'];
|
||||
$pages = [];
|
||||
if (!empty($checkedpages)) {
|
||||
foreach ($checkedpages as $pagelink) {
|
||||
foreach ($_SESSION['pages'] as &$page) {
|
||||
if ($page['pagelink'] === $pagelink) {
|
||||
$page['import'] = 1;
|
||||
$pagestoimport[] = $page;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($pagestoimport as $elementtoimport) {
|
||||
$pages[] = import_webpage_element($elementtoimport, $channel, 'page');
|
||||
}
|
||||
}
|
||||
$_SESSION['import_pages'] = $pages;
|
||||
if(!(empty($_SESSION['import_pages']) && empty($_SESSION['import_blocks']) && empty($_SESSION['import_layouts']))) {
|
||||
info( t('Import complete.') . EOL);
|
||||
}
|
||||
break;
|
||||
|
||||
default :
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Module;/** @file */
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
class Wiki extends \Zotlabs\Web\Controller {
|
||||
|
||||
@@ -20,11 +20,28 @@ class Wiki extends \Zotlabs\Web\Controller {
|
||||
notice(t('You must be logged in to see this page.') . EOL);
|
||||
goaway('/login');
|
||||
}
|
||||
profile_load($nick);
|
||||
|
||||
}
|
||||
|
||||
function get() {
|
||||
|
||||
if(observer_prohibited(true)) {
|
||||
return login();
|
||||
}
|
||||
|
||||
if(! feature_enabled(\App::$profile_uid,'wiki')) {
|
||||
notice( t('Not found') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$tab = 'wiki';
|
||||
|
||||
|
||||
require_once('include/wiki.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/conversation.php');
|
||||
|
||||
// TODO: Combine the interface configuration into a unified object
|
||||
// Something like $interface = array('new_page_button' => false, 'new_wiki_button' => false, ...)
|
||||
$wiki_owner = false;
|
||||
@@ -57,11 +74,16 @@ class Wiki extends \Zotlabs\Web\Controller {
|
||||
// Initialize the ACL to the channel default permissions
|
||||
$x = array(
|
||||
'lockstate' => (( $local_observer['channel_allow_cid'] ||
|
||||
$local_observer['channel_allow_gid'] ||
|
||||
$local_observer['channel_deny_cid'] ||
|
||||
$local_observer['channel_deny_gid'])
|
||||
? 'lock' : 'unlock'),
|
||||
$local_observer['channel_allow_gid'] ||
|
||||
$local_observer['channel_deny_cid'] ||
|
||||
$local_observer['channel_deny_gid'])
|
||||
? 'lock' : 'unlock'
|
||||
),
|
||||
'acl' => populate_acl($channel_acl),
|
||||
'allow_cid' => acl2json($channel_acl['allow_cid']),
|
||||
'allow_gid' => acl2json($channel_acl['allow_gid']),
|
||||
'deny_cid' => acl2json($channel_acl['deny_cid']),
|
||||
'deny_gid' => acl2json($channel_acl['deny_gid']),
|
||||
'bang' => ''
|
||||
);
|
||||
} else {
|
||||
@@ -72,8 +94,11 @@ class Wiki extends \Zotlabs\Web\Controller {
|
||||
switch (argc()) {
|
||||
case 2:
|
||||
// Configure page template
|
||||
$wikiheader = t('Wiki Sandbox');
|
||||
$content = '"# Wiki Sandbox\n\nContent you **edit** and **preview** here *will not be saved*."';
|
||||
$wikiheaderName = t('Wiki');
|
||||
$wikiheaderPage = t('Sandbox');
|
||||
require_once('library/markdown.php');
|
||||
$content = t('"# Wiki Sandbox\n\nContent you **edit** and **preview** here *will not be saved*."');
|
||||
$renderedContent = Markdown(json_decode($content));
|
||||
$hide_editor = false;
|
||||
$showPageControls = false;
|
||||
$showNewWikiButton = $wiki_owner;
|
||||
@@ -113,13 +138,18 @@ class Wiki extends \Zotlabs\Web\Controller {
|
||||
} else {
|
||||
$wiki_editor = true;
|
||||
}
|
||||
$wikiheader = urldecode($wikiUrlName) . ': ' . urldecode($pageUrlName); // show wiki name and page
|
||||
$wikiheaderName = urldecode($wikiUrlName);
|
||||
$wikiheaderPage = urldecode($pageUrlName);
|
||||
$p = wiki_get_page_content(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
|
||||
if(!$p['success']) {
|
||||
notice('Error retrieving page content' . EOL);
|
||||
goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName);
|
||||
}
|
||||
$content = ($p['content'] !== '' ? $p['content'] : '"# New page\n"');
|
||||
$content = ($p['content'] !== '' ? htmlspecialchars_decode($p['content'],ENT_COMPAT) : '"# New page\n"');
|
||||
// Render the Markdown-formatted page content in HTML
|
||||
require_once('library/markdown.php');
|
||||
$html = wiki_generate_toc(purify_html(Markdown(wiki_bbcode(json_decode($content)))));
|
||||
$renderedContent = wiki_convert_links($html,argv(0).'/'.argv(1).'/'.$wikiUrlName);
|
||||
$hide_editor = false;
|
||||
$showPageControls = $wiki_editor;
|
||||
$showNewWikiButton = $wiki_owner;
|
||||
@@ -131,11 +161,25 @@ class Wiki extends \Zotlabs\Web\Controller {
|
||||
default: // Strip the extraneous URL components
|
||||
goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName.'/'.$pageUrlName);
|
||||
}
|
||||
// Render the Markdown-formatted page content in HTML
|
||||
require_once('library/markdown.php');
|
||||
|
||||
$wikiModalID = random_string(3);
|
||||
$wikiModal = replace_macros(
|
||||
get_markup_template('generic_modal.tpl'), array(
|
||||
'$id' => $wikiModalID,
|
||||
'$title' => t('Revision Comparison'),
|
||||
'$ok' => t('Revert'),
|
||||
'$cancel' => t('Cancel')
|
||||
)
|
||||
);
|
||||
|
||||
$is_owner = ((local_channel()) && (local_channel() == \App::$profile['profile_uid']) ? true : false);
|
||||
|
||||
$o .= profile_tabs($a, $is_owner, \App::$profile['channel_address']);
|
||||
|
||||
|
||||
$o .= replace_macros(get_markup_template('wiki.tpl'),array(
|
||||
'$wikiheader' => $wikiheader,
|
||||
'$wikiheaderName' => $wikiheaderName,
|
||||
'$wikiheaderPage' => $wikiheaderPage,
|
||||
'$hideEditor' => $hide_editor,
|
||||
'$showPageControls' => $showPageControls,
|
||||
'$showNewWikiButton'=> $showNewWikiButton,
|
||||
@@ -147,13 +191,31 @@ class Wiki extends \Zotlabs\Web\Controller {
|
||||
'$page' => $pageUrlName,
|
||||
'$lockstate' => $x['lockstate'],
|
||||
'$acl' => $x['acl'],
|
||||
'$allow_cid' => $x['allow_cid'],
|
||||
'$allow_gid' => $x['allow_gid'],
|
||||
'$deny_cid' => $x['deny_cid'],
|
||||
'$deny_gid' => $x['deny_gid'],
|
||||
'$bang' => $x['bang'],
|
||||
'$content' => $content,
|
||||
'$renderedContent' => Markdown(json_decode($content)),
|
||||
'$renderedContent' => $renderedContent,
|
||||
'$wikiName' => array('wikiName', t('Enter the name of your new wiki:'), '', ''),
|
||||
'$pageName' => array('pageName', t('Enter the name of the new page:'), '', ''),
|
||||
'$pageRename' => array('pageRename', t('Enter the new name:'), '', ''),
|
||||
'$commitMsg' => array('commitMsg', '', '', '', '', 'placeholder="(optional) Enter a custom message when saving the page..."'),
|
||||
'$pageHistory' => $pageHistory['history']
|
||||
'$pageHistory' => $pageHistory['history'],
|
||||
'$wikiModal' => $wikiModal,
|
||||
'$wikiModalID' => $wikiModalID,
|
||||
'$commit' => 'HEAD',
|
||||
'$embedPhotos' => t('Embed image from photo albums'),
|
||||
'$embedPhotosModalTitle' => t('Embed an image from your albums'),
|
||||
'$embedPhotosModalCancel' => t('Cancel'),
|
||||
'$embedPhotosModalOK' => t('OK'),
|
||||
'$modalchooseimages' => t('Choose images to embed'),
|
||||
'$modalchoosealbum' => t('Choose an album'),
|
||||
'$modaldiffalbum' => t('Choose a different album...'),
|
||||
'$modalerrorlist' => t('Error getting album list'),
|
||||
'$modalerrorlink' => t('Error getting photo link'),
|
||||
'$modalerroralbum' => t('Error getting album'),
|
||||
));
|
||||
head_add_js('library/ace/ace.js'); // Ace Code Editor
|
||||
return $o;
|
||||
@@ -166,8 +228,13 @@ class Wiki extends \Zotlabs\Web\Controller {
|
||||
// Render mardown-formatted text in HTML for preview
|
||||
if((argc() > 2) && (argv(2) === 'preview')) {
|
||||
$content = $_POST['content'];
|
||||
$resource_id = $_POST['resource_id'];
|
||||
require_once('library/markdown.php');
|
||||
$html = purify_html(Markdown($content));
|
||||
$content = wiki_bbcode($content);
|
||||
$html = wiki_generate_toc(purify_html(Markdown($content)));
|
||||
$w = wiki_get_wiki($resource_id);
|
||||
$wikiURL = argv(0).'/'.argv(1).'/'.$w['urlName'];
|
||||
$html = wiki_convert_links($html,$wikiURL);
|
||||
json_return_and_die(array('html' => $html, 'success' => true));
|
||||
}
|
||||
|
||||
@@ -185,6 +252,7 @@ class Wiki extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
$wiki = array();
|
||||
// Generate new wiki info from input name
|
||||
$wiki['postVisible'] = ((intval($_POST['postVisible']) === 0) ? 0 : 1);
|
||||
$wiki['rawName'] = $_POST['wikiName'];
|
||||
$wiki['htmlName'] = escape_tags($_POST['wikiName']);
|
||||
$wiki['urlName'] = urlencode($_POST['wikiName']);
|
||||
@@ -218,20 +286,7 @@ class Wiki extends \Zotlabs\Web\Controller {
|
||||
if (local_channel() !== intval($channel['channel_id'])) {
|
||||
logger('Wiki delete permission denied.' . EOL);
|
||||
json_return_and_die(array('message' => 'Wiki delete permission denied.', 'success' => false));
|
||||
} else {
|
||||
/*
|
||||
$channel = get_channel_by_nick($nick);
|
||||
$observer_hash = get_observer_hash();
|
||||
// Figure out who the page owner is.
|
||||
$perms = get_all_perms(intval($channel['channel_id']), $observer_hash);
|
||||
// TODO: Create a new permission setting for wiki analogous to webpages. Until
|
||||
// then, use webpage permissions
|
||||
if (!$perms['write_pages']) {
|
||||
logger('Wiki delete permission denied.' . EOL);
|
||||
json_return_and_die(array('success' => false));
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
$resource_id = $_POST['resource_id'];
|
||||
$deleted = wiki_delete_wiki($resource_id);
|
||||
if ($deleted['success']) {
|
||||
@@ -377,7 +432,7 @@ class Wiki extends \Zotlabs\Web\Controller {
|
||||
if($deleted['success']) {
|
||||
$ob = \App::get_observer();
|
||||
$commit = wiki_git_commit(array(
|
||||
'commit_msg' => 'Deleted ' . $pageHtmlName,
|
||||
'commit_msg' => 'Deleted ' . $pageUrlName,
|
||||
'resource_id' => $resource_id,
|
||||
'observer' => $ob,
|
||||
'files' => null
|
||||
@@ -408,7 +463,7 @@ class Wiki extends \Zotlabs\Web\Controller {
|
||||
json_return_and_die(array('success' => false));
|
||||
}
|
||||
}
|
||||
$reverted = wiki_revert_page(array('commitHash' => $commitHash, 'observer' => \App::get_observer(), 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
|
||||
$reverted = wiki_revert_page(array('commitHash' => $commitHash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
|
||||
if($reverted['success']) {
|
||||
json_return_and_die(array('content' => $reverted['content'], 'message' => '', 'success' => true));
|
||||
} else {
|
||||
@@ -416,6 +471,73 @@ class Wiki extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
// Compare page revisions
|
||||
if ((argc() === 4) && (argv(2) === 'compare') && (argv(3) === 'page')) {
|
||||
$resource_id = $_POST['resource_id'];
|
||||
$pageUrlName = $_POST['name'];
|
||||
$compareCommit = $_POST['compareCommit'];
|
||||
$currentCommit = $_POST['currentCommit'];
|
||||
// Determine if observer has permission to revert pages
|
||||
$nick = argv(1);
|
||||
$channel = get_channel_by_nick($nick);
|
||||
if (local_channel() !== intval($channel['channel_id'])) {
|
||||
$observer_hash = get_observer_hash();
|
||||
$perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
|
||||
if(!$perms['read']) {
|
||||
logger('Wiki read permission denied.' . EOL);
|
||||
json_return_and_die(array('success' => false));
|
||||
}
|
||||
}
|
||||
$compare = wiki_compare_page(array('currentCommit' => $currentCommit, 'compareCommit' => $compareCommit, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
|
||||
if($compare['success']) {
|
||||
$diffHTML = '<table class="text-center" width="100%"><tr><td class="lead" width="50%">Current Revision</td><td class="lead" width="50%">Selected Revision</td></tr></table>' . $compare['diff'];
|
||||
json_return_and_die(array('diff' => $diffHTML, 'message' => '', 'success' => true));
|
||||
} else {
|
||||
json_return_and_die(array('diff' => '', 'message' => 'Error comparing page', 'success' => false));
|
||||
}
|
||||
}
|
||||
|
||||
// Rename a page
|
||||
if ((argc() === 4) && (argv(2) === 'rename') && (argv(3) === 'page')) {
|
||||
$resource_id = $_POST['resource_id'];
|
||||
$pageUrlName = $_POST['oldName'];
|
||||
$pageNewName = $_POST['newName'];
|
||||
if ($pageUrlName === 'Home') {
|
||||
json_return_and_die(array('message' => 'Cannot rename Home','success' => false));
|
||||
}
|
||||
if(urlencode(escape_tags($pageNewName)) === '') {
|
||||
json_return_and_die(array('message' => 'Error renaming page. Invalid name.', 'success' => false));
|
||||
}
|
||||
// Determine if observer has permission to rename pages
|
||||
$nick = argv(1);
|
||||
$channel = get_channel_by_nick($nick);
|
||||
if (local_channel() !== intval($channel['channel_id'])) {
|
||||
$observer_hash = get_observer_hash();
|
||||
$perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
|
||||
if(!$perms['write']) {
|
||||
logger('Wiki write permission denied. ' . EOL);
|
||||
json_return_and_die(array('success' => false));
|
||||
}
|
||||
}
|
||||
$renamed = wiki_rename_page(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'pageNewName' => $pageNewName));
|
||||
if($renamed['success']) {
|
||||
$ob = \App::get_observer();
|
||||
$commit = wiki_git_commit(array(
|
||||
'commit_msg' => 'Renamed ' . urldecode($pageUrlName) . ' to ' . $renamed['page']['htmlName'],
|
||||
'resource_id' => $resource_id,
|
||||
'observer' => $ob,
|
||||
'files' => array($pageUrlName . '.md', $renamed['page']['fileName']),
|
||||
'all' => true
|
||||
));
|
||||
if($commit['success']) {
|
||||
json_return_and_die(array('name' => $renamed['page'], 'message' => 'Wiki git repo commit made', 'success' => true));
|
||||
} else {
|
||||
json_return_and_die(array('message' => 'Error making git commit','success' => false));
|
||||
}
|
||||
} else {
|
||||
json_return_and_die(array('message' => 'Error renaming page', 'success' => false));
|
||||
}
|
||||
}
|
||||
|
||||
//notice('You must be authenticated.');
|
||||
json_return_and_die(array('message' => 'You must be authenticated.', 'success' => false));
|
||||
|
||||
@@ -179,7 +179,8 @@ class Comanche {
|
||||
$channel_id = $this->get_channel_id();
|
||||
|
||||
if($channel_id) {
|
||||
$r = q("select * from item inner join item_id on iid = item.id and item_id.uid = item.uid and item.uid = %d and service = 'BUILDBLOCK' and sid = '%s' limit 1",
|
||||
$r = q("select * from item inner join iconfig on iconfig.iid = item.id and item.uid = %d
|
||||
and iconfig.cat = 'system' and iconfig.k = 'BUILDBLOCK' and iconfig.v = '%s' limit 1",
|
||||
intval($channel_id),
|
||||
dbesc($name)
|
||||
);
|
||||
@@ -282,12 +283,12 @@ class Comanche {
|
||||
|
||||
|
||||
/**
|
||||
* Widgets will have to get any operational arguments from the session, the
|
||||
* global app environment, or config storage until we implement argument passing
|
||||
* Render a widget
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $text
|
||||
*/
|
||||
|
||||
function widget($name, $text) {
|
||||
$vars = array();
|
||||
$matches = array();
|
||||
@@ -314,7 +315,7 @@ class Comanche {
|
||||
require_once(theme_include($theme_widget));
|
||||
}
|
||||
|
||||
if (function_exists($func))
|
||||
if(function_exists($func))
|
||||
return $func($vars);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
namespace Zotlabs\Storage;
|
||||
|
||||
use Sabre\DAV;
|
||||
use Sabre\HTTP\RequestInterface;
|
||||
use Sabre\HTTP\ResponseInterface;
|
||||
|
||||
/**
|
||||
* @brief Authentication backend class for DAV.
|
||||
@@ -89,33 +91,20 @@ class BasicAuth extends DAV\Auth\Backend\AbstractBasic {
|
||||
|
||||
require_once('include/auth.php');
|
||||
$record = account_verify_password($username, $password);
|
||||
if ($record && $record['account_default_channel']) {
|
||||
$r = q("SELECT * FROM channel WHERE channel_account_id = %d AND channel_id = %d LIMIT 1",
|
||||
intval($record['account_id']),
|
||||
intval($record['account_default_channel'])
|
||||
);
|
||||
if($r && $this->check_module_access($r[0]['channel_id'])) {
|
||||
return $this->setAuthenticated($r[0]);
|
||||
if($record && $record['account']) {
|
||||
if($record['channel'])
|
||||
$channel = $record['channel'];
|
||||
else {
|
||||
$r = q("SELECT * FROM channel WHERE channel_account_id = %d AND channel_id = %d LIMIT 1",
|
||||
intval($record['account']['account_id']),
|
||||
intval($record['account']['account_default_channel'])
|
||||
);
|
||||
if($r)
|
||||
$channel = $r[0];
|
||||
}
|
||||
}
|
||||
$r = q("SELECT * FROM channel WHERE channel_address = '%s' LIMIT 1",
|
||||
dbesc($username)
|
||||
);
|
||||
if ($r) {
|
||||
$x = q("SELECT account_flags, account_salt, account_password FROM account WHERE account_id = %d LIMIT 1",
|
||||
intval($r[0]['channel_account_id'])
|
||||
);
|
||||
if ($x) {
|
||||
// @fixme this foreach should not be needed?
|
||||
foreach ($x as $record) {
|
||||
if ((($record['account_flags'] == ACCOUNT_OK) || ($record['account_flags'] == ACCOUNT_UNVERIFIED))
|
||||
&& (hash('whirlpool', $record['account_salt'] . $password) === $record['account_password'])) {
|
||||
logger('password verified for ' . $username);
|
||||
if($this->check_module_access($r[0]['channel_id']))
|
||||
return $this->setAuthenticated($r[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if($channel && $this->check_module_access($channel['channel_id'])) {
|
||||
return $this->setAuthenticated($channel);
|
||||
}
|
||||
|
||||
if($this->module_disabled)
|
||||
@@ -145,6 +134,58 @@ class BasicAuth extends DAV\Auth\Backend\AbstractBasic {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* When this method is called, the backend must check if authentication was
|
||||
* successful.
|
||||
*
|
||||
* The returned value must be one of the following
|
||||
*
|
||||
* [true, "principals/username"]
|
||||
* [false, "reason for failure"]
|
||||
*
|
||||
* If authentication was successful, it's expected that the authentication
|
||||
* backend returns a so-called principal url.
|
||||
*
|
||||
* Examples of a principal url:
|
||||
*
|
||||
* principals/admin
|
||||
* principals/user1
|
||||
* principals/users/joe
|
||||
* principals/uid/123457
|
||||
*
|
||||
* If you don't use WebDAV ACL (RFC3744) we recommend that you simply
|
||||
* return a string such as:
|
||||
*
|
||||
* principals/users/[username]
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return array
|
||||
*/
|
||||
function check(RequestInterface $request, ResponseInterface $response) {
|
||||
|
||||
if(local_channel()) {
|
||||
$this->setAuthenticated(\App::get_channel());
|
||||
return [ true, $this->principalPrefix . $this->channel_name ];
|
||||
}
|
||||
|
||||
$auth = new \Sabre\HTTP\Auth\Basic(
|
||||
$this->realm,
|
||||
$request,
|
||||
$response
|
||||
);
|
||||
|
||||
$userpass = $auth->getCredentials();
|
||||
if (!$userpass) {
|
||||
return [false, "No 'Authorization: Basic' header found. Either the client didn't send one, or the server is misconfigured"];
|
||||
}
|
||||
if (!$this->validateUserPass($userpass[0], $userpass[1])) {
|
||||
return [false, "Username or password was incorrect"];
|
||||
}
|
||||
return [true, $this->principalPrefix . $userpass[0]];
|
||||
|
||||
}
|
||||
|
||||
protected function check_module_access($channel_id) {
|
||||
if($channel_id && \App::$module === 'cdav') {
|
||||
$x = get_pconfig($channel_id,'cdav','enabled');
|
||||
@@ -178,7 +219,7 @@ class BasicAuth extends DAV\Auth\Backend\AbstractBasic {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the timezone from the channel in RedBasicAuth.
|
||||
* @brief Sets the timezone from the channel in BasicAuth.
|
||||
*
|
||||
* Set in mod/cloud.php if the channel has a timezone set.
|
||||
*
|
||||
@@ -222,4 +263,4 @@ class BasicAuth extends DAV\Auth\Backend\AbstractBasic {
|
||||
logger('owner_id ' . $this->owner_id, LOGGER_DATA);
|
||||
logger('owner_nick ' . $this->owner_nick, LOGGER_DATA);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ class Browser extends DAV\Browser\Plugin {
|
||||
|
||||
$output = '';
|
||||
if ($this->enablePost) {
|
||||
$this->server->emit('onHTMLActionsPanel', array($parent, &$output));
|
||||
$this->server->emit('onHTMLActionsPanel', array($parent, &$output, $path));
|
||||
}
|
||||
|
||||
$html .= replace_macros(get_markup_template('cloud.tpl'), array(
|
||||
@@ -266,7 +266,7 @@ class Browser extends DAV\Browser\Plugin {
|
||||
* @param \Sabre\DAV\INode $node
|
||||
* @param string &$output
|
||||
*/
|
||||
public function htmlActionsPanel(DAV\INode $node, &$output) {
|
||||
public function htmlActionsPanel(DAV\INode $node, &$output, $path) {
|
||||
if (! $node instanceof DAV\ICollection)
|
||||
return;
|
||||
|
||||
@@ -274,6 +274,22 @@ class Browser extends DAV\Browser\Plugin {
|
||||
// SimpleCollection, we won't need to show the panel either.
|
||||
if (get_class($node) === 'Sabre\\DAV\\SimpleCollection')
|
||||
return;
|
||||
require_once('include/acl_selectors.php');
|
||||
|
||||
$aclselect = null;
|
||||
$lockstate = '';
|
||||
|
||||
if($this->auth->owner_id) {
|
||||
$channel = channelx_by_n($this->auth->owner_id);
|
||||
if($channel) {
|
||||
$acl = new \Zotlabs\Access\AccessList($channel);
|
||||
$channel_acl = $acl->get();
|
||||
$lockstate = (($acl->is_private()) ? 'lock' : 'unlock');
|
||||
|
||||
$aclselect = ((local_channel() == $this->auth->owner_id) ? populate_acl($channel_acl,false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_storage')) : '');
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Storage and quota for the account (all channels of the owner of this directory)!
|
||||
$limit = engr_units_to_bytes(service_class_fetch($owner, 'attach_upload_limit'));
|
||||
@@ -293,7 +309,6 @@ class Browser extends DAV\Browser\Plugin {
|
||||
userReadableSize($limit),
|
||||
round($used / $limit, 1) * 100);
|
||||
}
|
||||
|
||||
// prepare quota for template
|
||||
$quota = array();
|
||||
$quota['used'] = $used;
|
||||
@@ -301,12 +316,25 @@ class Browser extends DAV\Browser\Plugin {
|
||||
$quota['desc'] = $quotaDesc;
|
||||
$quota['warning'] = ((($limit) && ((round($used / $limit, 1) * 100) >= 90)) ? t('WARNING:') : ''); // 10485760 bytes = 100MB
|
||||
|
||||
$path = trim(str_replace('cloud/' . $this->auth->owner_nick, '', $path),'/');
|
||||
|
||||
$output .= replace_macros(get_markup_template('cloud_actionspanel.tpl'), array(
|
||||
'$folder_header' => t('Create new folder'),
|
||||
'$folder_submit' => t('Create'),
|
||||
'$upload_header' => t('Upload file'),
|
||||
'$upload_submit' => t('Upload'),
|
||||
'$quota' => $quota
|
||||
'$quota' => $quota,
|
||||
'$channick' => $this->auth->owner_nick,
|
||||
'$aclselect' => $aclselect,
|
||||
'$allow_cid' => acl2json($channel_acl['allow_cid']),
|
||||
'$allow_gid' => acl2json($channel_acl['allow_gid']),
|
||||
'$deny_cid' => acl2json($channel_acl['deny_cid']),
|
||||
'$deny_gid' => acl2json($channel_acl['deny_gid']),
|
||||
'$lockstate' => $lockstate,
|
||||
'$return_url' => \App::$cmd,
|
||||
'$path' => $path,
|
||||
'$folder' => find_folder_hash_by_path($this->auth->owner_id, $path),
|
||||
'$dragdroptext' => t('Drop files here to immediately upload')
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
738
Zotlabs/Storage/CalDAVClient.php
Normal file
738
Zotlabs/Storage/CalDAVClient.php
Normal file
@@ -0,0 +1,738 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Storage;
|
||||
|
||||
// The Hubzilla CalDAV client will store calendar information in the 'cal' DB table.
|
||||
// Event information will remain in the 'event' table. In order to implement CalDAV on top of our
|
||||
// existing system, there is an event table column called vdata. This will hold the "one true record"
|
||||
// of the event in VCALENDAR format. When we receive a foreign event, we will pick out the fields
|
||||
// of this entry that are important to us and use it to populate the other event table fields.
|
||||
// When we make an event change, it is required that we load this entry as a vobject, make the changes on the
|
||||
// vobject, and then store the result back in event.vdata. This will preserve foreign keys which we
|
||||
// know nothing about. Then we sync this back to the DAV server.
|
||||
|
||||
// We still need a DB update to create a 'cal' table entry for our existing events and link these together.
|
||||
// I'm currently anticipating separating tasks/to-do items from events, so each new account wil get two default calendars.
|
||||
|
||||
// We will eventually provide for magic-auth or cookie login of the CURL process so we won't be required to
|
||||
// store our hubzilla password. Currently for testing we are using HTTP BASIC-AUTH and must initialise the
|
||||
// username/password correctly to make the connection.
|
||||
|
||||
// Repeating events will be awkward because every instance has the same UUID. This would make it difficult to
|
||||
// search for upcoming events if the initial instance was created (for instance) a few years ago. So the current plan is
|
||||
// to create event instances for a prescribed time limit from now (perhaps 5-10 years for annual events).
|
||||
// This plan may change. The repurcussions of this decision mean that an edit to a recurring event must
|
||||
// edit all existing instances of the event, and only one unique instance can be used for sync.
|
||||
// Sabre vobject provides a function to automatically expand recurring events into individual event instances.
|
||||
|
||||
|
||||
|
||||
class CalDAVClient {
|
||||
|
||||
private $username;
|
||||
private $password;
|
||||
|
||||
private $url;
|
||||
|
||||
public $filepos = 0;
|
||||
public $request_data = '';
|
||||
|
||||
function __construct($user,$pass,$url) {
|
||||
$this->username = $user;
|
||||
$this->password = $pass;
|
||||
$this->url = $url;
|
||||
|
||||
}
|
||||
|
||||
private function set_data($s) {
|
||||
$this->request_data = $s;
|
||||
$this->filepos = 0;
|
||||
}
|
||||
|
||||
public function curl_read($ch,$fh,$size) {
|
||||
|
||||
if($this->filepos < 0) {
|
||||
unset($fh);
|
||||
return '';
|
||||
}
|
||||
|
||||
$s = substr($this->request_data,$this->filepos,$size);
|
||||
|
||||
if(strlen($s) < $size)
|
||||
$this->filepos = (-1);
|
||||
else
|
||||
$this->filepos = $this->filepos + $size;
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
function ctag_fetch() {
|
||||
$headers = [ 'Depth: 0', 'Prefer: return-minimal', 'Content-Type: application/xml; charset=utf-8'];
|
||||
|
||||
// recommended ctag fetch by sabre
|
||||
|
||||
$this->set_data('<?xml version="1.0"?>
|
||||
<d:propfind xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
|
||||
<d:prop>
|
||||
<d:displayname />
|
||||
<cs:getctag />
|
||||
<d:sync-token />
|
||||
</d:prop>
|
||||
</d:propfind>');
|
||||
|
||||
// thunderbird uses this - it's a bit more verbose on what capabilities
|
||||
// are provided by the server
|
||||
|
||||
$this->set_data('<?xml version="1.0" encoding="UTF-8"?>
|
||||
<D:propfind xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/" xmlns:C="urn:ietf:params:xml:ns:caldav">
|
||||
<D:prop>
|
||||
<D:resourcetype/>
|
||||
<D:owner/>
|
||||
<D:current-user-principal/>
|
||||
<D:supported-report-set/>
|
||||
<C:supported-calendar-component-set/>
|
||||
<CS:getctag/>
|
||||
</D:prop>
|
||||
</D:propfind>');
|
||||
|
||||
|
||||
|
||||
$auth = $this->username . ':' . $this->password;
|
||||
|
||||
$recurse = 0;
|
||||
|
||||
$x = z_fetch_url($this->url,true,$recurse,
|
||||
[ 'headers' => $headers,
|
||||
'http_auth' => $auth,
|
||||
'custom' => 'PROPFIND',
|
||||
'upload' => true,
|
||||
'infile' => 3,
|
||||
'infilesize' => strlen($this->request_data),
|
||||
'readfunc' => [ $this, 'curl_read' ]
|
||||
]);
|
||||
|
||||
return $x;
|
||||
|
||||
}
|
||||
|
||||
|
||||
function detail_fetch() {
|
||||
$headers = [ 'Depth: 1', 'Prefer: return-minimal', 'Content-Type: application/xml; charset=utf-8'];
|
||||
|
||||
// this query should return all objects in the given calendar, you can filter it appropriately
|
||||
// using filter options
|
||||
|
||||
$this->set_data('<?xml version="1.0"?>
|
||||
<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">
|
||||
<d:prop>
|
||||
<d:getetag />
|
||||
<c:calendar-data />
|
||||
</d:prop>
|
||||
<c:filter>
|
||||
<c:comp-filter name="VCALENDAR" />
|
||||
</c:filter>
|
||||
</c:calendar-query>');
|
||||
|
||||
$auth = $this->username . ':' . $this->password;
|
||||
|
||||
$recurse = 0;
|
||||
$x = z_fetch_url($this->url,true,$recurse,
|
||||
[ 'headers' => $headers,
|
||||
'http_auth' => $auth,
|
||||
'custom' => 'REPORT',
|
||||
'upload' => true,
|
||||
'infile' => 3,
|
||||
'infilesize' => strlen($this->request_data),
|
||||
'readfunc' => [ $this, 'curl_read' ]
|
||||
]);
|
||||
|
||||
|
||||
return $x;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
PROPFIND /calendars/johndoe/home/ HTTP/1.1
|
||||
Depth: 0
|
||||
Prefer: return-minimal
|
||||
Content-Type: application/xml; charset=utf-8
|
||||
|
||||
<d:propfind xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
|
||||
<d:prop>
|
||||
<d:displayname />
|
||||
<cs:getctag />
|
||||
</d:prop>
|
||||
</d:propfind>
|
||||
|
||||
// Responses: success
|
||||
|
||||
HTTP/1.1 207 Multi-status
|
||||
Content-Type: application/xml; charset=utf-8
|
||||
|
||||
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
|
||||
<d:response>
|
||||
<d:href>/calendars/johndoe/home/</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<d:displayname>Home calendar</d:displayname>
|
||||
<cs:getctag>3145</cs:getctag>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
</d:multistatus>
|
||||
|
||||
// Responses: fail
|
||||
|
||||
HTTP/1.1 207 Multi-status
|
||||
Content-Type: application/xml; charset=utf-8
|
||||
|
||||
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
|
||||
<d:response>
|
||||
<d:href>/calendars/johndoe/home/</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<d:displayname />
|
||||
<cs:getctag />
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 403 Forbidden</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
</d:multistatus>
|
||||
|
||||
|
||||
// sample request body in DOM
|
||||
// prepare request body
|
||||
$doc = new DOMDocument('1.0', 'utf-8');
|
||||
$doc->formatOutput = true;
|
||||
|
||||
$query = $doc->createElement('c:calendar-query');
|
||||
$query->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:c', 'urn:ietf:params:xml:ns:caldav');
|
||||
$query->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:d', 'DAV:');
|
||||
|
||||
$prop = $doc->createElement('d:prop');
|
||||
$prop->appendChild($doc->createElement('d:getetag'));
|
||||
$prop->appendChild($doc->createElement('c:calendar-data'));
|
||||
$query->appendChild($prop);
|
||||
$doc->appendChild($query);
|
||||
$body = $doc->saveXML();
|
||||
|
||||
echo "Body: " . $body . "<br>";
|
||||
|
||||
|
||||
Now we download every single object in this calendar. To do this, we use a REPORT method.
|
||||
|
||||
REPORT /calendars/johndoe/home/ HTTP/1.1
|
||||
Depth: 1
|
||||
Prefer: return-minimal
|
||||
Content-Type: application/xml; charset=utf-8
|
||||
|
||||
<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
||||
<d:prop>
|
||||
<d:getetag />
|
||||
<c:calendar-data />
|
||||
</d:prop>
|
||||
<c:filter>
|
||||
<c:comp-filter name="VCALENDAR" />
|
||||
</c:filter>
|
||||
</c:calendar-query>
|
||||
|
||||
This request will give us every object that's a VCALENDAR object, and its etag.
|
||||
|
||||
If you're only interested in VTODO (because you're writing a todo app) you can also filter for just those:
|
||||
|
||||
REPORT /calendars/johndoe/home/ HTTP/1.1
|
||||
Depth: 1
|
||||
Prefer: return-minimal
|
||||
Content-Type: application/xml; charset=utf-8
|
||||
|
||||
<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
||||
<d:prop>
|
||||
<d:getetag />
|
||||
<c:calendar-data />
|
||||
</d:prop>
|
||||
<c:filter>
|
||||
<c:comp-filter name="VCALENDAR">
|
||||
<c:comp-filter name="VTODO" />
|
||||
</c:comp-filter>
|
||||
</c:filter>
|
||||
</c:calendar-query>
|
||||
|
||||
Similarly it's also possible to filter to just events, or only get events within a specific time-range.
|
||||
|
||||
This report will return a multi-status object again:
|
||||
|
||||
HTTP/1.1 207 Multi-status
|
||||
Content-Type: application/xml; charset=utf-8
|
||||
|
||||
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
|
||||
<d:response>
|
||||
<d:href>/calendars/johndoe/home/132456762153245.ics</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<d:getetag>"2134-314"</d:getetag>
|
||||
<c:calendar-data>BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
CALSCALE:GREGORIAN
|
||||
BEGIN:VTODO
|
||||
UID:132456762153245
|
||||
SUMMARY:Do the dishes
|
||||
DUE:20121028T115600Z
|
||||
END:VTODO
|
||||
END:VCALENDAR
|
||||
</c:calendar-data>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
<d:response>
|
||||
<d:href>/calendars/johndoe/home/132456-34365.ics</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<d:getetag>"5467-323"</d:getetag>
|
||||
<c:calendar-data>BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
CALSCALE:GREGORIAN
|
||||
BEGIN:VEVENT
|
||||
UID:132456-34365
|
||||
SUMMARY:Weekly meeting
|
||||
DTSTART:20120101T120000
|
||||
DURATION:PT1H
|
||||
RRULE:FREQ=WEEKLY
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
</c:calendar-data>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
</d:multistatus>
|
||||
|
||||
This calendar only contained 2 objects. A todo and a weekly event.
|
||||
|
||||
So after you retrieved and processed these, for each object you must retain:
|
||||
|
||||
The calendar data itself
|
||||
The url
|
||||
The etag
|
||||
|
||||
In this case all urls ended with .ics. This is often the case, but you must not rely on this. In this case the UID in the calendar object was also identical to a part of the url. This too is often the case, but again not something you can rely on, so don't make any assumptions.
|
||||
|
||||
The url and the UID have no meaningful relationship, so treat both those items as separate unique identifiers.
|
||||
Finding out if anything changed
|
||||
|
||||
To see if anything in a calendar changed, we simply request the ctag again on the calendar. If the ctag did not change, you still have the latest copy.
|
||||
|
||||
If it did change, you must request all the etags in the entire calendar again:
|
||||
|
||||
REPORT /calendars/johndoe/home/ HTTP/1.1
|
||||
Depth: 1
|
||||
Prefer: return-minimal
|
||||
Content-Type: application/xml; charset=utf-8
|
||||
|
||||
<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
||||
<d:prop>
|
||||
<d:getetag />
|
||||
</d:prop>
|
||||
<c:filter>
|
||||
<c:comp-filter name="VCALENDAR">
|
||||
<c:comp-filter name="VTODO" />
|
||||
</c:comp-filter>
|
||||
</c:filter>
|
||||
</c:calendar-query>
|
||||
|
||||
Note that this last request is extremely similar to a previous one, but we are only asking fo the etag, not the calendar-data.
|
||||
|
||||
The reason for this, is that calendars can be rather huge. It will save a TON of bandwidth to only check the etag first.
|
||||
|
||||
HTTP/1.1 207 Multi-status
|
||||
Content-Type: application/xml; charset=utf-8
|
||||
|
||||
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
|
||||
<d:response>
|
||||
<d:href>/calendars/johndoe/home/132456762153245.ics</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<d:getetag>"xxxx-xxx"</d:getetag>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
<d:response>
|
||||
<d:href>/calendars/johndoe/home/fancy-caldav-client-1234253678.ics</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<d:getetag>"5-12"</d:getetag>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
</d:multistatus>
|
||||
|
||||
Judging from this last request, 3 things have changed:
|
||||
|
||||
The etag for the task has changed, so the contents must be different
|
||||
There's a new url, some other client must have added an object
|
||||
One object is missing, something must have deleted it.
|
||||
|
||||
So based on those 3 items we know that we need to delete an object from our local list, and fetch the contents for the new item, and the updated one.
|
||||
|
||||
To fetch the data for these, you can simply issue GET requests:
|
||||
|
||||
GET /calendars/johndoe/home/132456762153245.ics HTTP/1.1
|
||||
|
||||
But, because in a worst-case scenario this could result in a LOT of GET requests we can do a 'multiget'.
|
||||
|
||||
REPORT /calendars/johndoe/home/ HTTP/1.1
|
||||
Depth: 1
|
||||
Prefer: return-minimal
|
||||
Content-Type: application/xml; charset=utf-8
|
||||
|
||||
<c:calendar-multiget xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
||||
<d:prop>
|
||||
<d:getetag />
|
||||
<c:calendar-data />
|
||||
</d:prop>
|
||||
<d:href>/calendars/johndoe/home/132456762153245.ics</d:href>
|
||||
<d:href>/calendars/johndoe/home/fancy-caldav-client-1234253678.ics</d:href>
|
||||
</c:calendar-multiget>
|
||||
|
||||
This request will simply return a multi-status again with the calendar-data and etag.
|
||||
A small note about application design
|
||||
|
||||
If you read this far and understood what's been said, you may have realized that it's a bit cumbersome to have a separate step for the initial sync, and subsequent updates.
|
||||
|
||||
It would totally be possible to skip the 'initial sync', and just use calendar-query and calendar-multiget REPORTS for the initial sync as well.
|
||||
Updating a calendar object
|
||||
|
||||
Updating a calendar object is rather simple:
|
||||
|
||||
PUT /calendars/johndoe/home/132456762153245.ics HTTP/1.1
|
||||
Content-Type: text/calendar; charset=utf-8
|
||||
If-Match: "2134-314"
|
||||
|
||||
BEGIN:VCALENDAR
|
||||
....
|
||||
END:VCALENDAR
|
||||
|
||||
A response to this will be something like this:
|
||||
|
||||
HTTP/1.1 204 No Content
|
||||
ETag: "2134-315"
|
||||
|
||||
The update gave us back the new ETag. SabreDAV gives this ETag on updates back most of the time, but not always.
|
||||
|
||||
There are cases where the caldav server must modify the iCalendar object right after storage. In those cases an ETag will not be returned, and you should issue a GET request immediately to get the correct object.
|
||||
|
||||
A few notes:
|
||||
|
||||
You must not change the UID of the original object
|
||||
Every object should hold only 1 event or task.
|
||||
You cannot change an VEVENT into a VTODO.
|
||||
|
||||
Creating a calendar object
|
||||
|
||||
Creating a calendar object is almost identical, except that you don't have a url yet to a calendar object.
|
||||
|
||||
Instead, it is up to you to determine the new url.
|
||||
|
||||
PUT /calendars/johndoe/home/somerandomstring.ics HTTP/1.1
|
||||
Content-Type: text/calendar; charset=utf-8
|
||||
|
||||
BEGIN:VCALENDAR
|
||||
....
|
||||
END:VCALENDAR
|
||||
|
||||
A response to this will be something like this:
|
||||
|
||||
HTTP/1.1 201 Created
|
||||
ETag: "21345-324"
|
||||
|
||||
Similar to updating, an ETag is often returned, but there are cases where this is not true.
|
||||
Deleting a calendar object
|
||||
|
||||
Deleting is simple enough:
|
||||
|
||||
DELETE /calendars/johndoe/home/132456762153245.ics HTTP/1.1
|
||||
If-Match: "2134-314"
|
||||
|
||||
Speeding up Sync with WebDAV-Sync
|
||||
|
||||
WebDAV-Sync is a protocol extension that is defined in rfc6578. Because this extension was defined later, some servers may not support this yet.
|
||||
|
||||
SabreDAV supports this since 2.0.
|
||||
|
||||
WebDAV-Sync allows a client to ask just for calendars that have changed. The process on a high-level is as follows:
|
||||
|
||||
Client requests sync-token from server.
|
||||
Server reports token 15.
|
||||
Some time passes.
|
||||
Client does a Sync REPORT on an calendar, and supplied token 15.
|
||||
Server returns vcard urls that have changed or have been deleted and returns token 17.
|
||||
|
||||
As you can see, after the initial sync, only items that have been created, modified or deleted will ever be sent.
|
||||
|
||||
This has a lot of advantages. The transmitted xml bodies can generally be a lot shorter, and is also easier on both client and server in terms of memory and CPU usage, because only a limited set of items will have to be compared.
|
||||
|
||||
It's important to note, that a client should only do Sync operations, if the server reports that it has support for it. The quickest way to do so, is to request {DAV}sync-token on the calendar you wish to sync.
|
||||
|
||||
Technically, a server may support 'sync' on one calendar, and it may not support it on another, although this is probably rare.
|
||||
Getting the first sync-token
|
||||
|
||||
Initially, we just request a sync token when asking for calendar information:
|
||||
|
||||
PROPFIND /calendars/johndoe/home/ HTTP/1.1
|
||||
Depth: 0
|
||||
Content-Type: application/xml; charset=utf-8
|
||||
|
||||
<d:propfind xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
|
||||
<d:prop>
|
||||
<d:displayname />
|
||||
<cs:getctag />
|
||||
<d:sync-token />
|
||||
</d:prop>
|
||||
</d:propfind>
|
||||
|
||||
This would return something as follows:
|
||||
|
||||
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
|
||||
<d:response>
|
||||
<d:href>/calendars/johndoe/home/</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<d:displayname>My calendar</d:displayname>
|
||||
<cs:getctag>3145</cs:getctag>
|
||||
<d:sync-token>http://sabredav.org/ns/sync-token/3145</d:sync-token>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
</d:multistatus>
|
||||
|
||||
As you can see, the sync-token is a url. It always should be a url. Even though a number appears in the url, you are not allowed to attach any meaning to that url. Some servers may have use an increasing number, another server may use a completely random string.
|
||||
Receiving changes
|
||||
|
||||
After a sync token has been obtained, and the client already has the initial copy of the calendar, the client is able to request all changes since the token was issued.
|
||||
|
||||
This is done with a REPORT request that may look like this:
|
||||
|
||||
REPORT /calendars/johndoe/home/ HTTP/1.1
|
||||
Host: dav.example.org
|
||||
Content-Type: application/xml; charset="utf-8"
|
||||
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<d:sync-collection xmlns:d="DAV:">
|
||||
<d:sync-token>http://sabredav.org/ns/sync/3145</d:sync-token>
|
||||
<d:sync-level>1</d:sync-level>
|
||||
<d:prop>
|
||||
<d:getetag/>
|
||||
</d:prop>
|
||||
</d:sync-collection>
|
||||
|
||||
This requests all the changes since sync-token identified by http://sabredav.org/ns/sync/3145, and for the calendar objects that have been added or modified, we're requesting the etag.
|
||||
|
||||
The response to a query like this is another multistatus xml body. Example:
|
||||
|
||||
HTTP/1.1 207 Multi-Status
|
||||
Content-Type: application/xml; charset="utf-8"
|
||||
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<d:multistatus xmlns:d="DAV:">
|
||||
<d:response>
|
||||
<d:href>/calendars/johndoe/home/newevent.ics</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<d:getetag>"33441-34321"</d:getetag>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
<d:response>
|
||||
<d:href>/calendars/johndoe/home/updatedevent.ics</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<d:getetag>"33541-34696"</d:getetag>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
<d:response>
|
||||
<d:href>/calendars/johndoe/home/deletedevent.ics</d:href>
|
||||
<d:status>HTTP/1.1 404 Not Found</d:status>
|
||||
</d:response>
|
||||
<d:sync-token>http://sabredav.org/ns/sync/5001</d:sync-token>
|
||||
</d:multistatus>
|
||||
|
||||
The last response reported two changes: newevent.ics and updatedevent.ics. There's no way to tell from the response wether those cards got created or updated, you, as a client can only infer this based on the vcards you are already aware of.
|
||||
|
||||
The entry with name deletedevent.ics got deleted as indicated by the 404 status. Note that the status element is here a child of d:response when in all previous examples it has been a child of d:propstat.
|
||||
|
||||
The other difference with the other multi-status examples, is that this one has a sync-token element with the latest sync-token.
|
||||
Caveats
|
||||
|
||||
Note that a server is free to 'forget' any sync-tokens that have been previously issued. In this case it may be needed to do a full-sync again.
|
||||
|
||||
In case the supplied sync-token is not recognized by the server, a HTTP error is emitted. SabreDAV emits a 403.
|
||||
Discovery
|
||||
|
||||
Ideally you will want to make sure that all the calendars in an account are automatically discovered. The best user interface would be to just have to ask for three items:
|
||||
|
||||
Username
|
||||
Password
|
||||
Server
|
||||
|
||||
And the server should be as short as possible. This is possible with most servers.
|
||||
|
||||
If, for example a user specified 'dav.example.org' for the server, the first thing you should do is attempt to send a PROPFIND request to https://dav.example.org/. Note that you SHOULD try the https url before the http url.
|
||||
|
||||
This PROPFIND request looks as follows:
|
||||
|
||||
PROPFIND / HTTP/1.1
|
||||
Depth: 0
|
||||
Prefer: return-minimal
|
||||
Content-Type: application/xml; charset=utf-8
|
||||
|
||||
<d:propfind xmlns:d="DAV:">
|
||||
<d:prop>
|
||||
<d:current-user-principal />
|
||||
</d:prop>
|
||||
</d:propfind>
|
||||
|
||||
This will return a response such as the following:
|
||||
|
||||
HTTP/1.1 207 Multi-status
|
||||
Content-Type: application/xml; charset=utf-8
|
||||
|
||||
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
|
||||
<d:response>
|
||||
<d:href>/</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<d:current-user-principal>
|
||||
<d:href>/principals/users/johndoe/</d:href>
|
||||
</d:current-user-principal>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
</d:multistatus>
|
||||
|
||||
A 'principal' is a user. The url that's being returned, is a url that refers to the current user. On this url you can request additional information about the user.
|
||||
|
||||
What we need from this url, is their 'calendar home'. The calendar home is a collection that contains all of the users' calendars.
|
||||
|
||||
To request that, issue the following request:
|
||||
|
||||
PROPFIND /principals/users/johndoe/ HTTP/1.1
|
||||
Depth: 0
|
||||
Prefer: return-minimal
|
||||
Content-Type: application/xml; charset=utf-8
|
||||
|
||||
<d:propfind xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
||||
<d:prop>
|
||||
<c:calendar-home-set />
|
||||
</d:prop>
|
||||
</d:propfind>
|
||||
|
||||
This will return a response such as the following:
|
||||
|
||||
HTTP/1.1 207 Multi-status
|
||||
Content-Type: application/xml; charset=utf-8
|
||||
|
||||
<d:multistatus xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
||||
<d:response>
|
||||
<d:href>/principals/users/johndoe/</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<c:calendar-home-set>
|
||||
<d:href>/calendars/johndoe/</d:href>
|
||||
</c:calendar-home-set>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
</d:multistatus>
|
||||
|
||||
Lastly, to list all the calendars for the user, issue a PROPFIND request with Depth: 1.
|
||||
|
||||
PROPFIND /calendars/johndoe/ HTTP/1.1
|
||||
Depth: 1
|
||||
Prefer: return-minimal
|
||||
Content-Type: application/xml; charset=utf-8
|
||||
|
||||
<d:propfind xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
||||
<d:prop>
|
||||
<d:resourcetype />
|
||||
<d:displayname />
|
||||
<cs:getctag />
|
||||
<c:supported-calendar-component-set />
|
||||
</d:prop>
|
||||
</d:propfind>
|
||||
|
||||
In that last request, we asked for 4 properties.
|
||||
|
||||
The resourcetype tells us what type of object we're getting back. You must read out the resourcetype and ensure that it contains at least a calendar element in the CalDAV namespace. Other items may be returned, including non- calendar, which your application should ignore.
|
||||
|
||||
The displayname is a human-readable string for the calendarname, the ctag was already covered in an earlier section.
|
||||
|
||||
Lastly, supported-calendar-component-set. This gives us a list of components that the calendar accepts. This could be just VTODO, VEVENT, VJOURNAL or a combination of these three.
|
||||
|
||||
If you are just creating a todo-list application, this means you should only list the calendars that support the VTODO component.
|
||||
|
||||
HTTP/1.1 207 Multi-status
|
||||
Content-Type: application/xml; charset=utf-8
|
||||
|
||||
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
||||
<d:response>
|
||||
<d:href>/calendars/johndoe/</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<d:resourcetype>
|
||||
<d:collection/>
|
||||
</d:resourcetype>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
<d:response>
|
||||
<d:href>/calendars/johndoe/home/</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<d:resourcetype>
|
||||
<d:collection/>
|
||||
<c:calendar/>
|
||||
</d:resourcetype>
|
||||
<d:displayname>Home calendar</d:displayname>
|
||||
<cs:getctag>3145</cs:getctag>
|
||||
<c:supported-calendar-component-set>
|
||||
<c:comp name="VEVENT" />
|
||||
</c:supported-calendar-component-set>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
<d:response>
|
||||
<d:href>/calendars/johndoe/tasks/</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<d:resourcetype>
|
||||
<d:collection/>
|
||||
<c:calendar/>
|
||||
</d:resourcetype>
|
||||
<d:displayname>My TODO list</d:displayname>
|
||||
<cs:getctag>3345</cs:getctag>
|
||||
<c:supported-calendar-component-set>
|
||||
<c:comp name="VTODO" />
|
||||
</c:supported-calendar-component-set>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
</d:multistatus>
|
||||
*/
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace Zotlabs\Storage;
|
||||
|
||||
use Sabre\DAV;
|
||||
use Sabre\HTTP;
|
||||
|
||||
/**
|
||||
* @brief RedDirectory class.
|
||||
@@ -91,7 +92,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||
}
|
||||
|
||||
$contents = RedCollectionData($this->red_path, $this->auth);
|
||||
$contents = $this->CollectionData($this->red_path, $this->auth);
|
||||
return $contents;
|
||||
}
|
||||
|
||||
@@ -119,7 +120,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
return new Directory('/' . $modulename, $this->auth);
|
||||
}
|
||||
|
||||
$x = RedFileData($this->ext_path . '/' . $name, $this->auth);
|
||||
$x = $this->FileData($this->ext_path . '/' . $name, $this->auth);
|
||||
if ($x) {
|
||||
return $x;
|
||||
}
|
||||
@@ -159,7 +160,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||
}
|
||||
|
||||
list($parent_path, ) = DAV\URLUtil::splitPath($this->red_path);
|
||||
list($parent_path, ) = HTTP\URLUtil::splitPath($this->red_path);
|
||||
$new_path = $parent_path . '/' . $name;
|
||||
|
||||
$r = q("UPDATE attach SET filename = '%s' WHERE hash = '%s' AND uid = %d",
|
||||
@@ -206,6 +207,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||
}
|
||||
|
||||
|
||||
$mimetype = z_mime_content_type($name);
|
||||
|
||||
$c = q("SELECT * FROM channel WHERE channel_id = %d AND channel_removed = 0 LIMIT 1",
|
||||
@@ -369,6 +371,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
);
|
||||
|
||||
if ($r) {
|
||||
require_once('include/attach.php');
|
||||
$result = attach_mkdir($r[0], $this->auth->observer, array('filename' => $name, 'folder' => $this->folder_hash));
|
||||
|
||||
if($result['success']) {
|
||||
@@ -431,8 +434,8 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
return true;
|
||||
}
|
||||
|
||||
$x = RedFileData($this->ext_path . '/' . $name, $this->auth, true);
|
||||
//logger('RedFileData returns: ' . print_r($x, true), LOGGER_DATA);
|
||||
$x = $this->FileData($this->ext_path . '/' . $name, $this->auth, true);
|
||||
//logger('FileData returns: ' . print_r($x, true), LOGGER_DATA);
|
||||
if ($x)
|
||||
return true;
|
||||
|
||||
@@ -565,4 +568,280 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
$free
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Array with all Directory and File DAV\Node items for the given path.
|
||||
*
|
||||
*
|
||||
* @param string $file path to a directory
|
||||
* @param \Zotlabs\Storage\BasicAuth &$auth
|
||||
* @returns null|array \Sabre\DAV\INode[]
|
||||
* @throw \Sabre\DAV\Exception\Forbidden
|
||||
* @throw \Sabre\DAV\Exception\NotFound
|
||||
*/
|
||||
|
||||
function CollectionData($file, &$auth) {
|
||||
$ret = array();
|
||||
|
||||
$x = strpos($file, '/cloud');
|
||||
if ($x === 0) {
|
||||
$file = substr($file, 6);
|
||||
}
|
||||
|
||||
// return a list of channel if we are not inside a channel
|
||||
if ((! $file) || ($file === '/')) {
|
||||
return $this->ChannelList($auth);
|
||||
}
|
||||
|
||||
$file = trim($file, '/');
|
||||
$path_arr = explode('/', $file);
|
||||
|
||||
if (! $path_arr)
|
||||
return null;
|
||||
|
||||
$channel_name = $path_arr[0];
|
||||
|
||||
$r = q("SELECT channel_id FROM channel WHERE channel_address = '%s' LIMIT 1",
|
||||
dbesc($channel_name)
|
||||
);
|
||||
|
||||
if (! $r)
|
||||
return null;
|
||||
|
||||
$channel_id = $r[0]['channel_id'];
|
||||
$perms = permissions_sql($channel_id);
|
||||
|
||||
$auth->owner_id = $channel_id;
|
||||
|
||||
$path = '/' . $channel_name;
|
||||
|
||||
$folder = '';
|
||||
$errors = false;
|
||||
$permission_error = false;
|
||||
|
||||
for ($x = 1; $x < count($path_arr); $x++) {
|
||||
$r = q("SELECT id, hash, filename, flags, is_dir FROM attach WHERE folder = '%s' AND filename = '%s' AND uid = %d AND is_dir != 0 $perms LIMIT 1",
|
||||
dbesc($folder),
|
||||
dbesc($path_arr[$x]),
|
||||
intval($channel_id)
|
||||
);
|
||||
if (! $r) {
|
||||
// path wasn't found. Try without permissions to see if it was the result of permissions.
|
||||
$errors = true;
|
||||
$r = q("select id, hash, filename, flags, is_dir from attach where folder = '%s' and filename = '%s' and uid = %d and is_dir != 0 limit 1",
|
||||
dbesc($folder),
|
||||
basename($path_arr[$x]),
|
||||
intval($channel_id)
|
||||
);
|
||||
if ($r) {
|
||||
$permission_error = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ($r && intval($r[0]['is_dir'])) {
|
||||
$folder = $r[0]['hash'];
|
||||
$path = $path . '/' . $r[0]['filename'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($errors) {
|
||||
if ($permission_error) {
|
||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||
}
|
||||
else {
|
||||
throw new DAV\Exception\NotFound('A component of the request file path could not be found.');
|
||||
}
|
||||
}
|
||||
|
||||
// This should no longer be needed since we just returned errors for paths not found
|
||||
if ($path !== '/' . $file) {
|
||||
logger("Path mismatch: $path !== /$file");
|
||||
return NULL;
|
||||
}
|
||||
if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
|
||||
$prefix = 'DISTINCT ON (filename)';
|
||||
$suffix = 'ORDER BY filename';
|
||||
}
|
||||
else {
|
||||
$prefix = '';
|
||||
$suffix = 'GROUP BY filename';
|
||||
}
|
||||
$r = q("select $prefix id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, created, edited from attach where folder = '%s' and uid = %d $perms $suffix",
|
||||
dbesc($folder),
|
||||
intval($channel_id)
|
||||
);
|
||||
|
||||
foreach ($r as $rr) {
|
||||
//logger('filename: ' . $rr['filename'], LOGGER_DEBUG);
|
||||
if (intval($rr['is_dir'])) {
|
||||
$ret[] = new Directory($path . '/' . $rr['filename'], $auth);
|
||||
}
|
||||
else {
|
||||
$ret[] = new File($path . '/' . $rr['filename'], $rr, $auth);
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Returns an array with viewable channels.
|
||||
*
|
||||
* Get a list of Directory objects with all the channels where the visitor
|
||||
* has <b>view_storage</b> perms.
|
||||
*
|
||||
*
|
||||
* @param BasicAuth &$auth
|
||||
* @return array Directory[]
|
||||
*/
|
||||
|
||||
function ChannelList(&$auth) {
|
||||
$ret = array();
|
||||
|
||||
$r = q("SELECT channel_id, channel_address FROM channel WHERE channel_removed = 0
|
||||
AND channel_system = 0 AND NOT (channel_pageflags & %d)>0",
|
||||
intval(PAGE_HIDDEN)
|
||||
);
|
||||
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
if (perm_is_allowed($rr['channel_id'], $auth->observer, 'view_storage')) {
|
||||
logger('found channel: /cloud/' . $rr['channel_address'], LOGGER_DATA);
|
||||
// @todo can't we drop '/cloud'? It gets stripped off anyway in RedDirectory
|
||||
$ret[] = new Directory('/cloud/' . $rr['channel_address'], $auth);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*
|
||||
* @param string $file
|
||||
* path to file or directory
|
||||
* @param BasicAuth &$auth
|
||||
* @param boolean $test (optional) enable test mode
|
||||
* @return File|Directory|boolean|null
|
||||
* @throw \Sabre\DAV\Exception\Forbidden
|
||||
*/
|
||||
|
||||
function FileData($file, &$auth, $test = false) {
|
||||
logger($file . (($test) ? ' (test mode) ' : ''), LOGGER_DATA);
|
||||
|
||||
$x = strpos($file, '/cloud');
|
||||
if ($x === 0) {
|
||||
$file = substr($file, 6);
|
||||
}
|
||||
else {
|
||||
$x = strpos($file,'/dav');
|
||||
if($x === 0)
|
||||
$file = substr($file,4);
|
||||
}
|
||||
|
||||
|
||||
if ((! $file) || ($file === '/')) {
|
||||
return new Directory('/', $auth);
|
||||
}
|
||||
|
||||
$file = trim($file, '/');
|
||||
|
||||
$path_arr = explode('/', $file);
|
||||
|
||||
if (! $path_arr)
|
||||
return null;
|
||||
|
||||
$channel_name = $path_arr[0];
|
||||
|
||||
$r = q("select channel_id from channel where channel_address = '%s' limit 1",
|
||||
dbesc($channel_name)
|
||||
);
|
||||
|
||||
if (! $r)
|
||||
return null;
|
||||
|
||||
$channel_id = $r[0]['channel_id'];
|
||||
|
||||
$path = '/' . $channel_name;
|
||||
|
||||
$auth->owner_id = $channel_id;
|
||||
|
||||
$permission_error = false;
|
||||
|
||||
$folder = '';
|
||||
|
||||
require_once('include/security.php');
|
||||
$perms = permissions_sql($channel_id);
|
||||
|
||||
$errors = false;
|
||||
|
||||
for ($x = 1; $x < count($path_arr); $x++) {
|
||||
$r = q("select id, hash, filename, flags, is_dir from attach where folder = '%s' and filename = '%s' and uid = %d and is_dir != 0 $perms",
|
||||
dbesc($folder),
|
||||
dbesc($path_arr[$x]),
|
||||
intval($channel_id)
|
||||
);
|
||||
|
||||
if ($r && intval($r[0]['is_dir'])) {
|
||||
$folder = $r[0]['hash'];
|
||||
$path = $path . '/' . $r[0]['filename'];
|
||||
}
|
||||
if (! $r) {
|
||||
$r = q("select id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, os_storage, created, edited from attach
|
||||
where folder = '%s' and filename = '%s' and uid = %d $perms order by filename limit 1",
|
||||
dbesc($folder),
|
||||
dbesc(basename($file)),
|
||||
intval($channel_id)
|
||||
);
|
||||
}
|
||||
if (! $r) {
|
||||
$errors = true;
|
||||
$r = q("select id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, os_storage, created, edited from attach
|
||||
where folder = '%s' and filename = '%s' and uid = %d order by filename limit 1",
|
||||
dbesc($folder),
|
||||
dbesc(basename($file)),
|
||||
intval($channel_id)
|
||||
);
|
||||
if ($r)
|
||||
$permission_error = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($path === '/' . $file) {
|
||||
if ($test)
|
||||
return true;
|
||||
// final component was a directory.
|
||||
return new Directory($file, $auth);
|
||||
}
|
||||
|
||||
if ($errors) {
|
||||
logger('not found ' . $file);
|
||||
if ($test)
|
||||
return false;
|
||||
if ($permission_error) {
|
||||
logger('permission error ' . $file);
|
||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ($r) {
|
||||
if ($test)
|
||||
return true;
|
||||
|
||||
if (intval($r[0]['is_dir'])) {
|
||||
return new Directory($path . '/' . $r[0]['filename'], $auth);
|
||||
}
|
||||
else {
|
||||
return new File($path . '/' . $r[0]['filename'], $r[0], $auth);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -337,6 +337,10 @@ class File extends DAV\Node implements DAV\IFile {
|
||||
}
|
||||
}
|
||||
|
||||
if(get_pconfig($this->auth->owner_id,'system','os_delete_prohibit') && \App::$module == 'dav') {
|
||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||
}
|
||||
|
||||
attach_delete($this->auth->owner_id, $this->data['hash']);
|
||||
|
||||
$ch = channelx_by_n($this->auth->owner_id);
|
||||
|
||||
@@ -21,6 +21,9 @@ class CheckJS {
|
||||
$page = urlencode(\App::$query_string);
|
||||
|
||||
if($test) {
|
||||
self::$jsdisabled = 1;
|
||||
if(array_key_exists('jsdisabled',$_COOKIE))
|
||||
self::$jsdisabled = $_COOKIE['jsdisabled'];
|
||||
|
||||
if(! array_key_exists('jsdisabled',$_COOKIE)) {
|
||||
\App::$page['htmlhead'] .= "\r\n" . '<script>document.cookie="jsdisabled=0; path=/"; var jsMatch = /\&jsdisabled=0/; if (!jsMatch.exec(location.href)) { location.href = "' . z_root() . '/nojs/0?f=&redir=' . $page . '" ; }</script>' . "\r\n";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user