mirror of
https://framagit.org/hubzilla/core.git
synced 2026-06-22 17:26:14 -04:00
Compare commits
906 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 | ||
|
|
953ca2c21e | ||
|
|
8b42834c3f | ||
|
|
fb61c4fb34 | ||
|
|
30841d9470 | ||
|
|
7a4efcf67f | ||
|
|
6e0eb532a5 | ||
|
|
bfaabfb7b5 | ||
|
|
4578649f75 | ||
|
|
b6324246ff | ||
|
|
53e4713932 | ||
|
|
76e11b46b7 | ||
|
|
3dad4a9ff1 | ||
|
|
310f370b55 | ||
|
|
5b92922516 | ||
|
|
dbb0a0283f | ||
|
|
08f108e6cf | ||
|
|
5c947c7519 | ||
|
|
178b440f05 | ||
|
|
755dd67ec7 | ||
|
|
99e8499722 | ||
|
|
2e7606f569 | ||
|
|
22edd00211 | ||
|
|
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 | ||
|
|
d9aa16aa82 | ||
|
|
976e32d3ae | ||
|
|
476116a972 | ||
|
|
f2dda646ec | ||
|
|
05ed20d336 | ||
|
|
b0476be36f | ||
|
|
a005088228 | ||
|
|
ef1c01d968 | ||
|
|
47fc0c7958 | ||
|
|
a9f690260a | ||
|
|
688171d016 | ||
|
|
a16dcc877c | ||
|
|
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 | ||
|
|
7abfe716b4 | ||
|
|
81b3c59711 | ||
|
|
410f5389ae | ||
|
|
290a14d29e | ||
|
|
a1183bf09a | ||
|
|
e109abbef7 | ||
|
|
43055e0199 | ||
|
|
1789c3242a | ||
|
|
f41380de77 | ||
|
|
0e0a6f5f8d | ||
|
|
ef95c68b4f | ||
|
|
0cada39c8a | ||
|
|
bdbbe00bdf | ||
|
|
a1241daa41 | ||
|
|
1f43da2ade | ||
|
|
1614dbf6ae | ||
|
|
96cd63cf1a | ||
|
|
974ca9d526 | ||
|
|
86985b454f | ||
|
|
c55a7b5f36 | ||
|
|
beb55235c6 | ||
|
|
9d5d3a9468 | ||
|
|
cf415a4312 | ||
|
|
bb3d56a0b2 | ||
|
|
8f181bb188 | ||
|
|
135d84ba37 | ||
|
|
77442dfcdc | ||
|
|
ed597146fa | ||
|
|
7a242f829f | ||
|
|
7fc2b13fe6 | ||
|
|
ee5372784e | ||
|
|
0dcea87b99 | ||
|
|
d5d5d78e3a | ||
|
|
a10f5e9e06 | ||
|
|
85e82e919e | ||
|
|
9b96fe66a6 | ||
|
|
11045b92fb | ||
|
|
2ad5010dc3 | ||
|
|
40bba93a31 | ||
|
|
9410b63bbc | ||
|
|
4234c9a194 | ||
|
|
d43a814385 | ||
|
|
e46e7002a8 | ||
|
|
e6d20877b8 | ||
|
|
5ef8199dae | ||
|
|
e86e666c22 | ||
|
|
cf180f6142 | ||
|
|
67665a8b9d | ||
|
|
a50e555515 | ||
|
|
75b97cafb0 | ||
|
|
037cd74e8e | ||
|
|
82a81cd01f | ||
|
|
655290b022 | ||
|
|
b886a40471 | ||
|
|
c0d80a5828 | ||
|
|
adecd2960e | ||
|
|
9afecaaffe | ||
|
|
2af8105b46 | ||
|
|
4528becf4c | ||
|
|
d2a7f83bb5 | ||
|
|
b8b50bdb5a | ||
|
|
4485142a25 | ||
|
|
2a6afeb9a7 | ||
|
|
e2245446a3 | ||
|
|
08a9553ccc | ||
|
|
0a3fbdd128 | ||
|
|
cfbd2fc85c | ||
|
|
dd6718c2cd | ||
|
|
c1a24d44a3 | ||
|
|
bf438f67e1 | ||
|
|
81f6511d34 | ||
|
|
a6012af00d | ||
|
|
a0d339f208 | ||
|
|
2c7ce20ccf | ||
|
|
4bc4fd5b7e | ||
|
|
a92241d3cf | ||
|
|
344c293424 | ||
|
|
71cd6ef24b | ||
|
|
9b87a249b9 | ||
|
|
b84f7cd37f | ||
|
|
b5d8443f59 | ||
|
|
c08f428b5e | ||
|
|
20a79c7acf | ||
|
|
a4474b49cb | ||
|
|
0333dca550 | ||
|
|
af4352adf2 | ||
|
|
1877df0e70 | ||
|
|
a7e5e3d574 | ||
|
|
e81ac9e063 | ||
|
|
624f4641e2 | ||
|
|
dcba30a6aa | ||
|
|
25aded6b9b | ||
|
|
8d6c2b5d4a | ||
|
|
29a0a11b7e | ||
|
|
7582802f03 | ||
|
|
f8949ed5d1 | ||
|
|
7ae376b6cd | ||
|
|
390ce207db | ||
|
|
b93e398674 | ||
|
|
b70c680964 | ||
|
|
f9075e2a2f | ||
|
|
e596bf025b | ||
|
|
4a3ec65409 | ||
|
|
0f1fcd9743 | ||
|
|
f23bdde464 | ||
|
|
05d9e1bee5 | ||
|
|
a9d7acda27 | ||
|
|
b4eb9f2a11 | ||
|
|
c1039977f1 | ||
|
|
b1259876bf | ||
|
|
dfb6255f59 | ||
|
|
00b4843425 | ||
|
|
701acf59e2 | ||
|
|
380f65d309 | ||
|
|
316fee93f7 | ||
|
|
ca78374f30 | ||
|
|
670e83b300 | ||
|
|
44d3dadb03 | ||
|
|
9e9f2e13fe | ||
|
|
6602ff83dd | ||
|
|
8d284bab47 | ||
|
|
490ab9e2c5 | ||
|
|
0757dbf07f | ||
|
|
f35609d26c | ||
|
|
82ec40dd80 | ||
|
|
a52cdcb241 | ||
|
|
d1efb59fcd | ||
|
|
1523e116b9 | ||
|
|
90f2959076 | ||
|
|
6d4adfcedc | ||
|
|
f2ebe41a50 | ||
|
|
8f0c3f0e9b | ||
|
|
3b2679db29 | ||
|
|
4b350b9090 | ||
|
|
a3dfdd9d38 | ||
|
|
00d32f6b94 | ||
|
|
fad27fc1e7 | ||
|
|
3e6af5c876 | ||
|
|
75b169f391 | ||
|
|
df7772e301 | ||
|
|
63a97ff6fc | ||
|
|
cac6cef495 | ||
|
|
aab9766c53 | ||
|
|
ab54bf5149 | ||
|
|
55b587002e | ||
|
|
819683a073 | ||
|
|
7393dccde8 | ||
|
|
66effbfe08 | ||
|
|
ae94e8a855 | ||
|
|
f884fa6678 | ||
|
|
ac4688eac0 | ||
|
|
4691c3ec01 | ||
|
|
ca78ebce6d | ||
|
|
97e6b7c4ba | ||
|
|
ab6eb1c4b2 | ||
|
|
0919c1eb61 | ||
|
|
d554681174 | ||
|
|
551cf8ee94 | ||
|
|
61304d80d2 | ||
|
|
1bce285eca | ||
|
|
096fdfc61b | ||
|
|
8e4889bdf1 | ||
|
|
7b91e551c4 | ||
|
|
9d7abd58ac | ||
|
|
24360fd191 | ||
|
|
9017dcd0fd | ||
|
|
30d0f21079 | ||
|
|
d78bc12cbe | ||
|
|
2a9c1db0c9 | ||
|
|
4716627453 | ||
|
|
2f64684299 | ||
|
|
66b6f8c0ff | ||
|
|
e559f8b6a1 | ||
|
|
0d8dcdbbc9 | ||
|
|
da19ac98dd | ||
|
|
45568bf097 | ||
|
|
9908a7193a | ||
|
|
929d33fb22 | ||
|
|
a3e617987f | ||
|
|
c37eaff263 | ||
|
|
80f2ba640e | ||
|
|
f9a295a236 | ||
|
|
516c43ba15 | ||
|
|
84ba6393ad | ||
|
|
e00b8a7082 | ||
|
|
29ba891809 | ||
|
|
25357b208a | ||
|
|
80b422bdbe | ||
|
|
1215638540 | ||
|
|
bbc71343bd | ||
|
|
a1aa3d9061 | ||
|
|
1aa3051e97 | ||
|
|
20f444f5f2 | ||
|
|
2d06663490 | ||
|
|
5e0698ba87 | ||
|
|
d7d347469c | ||
|
|
de006771c7 | ||
|
|
b4e5d303b5 | ||
|
|
a36bef7979 | ||
|
|
2fdd148598 | ||
|
|
3dc131757d | ||
|
|
1cb311cef9 | ||
|
|
ed56b6e67b | ||
|
|
049147a9d7 | ||
|
|
5c1f23b61a | ||
|
|
4d4e49f4d8 | ||
|
|
5f2baa59f5 | ||
|
|
c6aa42773a | ||
|
|
7a526fa8a9 | ||
|
|
598baa1b32 | ||
|
|
ef9b42aeb3 | ||
|
|
4979a45120 | ||
|
|
b66bacff9f | ||
|
|
9480e9b68b | ||
|
|
bf05012150 | ||
|
|
d8ace38041 | ||
|
|
bc20cf9fa3 | ||
|
|
019250eff8 | ||
|
|
ac095c89f1 | ||
|
|
f4da365abd | ||
|
|
b2f0d2d085 | ||
|
|
aefeda8c41 | ||
|
|
fdece3b102 | ||
|
|
cae380f068 | ||
|
|
3aa6e96904 | ||
|
|
a97e7b2758 | ||
|
|
2cda18f354 | ||
|
|
2e83c17e2d | ||
|
|
f228bf4555 | ||
|
|
a2cec8899a | ||
|
|
014168a29b | ||
|
|
39bc0664a7 | ||
|
|
853322e7d2 | ||
|
|
9cb1ac3de5 | ||
|
|
5b2474238e | ||
|
|
3c5cb15432 | ||
|
|
6e7d7c5017 | ||
|
|
1f2bd00d93 | ||
|
|
c7cad6ab60 | ||
|
|
0f5eb65210 | ||
|
|
fc239cb8a2 | ||
|
|
3fe7bd8bcc | ||
|
|
6b69184554 | ||
|
|
d5ca889cf5 | ||
|
|
062cb77539 | ||
|
|
b55e2776cc | ||
|
|
50d1d06b03 | ||
|
|
93a7df5a1b | ||
|
|
905432c7ae | ||
|
|
3355210878 | ||
|
|
ada26dd2cb | ||
|
|
f4b31dcb3a | ||
|
|
7abb214eaf | ||
|
|
77eb9bcfa0 | ||
|
|
c17b47518d | ||
|
|
1f7e6cae82 | ||
|
|
37d14f3a1d | ||
|
|
166d63ff60 | ||
|
|
d38851023e | ||
|
|
e35bd5d251 | ||
|
|
c77732b8ed | ||
|
|
16f79b70e4 | ||
|
|
43c2b22fca | ||
|
|
9a64c6b9f7 | ||
|
|
20cb4130d4 | ||
|
|
bfbe6c1660 | ||
|
|
51edd472c2 | ||
|
|
1977ab35c0 | ||
|
|
296957b5b5 | ||
|
|
0d04a1221a | ||
|
|
6ac6537f10 | ||
|
|
883b1ff513 | ||
|
|
de1527eba8 | ||
|
|
2dcedd6951 | ||
|
|
c8322e89c6 | ||
|
|
18a9831cd3 | ||
|
|
9f77180af8 | ||
|
|
0bd4939695 | ||
|
|
605c05fc8b | ||
|
|
fa3aed4e59 | ||
|
|
217db8f9b2 | ||
|
|
a0dd03ea0e | ||
|
|
894114bfbd | ||
|
|
90353d90dc | ||
|
|
c9ce5664d4 | ||
|
|
e8ad16cf2a | ||
|
|
c3090d5480 | ||
|
|
f48aee5975 | ||
|
|
60f6b827f4 | ||
|
|
f05b4637b9 | ||
|
|
fffeca59d0 | ||
|
|
b14dd0e066 | ||
|
|
ec81ef7b8d | ||
|
|
e02c658eb5 | ||
|
|
0800bd1e19 | ||
|
|
0503b11840 | ||
|
|
b497faee27 | ||
|
|
7ee31276f5 | ||
|
|
5897f62fa9 | ||
|
|
0baab50191 | ||
|
|
0db1594f95 | ||
|
|
1e00fa79b3 | ||
|
|
573dea42d0 | ||
|
|
269055e71c | ||
|
|
2f222546da | ||
|
|
522fec5763 | ||
|
|
f2fc7d25c5 | ||
|
|
2d79e75788 | ||
|
|
781716277b | ||
|
|
9f57bfb5df | ||
|
|
4d00c48026 | ||
|
|
8fe8341d93 | ||
|
|
57273db8a6 | ||
|
|
bc9f88f3f9 | ||
|
|
70d413ab04 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -14,6 +14,8 @@
|
||||
*.rej
|
||||
# OSX .DS_Store files
|
||||
.DS_Store
|
||||
# version scripts (repo master only)
|
||||
.version*
|
||||
Thumbs.db
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
142
CHANGELOG
142
CHANGELOG
@@ -1,3 +1,145 @@
|
||||
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
|
||||
Provide sort field and direction on all fields of account and channel administration tables
|
||||
Rename 'user' administration to account administration to reflect its true purpose
|
||||
'safemode' tool to quickly disable and re-enable addons during a hypothetical upgrade crisis
|
||||
Security:
|
||||
Edited comments to private posts could lose their privacy settings under some circumstances
|
||||
Provide zot-finger signatures to prevent a possible but rare exploit involving DNS spoofing and phishing
|
||||
ACL selections:
|
||||
Various improvements to the ACL editor to further simplify the concepts and make it more intuitive
|
||||
Chat:
|
||||
Notifications of chatroom activity using standard browser notification interfaces.
|
||||
Themes:
|
||||
Allow a theme:schema string to represent a valid theme name. This fixes issues with setting schemas on site themes.
|
||||
Pubsites:
|
||||
Show server role (identify UNO or basic sites as opposed to hubzilla pro) and link to statistics
|
||||
Documentation:
|
||||
Clarify privacy rights of commenters w/r/t conversation owners, as this policy is network dependent.
|
||||
Wiki (Git backed):
|
||||
Brand new feature. We'll call it experimental until it has undergone a bit more testing.
|
||||
Account Cloning:
|
||||
Regression on clone channel creation created a new channel name each time.
|
||||
New issue (fixed) with directory creation on cloned file content
|
||||
Content Rendering:
|
||||
Add inline code (in addition to the existing code blocks) to BBcode
|
||||
Add emoji reactions
|
||||
Add emojis as extended smilies with auto-complete support
|
||||
Emoji added as feature so it can be enabled/disabled and locked
|
||||
Ability to configure the standard reactions available on a site basis
|
||||
Disable 'convenience' ajax autoload on pgdn key, as it could lead to premature memory exhaustion
|
||||
Photos:
|
||||
Change album sort ordering, allow widgets and plugins to define other orderings
|
||||
Apps:
|
||||
Synchronise app list with changes to system apps
|
||||
Preserve existing app categories on app updates/edits
|
||||
Regression: fixed translated system app names
|
||||
Architecture:
|
||||
Provide autoloaded class files and libraries for plugins.
|
||||
Further refactoring of session driver to sort out some cookie anomolies
|
||||
Experimental PDO database driver
|
||||
Creation of Daemon Master class and port all daemon (background task) interfaces to use it
|
||||
Create separate class for each of 'Cron', 'Cron daily', and 'Cron weekly'.
|
||||
Always run a Cron maintenance task if not run in the last four hours
|
||||
Refactor the template classes
|
||||
Refactor the ConversationItem mess into ThreadItem and ThreadStream
|
||||
Refactor Apps, Enotify, and Chat library code
|
||||
Refactor the various Config libraries (Config, PConfig, XConfig, AConfig, AbConfig, and IConfig)
|
||||
Created WebServer class for top level
|
||||
Remove mcrypt dependencies (deprecated in PHP 7.1)
|
||||
Remove all reserved (including merely 'not recommended') words as DB table column names
|
||||
Provide mutex lock on DB logging to prevent recursion under rare failure modes.
|
||||
Bugfixes:
|
||||
Remove db_close function on page end - not needed and will not work with persistent DB connections.
|
||||
Undefined ref_session_write
|
||||
Some session functions needed to be static to work with CalDAV/CardDAV
|
||||
CLI interface: argc and argv were reversed
|
||||
HTML entities double encoded in edited titles
|
||||
Prevent delivering to empty recipients
|
||||
Sabre library setting some security headers for SAML after we've emitted HTML content
|
||||
Always initialise miniApp (caused obscure warning message if not set)
|
||||
Block 'sys' channels from being 'random profile' candidates
|
||||
DB update failed email could be sent in the wrong language under rare circumstances
|
||||
Openid remote authentication used incorrect namespace
|
||||
URL attached to profile "things" was not linked, always showing the "thing" manage page
|
||||
New connection wasn't added to default privacy group when "auto-accept" was enabled
|
||||
Regression: iconfig sharing wasn't working properly
|
||||
Plugins:
|
||||
CalDAV/CardDAV plugin provided
|
||||
Issue sending Diaspora 'like' activities from sources that did not propagate the DCV
|
||||
Allow 'superblock' to work across API calls from third party clients
|
||||
statistics.json: use 'zot' as protocol
|
||||
Issues fixed during testing of ability to follow Diaspora tags
|
||||
Parse issue with Diaspora reshare content
|
||||
Chess: moved to main repo, ported to 1.8
|
||||
|
||||
Hubzilla 1.6
|
||||
Cleanup and standardise the interfaces to the "jot" editor
|
||||
Router re-written to support calling class object methods as controllers
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2010-2016 Hubzilla
|
||||
Copyright (c) 2010-2016 the Hubzilla Community
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
||||
19
README.md
19
README.md
@@ -3,8 +3,11 @@
|
||||
Hubzilla - Community Server
|
||||
===========================
|
||||
|
||||
Connected and linked web communities.
|
||||
-------------------------------------
|
||||
Groupware re-imagined and re-invented.
|
||||
--------------------------------------
|
||||
|
||||
Connect and link decentralised web communities.
|
||||
-----------------------------------------------
|
||||
|
||||
<p align="center" markdown="1">
|
||||
<em><a href="https://github.com/redmatrix/hubzilla/blob/master/install/INSTALL.txt">Installing Hubzilla</a></em>
|
||||
@@ -44,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;
|
||||
}
|
||||
}
|
||||
55
Zotlabs/Daemon/Checksites.php
Normal file
55
Zotlabs/Daemon/Checksites.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/hubloc.php');
|
||||
|
||||
|
||||
class Checksites {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
logger('checksites: start');
|
||||
|
||||
if(($argc > 1) && ($argv[1]))
|
||||
$site_id = $argv[1];
|
||||
|
||||
if($site_id)
|
||||
$sql_options = " and site_url = '" . dbesc($argv[1]) . "' ";
|
||||
|
||||
$days = intval(get_config('system','sitecheckdays'));
|
||||
if($days < 1)
|
||||
$days = 30;
|
||||
|
||||
$r = q("select * from site where site_dead = 0 and site_update < %s - INTERVAL %s and site_type = %d $sql_options ",
|
||||
db_utcnow(), db_quoteinterval($days . ' DAY'),
|
||||
intval(SITE_TYPE_ZOT)
|
||||
);
|
||||
|
||||
if(! $r)
|
||||
return;
|
||||
|
||||
foreach($r as $rr) {
|
||||
if(! strcasecmp($rr['site_url'],z_root()))
|
||||
continue;
|
||||
|
||||
$x = ping_site($rr['site_url']);
|
||||
if($x['success']) {
|
||||
logger('checksites: ' . $rr['site_url']);
|
||||
q("update site set site_update = '%s' where site_url = '%s' ",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($rr['site_url'])
|
||||
);
|
||||
}
|
||||
else {
|
||||
logger('marking dead site: ' . $x['message']);
|
||||
q("update site set site_dead = 1 where site_url = '%s' ",
|
||||
dbesc($rr['site_url'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
14
Zotlabs/Daemon/Cli_suggest.php
Normal file
14
Zotlabs/Daemon/Cli_suggest.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/socgraph.php');
|
||||
|
||||
class Cli_suggest {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
update_suggestions();
|
||||
|
||||
}
|
||||
}
|
||||
205
Zotlabs/Daemon/Cron.php
Normal file
205
Zotlabs/Daemon/Cron.php
Normal file
@@ -0,0 +1,205 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
class Cron {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
$maxsysload = intval(get_config('system','maxloadavg'));
|
||||
if($maxsysload < 1)
|
||||
$maxsysload = 50;
|
||||
if(function_exists('sys_getloadavg')) {
|
||||
$load = sys_getloadavg();
|
||||
if(intval($load[0]) > $maxsysload) {
|
||||
logger('system: load ' . $load . ' too high. Cron deferred to next scheduled run.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for a lockfile. If it exists, but is over an hour old, it's stale. Ignore it.
|
||||
$lockfile = 'store/[data]/cron';
|
||||
if((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 3600))
|
||||
&& (! get_config('system','override_cron_lockfile'))) {
|
||||
logger("cron: Already running");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a lockfile. Needs two vars, but $x doesn't need to contain anything.
|
||||
file_put_contents($lockfile, $x);
|
||||
|
||||
logger('cron: start');
|
||||
|
||||
// run queue delivery process in the background
|
||||
|
||||
Master::Summon(array('Queue'));
|
||||
|
||||
Master::Summon(array('Poller'));
|
||||
|
||||
// maintenance for mod sharedwithme - check for updated items and remove them
|
||||
|
||||
require_once('include/sharedwithme.php');
|
||||
apply_updates();
|
||||
|
||||
// expire any expired mail
|
||||
|
||||
q("delete from mail where expires != '%s' and expires < %s ",
|
||||
dbesc(NULL_DATE),
|
||||
db_utcnow()
|
||||
);
|
||||
|
||||
// expire any expired items
|
||||
|
||||
$r = q("select id from item where expires != '%s' and expires < %s
|
||||
and item_deleted = 0 ",
|
||||
dbesc(NULL_DATE),
|
||||
db_utcnow()
|
||||
);
|
||||
if($r) {
|
||||
require_once('include/items.php');
|
||||
foreach($r as $rr)
|
||||
drop_item($rr['id'],false);
|
||||
}
|
||||
|
||||
|
||||
// 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.
|
||||
|
||||
$r = q("select channel_id from channel where channel_dirdate < %s - INTERVAL %s",
|
||||
db_utcnow(),
|
||||
db_quoteinterval('30 DAY')
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
Master::Summon(array('Directory',$rr['channel_id'],'force'));
|
||||
if($interval)
|
||||
@time_sleep_until(microtime(true) + (float) $interval);
|
||||
}
|
||||
}
|
||||
|
||||
// publish any applicable items that were set to be published in the future
|
||||
// (time travel posts). Restrict to items that have come of age in the last
|
||||
// couple of days to limit the query to something reasonable.
|
||||
|
||||
$r = q("select id from item where item_delayed = 1 and created <= %s and created > '%s' ",
|
||||
db_utcnow(),
|
||||
dbesc(datetime_convert('UTC','UTC','now - 2 days'))
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$x = q("update item set item_delayed = 0 where id = %d",
|
||||
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']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$abandon_days = intval(get_config('system','account_abandon_days'));
|
||||
if($abandon_days < 1)
|
||||
$abandon_days = 0;
|
||||
|
||||
|
||||
// once daily run birthday_updates and then expire in background
|
||||
|
||||
// FIXME: add birthday updates, both locally and for xprof for use
|
||||
// by directory servers
|
||||
|
||||
$d1 = intval(get_config('system','last_expire_day'));
|
||||
$d2 = intval(datetime_convert('UTC','UTC','now','d'));
|
||||
|
||||
// Allow somebody to staggger daily activities if they have more than one site on their server,
|
||||
// or if it happens at an inconvenient (busy) hour.
|
||||
|
||||
$h1 = intval(get_config('system','cron_hour'));
|
||||
$h2 = intval(datetime_convert('UTC','UTC','now','G'));
|
||||
|
||||
|
||||
if(($d2 != $d1) && ($h1 == $h2)) {
|
||||
Master::Summon(array('Cron_daily'));
|
||||
}
|
||||
|
||||
// update any photos which didn't get imported properly
|
||||
// This should be rare
|
||||
|
||||
$r = q("select xchan_photo_l, xchan_hash from xchan where xchan_photo_l != '' and xchan_photo_m = ''
|
||||
and xchan_photo_date < %s - INTERVAL %s",
|
||||
db_utcnow(),
|
||||
db_quoteinterval('1 DAY')
|
||||
);
|
||||
if($r) {
|
||||
require_once('include/photo/photo_driver.php');
|
||||
foreach($r as $rr) {
|
||||
$photos = import_xchan_photo($rr['xchan_photo_l'],$rr['xchan_hash']);
|
||||
$x = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s'
|
||||
where xchan_hash = '%s'",
|
||||
dbesc($photos[0]),
|
||||
dbesc($photos[1]),
|
||||
dbesc($photos[2]),
|
||||
dbesc($photos[3]),
|
||||
dbesc($rr['xchan_hash'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// pull in some public posts
|
||||
|
||||
if(! get_config('system','disable_discover_tab'))
|
||||
Master::Summon(array('Externals'));
|
||||
|
||||
$generation = 0;
|
||||
|
||||
$restart = false;
|
||||
|
||||
if(($argc > 1) && ($argv[1] == 'restart')) {
|
||||
$restart = true;
|
||||
$generation = intval($argv[2]);
|
||||
if(! $generation)
|
||||
killme();
|
||||
}
|
||||
|
||||
reload_plugins();
|
||||
|
||||
$d = datetime_convert();
|
||||
|
||||
// TODO check to see if there are any cronhooks before wasting a process
|
||||
|
||||
if(! $restart)
|
||||
Master::Summon(array('Cronhooks'));
|
||||
|
||||
set_config('system','lastcron',datetime_convert());
|
||||
|
||||
//All done - clear the lockfile
|
||||
@unlink($lockfile);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
90
Zotlabs/Daemon/Cron_daily.php
Normal file
90
Zotlabs/Daemon/Cron_daily.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
class Cron_daily {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
logger('cron_daily: start');
|
||||
|
||||
/**
|
||||
* Cron Daily
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
require_once('include/dir_fns.php');
|
||||
check_upstream_directory();
|
||||
|
||||
|
||||
// Fire off the Cron_weekly process if it's the correct day.
|
||||
|
||||
$d3 = intval(datetime_convert('UTC','UTC','now','N'));
|
||||
if($d3 == 7) {
|
||||
Master::Summon(array('Cron_weekly'));
|
||||
}
|
||||
|
||||
// once daily run birthday_updates and then expire in background
|
||||
|
||||
// FIXME: add birthday updates, both locally and for xprof for use
|
||||
// by directory servers
|
||||
|
||||
update_birthdays();
|
||||
|
||||
// expire any read notifications over a month old
|
||||
|
||||
q("delete from notify where seen = 1 and created < %s - INTERVAL %s",
|
||||
db_utcnow(), db_quoteinterval('30 DAY')
|
||||
);
|
||||
|
||||
//update statistics in config
|
||||
require_once('include/statistics_fns.php');
|
||||
update_channels_total_stat();
|
||||
update_channels_active_halfyear_stat();
|
||||
update_channels_active_monthly_stat();
|
||||
update_local_posts_stat();
|
||||
|
||||
|
||||
// expire old delivery reports
|
||||
|
||||
$keep_reports = intval(get_config('system','expire_delivery_reports'));
|
||||
if($keep_reports === 0)
|
||||
$keep_reports = 10;
|
||||
|
||||
q("delete from dreport where dreport_time < %s - INTERVAL %s",
|
||||
db_utcnow(),
|
||||
db_quoteinterval($keep_reports . ' DAY')
|
||||
);
|
||||
|
||||
// expire any expired accounts
|
||||
downgrade_accounts();
|
||||
|
||||
// If this is a directory server, request a sync with an upstream
|
||||
// directory at least once a day, up to once every poll interval.
|
||||
// Pull remote changes and push local changes.
|
||||
// potential issue: how do we keep from creating an endless update loop?
|
||||
|
||||
$dirmode = get_config('system','directory_mode');
|
||||
|
||||
if($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) {
|
||||
require_once('include/dir_fns.php');
|
||||
sync_directories($dirmode);
|
||||
}
|
||||
|
||||
|
||||
Master::Summon(array('Expire'));
|
||||
Master::Summon(array('Cli_suggest'));
|
||||
|
||||
require_once('include/hubloc.php');
|
||||
remove_obsolete_hublocs();
|
||||
|
||||
call_hooks('cron_daily',datetime_convert());
|
||||
|
||||
set_config('system','last_expire_day',$d2);
|
||||
|
||||
/**
|
||||
* End Cron Daily
|
||||
*/
|
||||
}
|
||||
}
|
||||
48
Zotlabs/Daemon/Cron_weekly.php
Normal file
48
Zotlabs/Daemon/Cron_weekly.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
class Cron_weekly {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
/**
|
||||
* Cron Weekly
|
||||
*
|
||||
* Actions in the following block are executed once per day only on Sunday (once per week).
|
||||
*
|
||||
*/
|
||||
|
||||
call_hooks('cron_weekly',datetime_convert());
|
||||
|
||||
z_check_cert();
|
||||
|
||||
require_once('include/hubloc.php');
|
||||
prune_hub_reinstalls();
|
||||
|
||||
mark_orphan_hubsxchans();
|
||||
|
||||
|
||||
// get rid of really old poco records
|
||||
|
||||
q("delete from xlink where xlink_updated < %s - INTERVAL %s and xlink_static = 0 ",
|
||||
db_utcnow(), db_quoteinterval('14 DAY')
|
||||
);
|
||||
|
||||
$dirmode = intval(get_config('system','directory_mode'));
|
||||
if($dirmode === DIRECTORY_MODE_SECONDARY || $dirmode === DIRECTORY_MODE_PRIMARY) {
|
||||
logger('regdir: ' . print_r(z_fetch_url(get_directory_primary() . '/regdir?f=&url=' . urlencode(z_root()) . '&realm=' . urlencode(get_directory_realm())),true));
|
||||
}
|
||||
|
||||
// Check for dead sites
|
||||
Master::Summon(array('Checksites'));
|
||||
|
||||
// update searchable doc indexes
|
||||
Master::Summon(array('Importdoc'));
|
||||
|
||||
/**
|
||||
* End Cron Weekly
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
17
Zotlabs/Daemon/Cronhooks.php
Normal file
17
Zotlabs/Daemon/Cronhooks.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
class Cronhooks {
|
||||
|
||||
static public function run($argc,$argv){
|
||||
|
||||
logger('cronhooks: start');
|
||||
|
||||
$d = datetime_convert();
|
||||
|
||||
call_hooks('cron', $d);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
85
Zotlabs/Daemon/Deliver.php
Normal file
85
Zotlabs/Daemon/Deliver.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/queue_fn.php');
|
||||
|
||||
|
||||
class Deliver {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
if($argc < 2)
|
||||
return;
|
||||
|
||||
logger('deliver: invoked: ' . print_r($argv,true), LOGGER_DATA);
|
||||
|
||||
for($x = 1; $x < $argc; $x ++) {
|
||||
|
||||
if(! $argv[$x])
|
||||
continue;
|
||||
|
||||
$dresult = null;
|
||||
$r = q("select * from outq where outq_hash = '%s' limit 1",
|
||||
dbesc($argv[$x])
|
||||
);
|
||||
if($r) {
|
||||
|
||||
$notify = json_decode($r[0]['outq_notify'],true);
|
||||
|
||||
// Messages without an outq_msg will need to go via the web, even if it's a
|
||||
// local delivery. This includes conversation requests and refresh packets.
|
||||
|
||||
if(($r[0]['outq_posturl'] === z_root() . '/post') && ($r[0]['outq_msg'])) {
|
||||
logger('deliver: local delivery', LOGGER_DEBUG);
|
||||
|
||||
// local delivery
|
||||
// we should probably batch these and save a few delivery processes
|
||||
|
||||
if($r[0]['outq_msg']) {
|
||||
$m = json_decode($r[0]['outq_msg'],true);
|
||||
if(array_key_exists('message_list',$m)) {
|
||||
foreach($m['message_list'] as $mm) {
|
||||
$msg = array('body' => json_encode(array('success' => true, 'pickup' => array(array('notify' => $notify,'message' => $mm)))));
|
||||
zot_import($msg,z_root());
|
||||
}
|
||||
}
|
||||
else {
|
||||
$msg = array('body' => json_encode(array('success' => true, 'pickup' => array(array('notify' => $notify,'message' => $m)))));
|
||||
$dresult = zot_import($msg,z_root());
|
||||
}
|
||||
|
||||
remove_queue_item($r[0]['outq_hash']);
|
||||
|
||||
if($dresult && is_array($dresult)) {
|
||||
foreach($dresult as $xx) {
|
||||
if(is_array($xx) && array_key_exists('message_id',$xx)) {
|
||||
if(delivery_report_is_storable($xx)) {
|
||||
q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan ) values ( '%s', '%s','%s','%s','%s','%s' ) ",
|
||||
dbesc($xx['message_id']),
|
||||
dbesc($xx['location']),
|
||||
dbesc($xx['recipient']),
|
||||
dbesc($xx['status']),
|
||||
dbesc(datetime_convert($xx['date'])),
|
||||
dbesc($xx['sender'])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
q("delete from dreport where dreport_queue = '%s'",
|
||||
dbesc($argv[$x])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise it's a remote delivery - call queue_deliver() with the $immediate flag
|
||||
|
||||
queue_deliver($r[0],true);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
Zotlabs/Daemon/Deliver_hooks.php
Normal file
24
Zotlabs/Daemon/Deliver_hooks.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/zot.php');
|
||||
|
||||
class Deliver_hooks {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
if($argc < 2)
|
||||
return;
|
||||
|
||||
|
||||
$r = q("select * from item where id = '%d'",
|
||||
intval($argv[1])
|
||||
);
|
||||
if($r)
|
||||
call_hooks('notifier_normal',$r[0]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
100
Zotlabs/Daemon/Directory.php
Normal file
100
Zotlabs/Daemon/Directory.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/dir_fns.php');
|
||||
require_once('include/queue_fn.php');
|
||||
|
||||
|
||||
class Directory {
|
||||
|
||||
static public function run($argc,$argv){
|
||||
|
||||
if($argc < 2)
|
||||
return;
|
||||
|
||||
$force = false;
|
||||
$pushall = true;
|
||||
|
||||
if($argc > 2) {
|
||||
if($argv[2] === 'force')
|
||||
$force = true;
|
||||
if($argv[2] === 'nopush')
|
||||
$pushall = false;
|
||||
}
|
||||
|
||||
logger('directory update', LOGGER_DEBUG);
|
||||
|
||||
$dirmode = get_config('system','directory_mode');
|
||||
if($dirmode === false)
|
||||
$dirmode = DIRECTORY_MODE_NORMAL;
|
||||
|
||||
$x = q("select * from channel where channel_id = %d limit 1",
|
||||
intval($argv[1])
|
||||
);
|
||||
if(! $x)
|
||||
return;
|
||||
|
||||
$channel = $x[0];
|
||||
|
||||
if($dirmode != DIRECTORY_MODE_NORMAL) {
|
||||
|
||||
// this is an in-memory update and we don't need to send a network packet.
|
||||
|
||||
local_dir_update($argv[1],$force);
|
||||
|
||||
q("update channel set channel_dirdate = '%s' where channel_id = %d",
|
||||
dbesc(datetime_convert()),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
// Now update all the connections
|
||||
if($pushall)
|
||||
Master::Summon(array('Notifier','refresh_all',$channel['channel_id']));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise send the changes upstream
|
||||
|
||||
$directory = find_upstream_directory($dirmode);
|
||||
$url = $directory['url'] . '/post';
|
||||
|
||||
// ensure the upstream directory is updated
|
||||
|
||||
$packet = zot_build_packet($channel,(($force) ? 'force_refresh' : 'refresh'));
|
||||
$z = zot_zot($url,$packet);
|
||||
|
||||
// re-queue if unsuccessful
|
||||
|
||||
if(! $z['success']) {
|
||||
|
||||
/** @FIXME we aren't updating channel_dirdate if we have to queue
|
||||
* the directory packet. That means we'll try again on the next poll run.
|
||||
*/
|
||||
|
||||
$hash = random_string();
|
||||
|
||||
queue_insert(array(
|
||||
'hash' => $hash,
|
||||
'account_id' => $channel['channel_account_id'],
|
||||
'channel_id' => $channel['channel_id'],
|
||||
'posturl' => $url,
|
||||
'notify' => $packet,
|
||||
));
|
||||
|
||||
}
|
||||
else {
|
||||
q("update channel set channel_dirdate = '%s' where channel_id = %d",
|
||||
dbesc(datetime_convert()),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
}
|
||||
|
||||
// Now update all the connections
|
||||
if($pushall)
|
||||
Master::Summon(array('Notifier','refresh_all',$channel['channel_id']));
|
||||
|
||||
}
|
||||
}
|
||||
93
Zotlabs/Daemon/Expire.php
Normal file
93
Zotlabs/Daemon/Expire.php
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
|
||||
class Expire {
|
||||
|
||||
static public function run($argc,$argv){
|
||||
|
||||
cli_startup();
|
||||
|
||||
// perform final cleanup on previously delete items
|
||||
|
||||
$r = q("select id from item where item_deleted = 1 and item_pending_remove = 0 and changed < %s - INTERVAL %s",
|
||||
db_utcnow(), db_quoteinterval('10 DAY')
|
||||
);
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
drop_item($rr['id'], false, DROPITEM_PHASE2);
|
||||
}
|
||||
}
|
||||
|
||||
// physically remove anything that has been deleted for more than two months
|
||||
/** @FIXME - this is a wretchedly inefficient query */
|
||||
|
||||
$r = q("delete from item where item_pending_remove = 1 and changed < %s - INTERVAL %s",
|
||||
db_utcnow(), db_quoteinterval('36 DAY')
|
||||
);
|
||||
|
||||
/** @FIXME make this optional as it could have a performance impact on large sites */
|
||||
|
||||
if (intval(get_config('system', 'optimize_items')))
|
||||
q("optimize table item");
|
||||
|
||||
logger('expire: start', LOGGER_DEBUG);
|
||||
|
||||
$site_expire = get_config('system', 'default_expire_days');
|
||||
|
||||
logger('site_expire: ' . $site_expire);
|
||||
|
||||
$r = q("SELECT channel_id, channel_system, channel_address, channel_expire_days from channel where true");
|
||||
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
|
||||
// expire the sys channel separately
|
||||
if (intval($rr['channel_system']))
|
||||
continue;
|
||||
|
||||
// service class default (if non-zero) over-rides the site default
|
||||
|
||||
$service_class_expire = service_class_fetch($rr['channel_id'], 'expire_days');
|
||||
if (intval($service_class_expire))
|
||||
$channel_expire = $service_class_expire;
|
||||
else
|
||||
$channel_expire = $site_expire;
|
||||
|
||||
if (intval($channel_expire) && (intval($channel_expire) < intval($rr['channel_expire_days'])) ||
|
||||
intval($rr['channel_expire_days'] == 0)) {
|
||||
$expire_days = $channel_expire;
|
||||
} else {
|
||||
$expire_days = $rr['channel_expire_days'];
|
||||
}
|
||||
|
||||
// if the site or service class expiration is non-zero and less than person expiration, use that
|
||||
logger('Expire: ' . $rr['channel_address'] . ' interval: ' . $expire_days, LOGGER_DEBUG);
|
||||
item_expire($rr['channel_id'], $expire_days);
|
||||
}
|
||||
}
|
||||
|
||||
$x = get_sys_channel();
|
||||
if ($x) {
|
||||
|
||||
// this should probably just fetch the channel_expire_days from the sys channel,
|
||||
// but there's no convenient way to set it.
|
||||
|
||||
$expire_days = get_config('system', 'sys_expire_days');
|
||||
if ($expire_days === false)
|
||||
$expire_days = 30;
|
||||
|
||||
if (intval($site_expire) && (intval($site_expire) < intval($expire_days))) {
|
||||
$expire_days = $site_expire;
|
||||
}
|
||||
|
||||
logger('Expire: sys interval: ' . $expire_days, LOGGER_DEBUG);
|
||||
|
||||
if ($expire_days)
|
||||
item_expire($x['channel_id'], $expire_days);
|
||||
|
||||
logger('Expire: sys: done', LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
98
Zotlabs/Daemon/Externals.php
Normal file
98
Zotlabs/Daemon/Externals.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/channel.php');
|
||||
|
||||
|
||||
class Externals {
|
||||
|
||||
static public function run($argc,$argv){
|
||||
|
||||
$total = 0;
|
||||
$attempts = 0;
|
||||
|
||||
logger('externals: startup', LOGGER_DEBUG);
|
||||
|
||||
// pull in some public posts
|
||||
|
||||
|
||||
while($total == 0 && $attempts < 3) {
|
||||
$arr = array('url' => '');
|
||||
call_hooks('externals_url_select',$arr);
|
||||
|
||||
if($arr['url']) {
|
||||
$url = $arr['url'];
|
||||
}
|
||||
else {
|
||||
$randfunc = db_getfunc('RAND');
|
||||
|
||||
// fixme this query does not deal with directory realms.
|
||||
|
||||
$r = q("select site_url, site_pull from site where site_url != '%s' and site_flags != %d and site_type = %d and site_dead = 0 order by $randfunc limit 1",
|
||||
dbesc(z_root()),
|
||||
intval(DIRECTORY_MODE_STANDALONE),
|
||||
intval(SITE_TYPE_ZOT)
|
||||
);
|
||||
if($r)
|
||||
$url = $r[0]['site_url'];
|
||||
}
|
||||
|
||||
$blacklisted = false;
|
||||
|
||||
if(! check_siteallowed($url)) {
|
||||
logger('blacklisted site: ' . $url);
|
||||
$blacklisted = true;
|
||||
}
|
||||
|
||||
$attempts ++;
|
||||
|
||||
// make sure we can eventually break out if somebody blacklists all known sites
|
||||
|
||||
if($blacklisted) {
|
||||
if($attempts > 20)
|
||||
break;
|
||||
$attempts --;
|
||||
continue;
|
||||
}
|
||||
|
||||
if($url) {
|
||||
if($r[0]['site_pull'] !== NULL_DATE)
|
||||
$mindate = urlencode(datetime_convert('','',$r[0]['site_pull'] . ' - 1 day'));
|
||||
else {
|
||||
$days = get_config('externals','since_days');
|
||||
if($days === false)
|
||||
$days = 15;
|
||||
$mindate = urlencode(datetime_convert('','','now - ' . intval($days) . ' days'));
|
||||
}
|
||||
|
||||
$feedurl = $url . '/zotfeed?f=&mindate=' . $mindate;
|
||||
|
||||
logger('externals: pulling public content from ' . $feedurl, LOGGER_DEBUG);
|
||||
|
||||
$x = z_fetch_url($feedurl);
|
||||
if(($x) && ($x['success'])) {
|
||||
|
||||
q("update site set site_pull = '%s' where site_url = '%s'",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($url)
|
||||
);
|
||||
|
||||
$j = json_decode($x['body'],true);
|
||||
if($j['success'] && $j['messages']) {
|
||||
$sys = get_sys_channel();
|
||||
foreach($j['messages'] as $message) {
|
||||
// on these posts, clear any route info.
|
||||
$message['route'] = '';
|
||||
$results = process_delivery(array('hash' => 'undefined'), get_item_elements($message),
|
||||
array(array('hash' => $sys['xchan_hash'])), false, true);
|
||||
$total ++;
|
||||
}
|
||||
logger('externals: import_public_posts: ' . $total . ' messages imported', LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
Zotlabs/Daemon/Gprobe.php
Normal file
33
Zotlabs/Daemon/Gprobe.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/zot.php');
|
||||
|
||||
// performs zot_finger on $argv[1], which is a hex_encoded webbie/reddress
|
||||
|
||||
class Gprobe {
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
if($argc != 2)
|
||||
return;
|
||||
|
||||
$url = hex2bin($argv[1]);
|
||||
|
||||
if(! strpos($url,'@'))
|
||||
return;
|
||||
|
||||
$r = q("select * from xchan where xchan_addr = '%s' limit 1",
|
||||
dbesc($url)
|
||||
);
|
||||
|
||||
if(! $r) {
|
||||
$j = \Zotlabs\Zot\Finger::run($url,null);
|
||||
if($j['success']) {
|
||||
$y = import_xchan($j);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
35
Zotlabs/Daemon/Importdoc.php
Executable file
35
Zotlabs/Daemon/Importdoc.php
Executable file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
|
||||
class Importdoc {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
require_once('include/help.php');
|
||||
|
||||
self::update_docs_dir('doc/*');
|
||||
|
||||
}
|
||||
|
||||
static public function update_docs_dir($s) {
|
||||
$f = basename($s);
|
||||
$d = dirname($s);
|
||||
if($s === 'doc/html')
|
||||
return;
|
||||
$files = glob("$d/$f");
|
||||
if($files) {
|
||||
foreach($files as $fi) {
|
||||
if($fi === 'doc/html')
|
||||
continue;
|
||||
if(is_dir($fi))
|
||||
self::update_docs_dir("$fi/*");
|
||||
else
|
||||
store_doc_file($fi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
31
Zotlabs/Daemon/Master.php
Normal file
31
Zotlabs/Daemon/Master.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
if(array_search( __file__ , get_included_files()) === 0) {
|
||||
|
||||
require_once('include/cli_startup.php');
|
||||
array_shift($argv);
|
||||
$argc = count($argv);
|
||||
|
||||
if($argc)
|
||||
Master::Release($argc,$argv);
|
||||
killme();
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Master {
|
||||
|
||||
static public function Summon($arr) {
|
||||
proc_run('php','Zotlabs/Daemon/Master.php',$arr);
|
||||
}
|
||||
|
||||
static public function Release($argc,$argv) {
|
||||
cli_startup();
|
||||
logger('Master: release: ' . print_r($argv,true), LOGGER_ALL,LOG_DEBUG);
|
||||
require_once('Zotlabs/Daemon/' . $argv[0] . '.php');
|
||||
$cls = '\\Zotlabs\\Daemon\\' . $argv[0];
|
||||
$cls::run($argc,$argv);
|
||||
}
|
||||
}
|
||||
663
Zotlabs/Daemon/Notifier.php
Normal file
663
Zotlabs/Daemon/Notifier.php
Normal file
@@ -0,0 +1,663 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/queue_fn.php');
|
||||
require_once('include/html2plain.php');
|
||||
|
||||
/*
|
||||
* This file was at one time responsible for doing all deliveries, but this caused
|
||||
* big problems on shared hosting systems, where the process might get killed by the
|
||||
* hosting provider and nothing would get delivered.
|
||||
* It now only delivers one message under certain cases, and invokes a queued
|
||||
* delivery mechanism (include/deliver.php) to deliver individual contacts at
|
||||
* controlled intervals.
|
||||
* This has a much better chance of surviving random processes getting killed
|
||||
* by the hosting provider.
|
||||
*
|
||||
* The basic flow is:
|
||||
* Identify the type of message
|
||||
* Collect any information that needs to be sent
|
||||
* Convert it into a suitable generic format for sending
|
||||
* Figure out who the recipients are and if we need to relay
|
||||
* through a conversation owner
|
||||
* Once we know what recipients are involved, collect a list of
|
||||
* destination sites
|
||||
* Build and store a queue item for each unique site and invoke
|
||||
* a delivery process for each site or a small number of sites (1-3)
|
||||
* and add a slight delay between each delivery invocation if desired (usually)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The notifier is typically called with:
|
||||
*
|
||||
* Zotlabs\Daemon\Master::Summon(array('Notifier', COMMAND, ITEM_ID));
|
||||
*
|
||||
* where COMMAND is one of the following:
|
||||
*
|
||||
* activity (in diaspora.php, dfrn_confirm.php, profiles.php)
|
||||
* comment-import (in diaspora.php, items.php)
|
||||
* comment-new (in item.php)
|
||||
* drop (in diaspora.php, items.php, photos.php)
|
||||
* edit_post (in item.php)
|
||||
* event (in events.php)
|
||||
* expire (in items.php)
|
||||
* like (in like.php, poke.php)
|
||||
* mail (in message.php)
|
||||
* tag (in photos.php, poke.php, tagger.php)
|
||||
* tgroup (in items.php)
|
||||
* wall-new (in photos.php, item.php)
|
||||
*
|
||||
* and ITEM_ID is the id of the item in the database that needs to be sent to others.
|
||||
*
|
||||
* ZOT
|
||||
* permission_create abook_id
|
||||
* permission_update abook_id
|
||||
* refresh_all channel_id
|
||||
* purge_all channel_id
|
||||
* expire channel_id
|
||||
* relay item_id (item was relayed to owner, we will deliver it as owner)
|
||||
* single_activity item_id (deliver to a singleton network from the appropriate clone)
|
||||
* single_mail mail_id (deliver to a singleton network from the appropriate clone)
|
||||
* location channel_id
|
||||
* request channel_id xchan_hash message_id
|
||||
* rating xlink_id
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/queue_fn.php');
|
||||
require_once('include/datetime.php');
|
||||
require_once('include/items.php');
|
||||
require_once('include/bbcode.php');
|
||||
require_once('include/channel.php');
|
||||
|
||||
|
||||
class Notifier {
|
||||
|
||||
static public function run($argc,$argv){
|
||||
|
||||
if($argc < 3)
|
||||
return;
|
||||
|
||||
logger('notifier: invoked: ' . print_r($argv,true), LOGGER_DEBUG);
|
||||
|
||||
$cmd = $argv[1];
|
||||
|
||||
$item_id = $argv[2];
|
||||
|
||||
$extra = (($argc > 3) ? $argv[3] : null);
|
||||
|
||||
if(! $item_id)
|
||||
return;
|
||||
|
||||
$sys = get_sys_channel();
|
||||
|
||||
$deliveries = array();
|
||||
|
||||
$dead_hubs = array();
|
||||
|
||||
$dh = q("select site_url from site where site_dead = 1");
|
||||
if($dh) {
|
||||
foreach($dh as $dead) {
|
||||
$dead_hubs[] = $dead['site_url'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$request = false;
|
||||
$mail = false;
|
||||
$top_level = false;
|
||||
$location = false;
|
||||
$recipients = array();
|
||||
$url_recipients = array();
|
||||
$normal_mode = true;
|
||||
$packet_type = 'undefined';
|
||||
|
||||
if($cmd === 'mail' || $cmd === 'single_mail') {
|
||||
$normal_mode = false;
|
||||
$mail = true;
|
||||
$private = true;
|
||||
$message = q("SELECT * FROM `mail` WHERE `id` = %d LIMIT 1",
|
||||
intval($item_id)
|
||||
);
|
||||
if(! $message) {
|
||||
return;
|
||||
}
|
||||
xchan_mail_query($message[0]);
|
||||
$uid = $message[0]['channel_id'];
|
||||
$recipients[] = $message[0]['from_xchan']; // include clones
|
||||
$recipients[] = $message[0]['to_xchan'];
|
||||
$item = $message[0];
|
||||
|
||||
$encoded_item = encode_mail($item);
|
||||
|
||||
$s = q("select * from channel where channel_id = %d limit 1",
|
||||
intval($item['channel_id'])
|
||||
);
|
||||
if($s)
|
||||
$channel = $s[0];
|
||||
|
||||
}
|
||||
elseif($cmd === 'request') {
|
||||
$channel_id = $item_id;
|
||||
$xchan = $argv[3];
|
||||
$request_message_id = $argv[4];
|
||||
|
||||
$s = q("select * from channel where channel_id = %d limit 1",
|
||||
intval($channel_id)
|
||||
);
|
||||
if($s)
|
||||
$channel = $s[0];
|
||||
|
||||
$private = true;
|
||||
$recipients[] = $xchan;
|
||||
$packet_type = 'request';
|
||||
$normal_mode = false;
|
||||
}
|
||||
elseif($cmd == 'permission_update' || $cmd == 'permission_create') {
|
||||
// Get the (single) recipient
|
||||
$r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_self = 0",
|
||||
intval($item_id)
|
||||
);
|
||||
if($r) {
|
||||
$uid = $r[0]['abook_channel'];
|
||||
// Get the sender
|
||||
$channel = channelx_by_n($uid);
|
||||
if($channel) {
|
||||
$perm_update = array('sender' => $channel, 'recipient' => $r[0], 'success' => false, 'deliveries' => '');
|
||||
|
||||
if($cmd == 'permission_create')
|
||||
call_hooks('permissions_create',$perm_update);
|
||||
else
|
||||
call_hooks('permissions_update',$perm_update);
|
||||
|
||||
if($perm_update['success']) {
|
||||
if($perm_update['deliveries']) {
|
||||
$deliveries[] = $perm_update['deliveries'];
|
||||
do_delivery($deliveries);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
$recipients[] = $r[0]['abook_xchan'];
|
||||
$private = false;
|
||||
$packet_type = 'refresh';
|
||||
$packet_recips = array(array('guid' => $r[0]['xchan_guid'],'guid_sig' => $r[0]['xchan_guid_sig'],'hash' => $r[0]['xchan_hash']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif($cmd === 'refresh_all') {
|
||||
logger('notifier: refresh_all: ' . $item_id);
|
||||
$uid = $item_id;
|
||||
$channel = channelx_by_n($item_id);
|
||||
$r = q("select abook_xchan from abook where abook_channel = %d",
|
||||
intval($item_id)
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$recipients[] = $rr['abook_xchan'];
|
||||
}
|
||||
}
|
||||
$private = false;
|
||||
$packet_type = 'refresh';
|
||||
}
|
||||
elseif($cmd === 'location') {
|
||||
logger('notifier: location: ' . $item_id);
|
||||
$s = q("select * from channel where channel_id = %d limit 1",
|
||||
intval($item_id)
|
||||
);
|
||||
if($s)
|
||||
$channel = $s[0];
|
||||
$uid = $item_id;
|
||||
$recipients = array();
|
||||
$r = q("select abook_xchan from abook where abook_channel = %d",
|
||||
intval($item_id)
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$recipients[] = $rr['abook_xchan'];
|
||||
}
|
||||
}
|
||||
|
||||
$encoded_item = array('locations' => zot_encode_locations($channel),'type' => 'location', 'encoding' => 'zot');
|
||||
$target_item = array('aid' => $channel['channel_account_id'],'uid' => $channel['channel_id']);
|
||||
$private = false;
|
||||
$packet_type = 'location';
|
||||
$location = true;
|
||||
}
|
||||
elseif($cmd === 'purge_all') {
|
||||
logger('notifier: purge_all: ' . $item_id);
|
||||
$s = q("select * from channel where channel_id = %d limit 1",
|
||||
intval($item_id)
|
||||
);
|
||||
if($s)
|
||||
$channel = $s[0];
|
||||
$uid = $item_id;
|
||||
$recipients = array();
|
||||
$r = q("select abook_xchan from abook where abook_channel = %d",
|
||||
intval($item_id)
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$recipients[] = $rr['abook_xchan'];
|
||||
}
|
||||
}
|
||||
$private = false;
|
||||
$packet_type = 'purge';
|
||||
}
|
||||
else {
|
||||
|
||||
// Normal items
|
||||
|
||||
// Fetch the target item
|
||||
|
||||
$r = q("SELECT * FROM item WHERE id = %d and parent != 0 LIMIT 1",
|
||||
intval($item_id)
|
||||
);
|
||||
|
||||
if(! $r)
|
||||
return;
|
||||
|
||||
xchan_query($r);
|
||||
|
||||
$r = fetch_post_tags($r);
|
||||
|
||||
$target_item = $r[0];
|
||||
$deleted_item = false;
|
||||
|
||||
if(intval($target_item['item_deleted'])) {
|
||||
logger('notifier: target item ITEM_DELETED', LOGGER_DEBUG);
|
||||
$deleted_item = true;
|
||||
}
|
||||
|
||||
if(intval($target_item['item_type']) != ITEM_TYPE_POST) {
|
||||
logger('notifier: target item not forwardable: type ' . $target_item['item_type'], LOGGER_DEBUG);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for non published items, but allow an exclusion for transmitting hidden file activities
|
||||
|
||||
if(intval($target_item['item_unpublished']) || intval($target_item['item_delayed']) ||
|
||||
( intval($target_item['item_hidden']) && ($target_item['obj_type'] !== ACTIVITY_OBJ_FILE))) {
|
||||
logger('notifier: target item not published, so not forwardable', LOGGER_DEBUG);
|
||||
return;
|
||||
}
|
||||
|
||||
if(strpos($target_item['postopts'],'nodeliver') !== false) {
|
||||
logger('notifier: target item is undeliverable', LOGGER_DEBUG);
|
||||
return;
|
||||
}
|
||||
|
||||
$s = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1",
|
||||
intval($target_item['uid'])
|
||||
);
|
||||
if($s)
|
||||
$channel = $s[0];
|
||||
|
||||
if($channel['channel_hash'] !== $target_item['author_xchan'] && $channel['channel_hash'] !== $target_item['owner_xchan']) {
|
||||
logger("notifier: Sending channel {$channel['channel_hash']} is not owner {$target_item['owner_xchan']} or author {$target_item['author_xchan']}", LOGGER_NORMAL, LOG_WARNING);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if($target_item['id'] == $target_item['parent']) {
|
||||
$parent_item = $target_item;
|
||||
$top_level_post = true;
|
||||
}
|
||||
else {
|
||||
// fetch the parent item
|
||||
$r = q("SELECT * from item where id = %d order by id asc",
|
||||
intval($target_item['parent'])
|
||||
);
|
||||
|
||||
if(! $r)
|
||||
return;
|
||||
|
||||
if(strpos($r[0]['postopts'],'nodeliver') !== false) {
|
||||
logger('notifier: target item is undeliverable', LOGGER_DEBUG, LOG_NOTICE);
|
||||
return;
|
||||
}
|
||||
|
||||
xchan_query($r);
|
||||
$r = fetch_post_tags($r);
|
||||
|
||||
$parent_item = $r[0];
|
||||
$top_level_post = false;
|
||||
}
|
||||
|
||||
// avoid looping of discover items 12/4/2014
|
||||
|
||||
if($sys && $parent_item['uid'] == $sys['channel_id'])
|
||||
return;
|
||||
|
||||
$encoded_item = encode_item($target_item);
|
||||
|
||||
// Send comments to the owner to re-deliver to everybody in the conversation
|
||||
// We only do this if the item in question originated on this site. This prevents looping.
|
||||
// To clarify, a site accepting a new comment is responsible for sending it to the owner for relay.
|
||||
// Relaying should never be initiated on a post that arrived from elsewhere.
|
||||
|
||||
// We should normally be able to rely on ITEM_ORIGIN, but start_delivery_chain() incorrectly set this
|
||||
// flag on comments for an extended period. So we'll also call comment_local_origin() which looks at
|
||||
// the hostname in the message_id and provides a second (fallback) opinion.
|
||||
|
||||
$relay_to_owner = (((! $top_level_post) && (intval($target_item['item_origin'])) && comment_local_origin($target_item)) ? true : false);
|
||||
|
||||
|
||||
|
||||
$uplink = false;
|
||||
|
||||
// $cmd === 'relay' indicates the owner is sending it to the original recipients
|
||||
// don't allow the item in the relay command to relay to owner under any circumstances, it will loop
|
||||
|
||||
logger('notifier: relay_to_owner: ' . (($relay_to_owner) ? 'true' : 'false'), LOGGER_DATA, LOG_DEBUG);
|
||||
logger('notifier: top_level_post: ' . (($top_level_post) ? 'true' : 'false'), LOGGER_DATA, LOG_DEBUG);
|
||||
|
||||
// tag_deliver'd post which needs to be sent back to the original author
|
||||
|
||||
if(($cmd === 'uplink') && intval($parent_item['item_uplink']) && (! $top_level_post)) {
|
||||
logger('notifier: uplink');
|
||||
$uplink = true;
|
||||
}
|
||||
|
||||
if(($relay_to_owner || $uplink) && ($cmd !== 'relay')) {
|
||||
logger('notifier: followup relay', LOGGER_DEBUG);
|
||||
$recipients = array(($uplink) ? $parent_item['source_xchan'] : $parent_item['owner_xchan']);
|
||||
$private = true;
|
||||
if(! $encoded_item['flags'])
|
||||
$encoded_item['flags'] = array();
|
||||
$encoded_item['flags'][] = 'relay';
|
||||
}
|
||||
else {
|
||||
logger('notifier: normal distribution', LOGGER_DEBUG);
|
||||
if($cmd === 'relay')
|
||||
logger('notifier: owner relay');
|
||||
|
||||
// if our parent is a tag_delivery recipient, uplink to the original author causing
|
||||
// a delivery fork.
|
||||
|
||||
if(($parent_item) && intval($parent_item['item_uplink']) && (! $top_level_post) && ($cmd !== 'uplink')) {
|
||||
// don't uplink a relayed post to the relay owner
|
||||
if($parent_item['source_xchan'] !== $parent_item['owner_xchan']) {
|
||||
logger('notifier: uplinking this item');
|
||||
Master::Summon(array('Notifier','uplink',$item_id));
|
||||
}
|
||||
}
|
||||
|
||||
$private = false;
|
||||
$recipients = collect_recipients($parent_item,$private);
|
||||
|
||||
// FIXME add any additional recipients such as mentions, etc.
|
||||
|
||||
// don't send deletions onward for other people's stuff
|
||||
// TODO verify this is needed - copied logic from same place in old code
|
||||
|
||||
if(intval($target_item['item_deleted']) && (! intval($target_item['item_wall']))) {
|
||||
logger('notifier: ignoring delete notification for non-wall item', LOGGER_NORMAL, LOG_NOTICE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$walltowall = (($top_level_post && $channel['xchan_hash'] === $target_item['author_xchan']) ? true : false);
|
||||
|
||||
// Generic delivery section, we have an encoded item and recipients
|
||||
// Now start the delivery process
|
||||
|
||||
$x = $encoded_item;
|
||||
$x['title'] = 'private';
|
||||
$x['body'] = 'private';
|
||||
logger('notifier: encoded item: ' . print_r($x,true), LOGGER_DATA, LOG_DEBUG);
|
||||
|
||||
stringify_array_elms($recipients);
|
||||
if(! $recipients)
|
||||
return;
|
||||
|
||||
// logger('notifier: recipients: ' . print_r($recipients,true), LOGGER_NORMAL, LOG_DEBUG);
|
||||
|
||||
$env_recips = (($private) ? array() : null);
|
||||
|
||||
$details = q("select xchan_hash, xchan_instance_url, xchan_network, xchan_addr, xchan_guid, xchan_guid_sig from xchan where xchan_hash in (" . implode(',',$recipients) . ")");
|
||||
|
||||
|
||||
$recip_list = array();
|
||||
|
||||
if($details) {
|
||||
foreach($details as $d) {
|
||||
|
||||
$recip_list[] = $d['xchan_addr'] . ' (' . $d['xchan_hash'] . ')';
|
||||
if($private)
|
||||
$env_recips[] = array('guid' => $d['xchan_guid'],'guid_sig' => $d['xchan_guid_sig'],'hash' => $d['xchan_hash']);
|
||||
|
||||
if($d['xchan_network'] === 'mail' && $normal_mode) {
|
||||
$delivery_options = get_xconfig($d['xchan_hash'],'system','delivery_mode');
|
||||
if(! $delivery_options)
|
||||
format_and_send_email($channel,$d,$target_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$narr = array(
|
||||
'channel' => $channel,
|
||||
'env_recips' => $env_recips,
|
||||
'packet_recips' => $packet_recips,
|
||||
'recipients' => $recipients,
|
||||
'item' => $item,
|
||||
'target_item' => $target_item,
|
||||
'top_level_post' => $top_level_post,
|
||||
'private' => $private,
|
||||
'relay_to_owner' => $relay_to_owner,
|
||||
'uplink' => $uplink,
|
||||
'cmd' => $cmd,
|
||||
'mail' => $mail,
|
||||
'single' => (($cmd === 'single_mail' || $cmd === 'single_activity') ? true : false),
|
||||
'location' => $location,
|
||||
'request' => $request,
|
||||
'normal_mode' => $normal_mode,
|
||||
'packet_type' => $packet_type,
|
||||
'walltowall' => $walltowall,
|
||||
'queued' => array()
|
||||
);
|
||||
|
||||
call_hooks('notifier_process', $narr);
|
||||
if($narr['queued']) {
|
||||
foreach($narr['queued'] as $pq)
|
||||
$deliveries[] = $pq;
|
||||
}
|
||||
|
||||
// notifier_process can alter the recipient list
|
||||
|
||||
$recipients = $narr['recipients'];
|
||||
$env_recips = $narr['env_recips'];
|
||||
$packet_recips = $narr['packet_recips'];
|
||||
|
||||
if(($private) && (! $env_recips)) {
|
||||
// shouldn't happen
|
||||
logger('notifier: private message with no envelope recipients.' . print_r($argv,true), LOGGER_NORMAL, LOG_NOTICE);
|
||||
}
|
||||
|
||||
logger('notifier: recipients (may be delivered to more if public): ' . print_r($recip_list,true), LOGGER_DEBUG);
|
||||
|
||||
|
||||
// Now we have collected recipients (except for external mentions, FIXME)
|
||||
// Let's reduce this to a set of hubs.
|
||||
|
||||
$r = q("select * from hubloc where hubloc_hash in (" . implode(',',$recipients) . ")
|
||||
and hubloc_error = 0 and hubloc_deleted = 0"
|
||||
);
|
||||
|
||||
|
||||
if(! $r) {
|
||||
logger('notifier: no hubs', LOGGER_NORMAL, LOG_NOTICE);
|
||||
return;
|
||||
}
|
||||
|
||||
$hubs = $r;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reduce the hubs to those that are unique. For zot hubs, we need to verify uniqueness by the sitekey, since it may have been
|
||||
* a re-install which has not yet been detected and pruned.
|
||||
* For other networks which don't have or require sitekeys, we'll have to use the URL
|
||||
*/
|
||||
|
||||
|
||||
$hublist = array(); // this provides an easily printable list for the logs
|
||||
$dhubs = array(); // delivery hubs where we store our resulting unique array
|
||||
$keys = array(); // array of keys to check uniquness for zot hubs
|
||||
$urls = array(); // array of urls to check uniqueness of hubs from other networks
|
||||
|
||||
|
||||
foreach($hubs as $hub) {
|
||||
if(in_array($hub['hubloc_url'],$dead_hubs)) {
|
||||
logger('skipping dead hub: ' . $hub['hubloc_url'], LOGGER_DEBUG, LOG_INFO);
|
||||
continue;
|
||||
}
|
||||
|
||||
if($hub['hubloc_network'] == 'zot') {
|
||||
if(! in_array($hub['hubloc_sitekey'],$keys)) {
|
||||
$hublist[] = $hub['hubloc_host'];
|
||||
$dhubs[] = $hub;
|
||||
$keys[] = $hub['hubloc_sitekey'];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(! in_array($hub['hubloc_url'],$urls)) {
|
||||
$hublist[] = $hub['hubloc_host'];
|
||||
$dhubs[] = $hub;
|
||||
$urls[] = $hub['hubloc_url'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger('notifier: will notify/deliver to these hubs: ' . print_r($hublist,true), LOGGER_DEBUG, LOG_DEBUG);
|
||||
|
||||
|
||||
foreach($dhubs as $hub) {
|
||||
|
||||
if($hub['hubloc_network'] !== 'zot') {
|
||||
|
||||
$narr = array(
|
||||
'channel' => $channel,
|
||||
'env_recips' => $env_recips,
|
||||
'packet_recips' => $packet_recips,
|
||||
'recipients' => $recipients,
|
||||
'item' => $item,
|
||||
'target_item' => $target_item,
|
||||
'hub' => $hub,
|
||||
'top_level_post' => $top_level_post,
|
||||
'private' => $private,
|
||||
'relay_to_owner' => $relay_to_owner,
|
||||
'uplink' => $uplink,
|
||||
'cmd' => $cmd,
|
||||
'mail' => $mail,
|
||||
'single' => (($cmd === 'single_mail' || $cmd === 'single_activity') ? true : false),
|
||||
'location' => $location,
|
||||
'request' => $request,
|
||||
'normal_mode' => $normal_mode,
|
||||
'packet_type' => $packet_type,
|
||||
'walltowall' => $walltowall,
|
||||
'queued' => array()
|
||||
);
|
||||
|
||||
|
||||
call_hooks('notifier_hub',$narr);
|
||||
if($narr['queued']) {
|
||||
foreach($narr['queued'] as $pq)
|
||||
$deliveries[] = $pq;
|
||||
}
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
// singleton deliveries by definition 'not got zot'.
|
||||
// Single deliveries are other federated networks (plugins) and we're essentially
|
||||
// delivering only to those that have this site url in their abook_instance
|
||||
// and only from within a sync operation. This means if you post from a clone,
|
||||
// and a connection is connected to one of your other clones; assuming that hub
|
||||
// is running it will receive a sync packet. On receipt of this sync packet it
|
||||
// will invoke a delivery to those connections which are connected to just that
|
||||
// hub instance.
|
||||
|
||||
if($cmd === 'single_mail' || $cmd === 'single_activity') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// default: zot protocol
|
||||
|
||||
$hash = random_string();
|
||||
$packet = null;
|
||||
|
||||
if($packet_type === 'refresh' || $packet_type === 'purge') {
|
||||
$packet = zot_build_packet($channel,$packet_type,(($packet_recips) ? $packet_recips : null));
|
||||
}
|
||||
elseif($packet_type === 'request') {
|
||||
$packet = zot_build_packet($channel,$packet_type,$env_recips,$hub['hubloc_sitekey'],$hash,
|
||||
array('message_id' => $request_message_id)
|
||||
);
|
||||
}
|
||||
|
||||
if($packet) {
|
||||
queue_insert(array(
|
||||
'hash' => $hash,
|
||||
'account_id' => $channel['channel_account_id'],
|
||||
'channel_id' => $channel['channel_id'],
|
||||
'posturl' => $hub['hubloc_callback'],
|
||||
'notify' => $packet
|
||||
));
|
||||
}
|
||||
else {
|
||||
$packet = zot_build_packet($channel,'notify',$env_recips,(($private) ? $hub['hubloc_sitekey'] : null),$hash);
|
||||
queue_insert(array(
|
||||
'hash' => $hash,
|
||||
'account_id' => $target_item['aid'],
|
||||
'channel_id' => $target_item['uid'],
|
||||
'posturl' => $hub['hubloc_callback'],
|
||||
'notify' => $packet,
|
||||
'msg' => json_encode($encoded_item)
|
||||
));
|
||||
|
||||
// only create delivery reports for normal undeleted items
|
||||
if(is_array($target_item) && array_key_exists('postopts',$target_item) && (! $target_item['item_deleted']) && (! get_config('system','disable_dreport'))) {
|
||||
q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan, dreport_queue ) values ( '%s','%s','%s','%s','%s','%s','%s' ) ",
|
||||
dbesc($target_item['mid']),
|
||||
dbesc($hub['hubloc_host']),
|
||||
dbesc($hub['hubloc_host']),
|
||||
dbesc('queued'),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($channel['channel_hash']),
|
||||
dbesc($hash)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$deliveries[] = $hash;
|
||||
}
|
||||
|
||||
if($normal_mode) {
|
||||
$x = q("select * from hook where hook = 'notifier_normal'");
|
||||
if($x)
|
||||
Master::Summon(array('Deliver_hooks',$target_item['id']));
|
||||
|
||||
}
|
||||
|
||||
if($deliveries)
|
||||
do_delivery($deliveries);
|
||||
|
||||
logger('notifier: basic loop complete.', LOGGER_DEBUG);
|
||||
|
||||
call_hooks('notifier_end',$target_item);
|
||||
|
||||
logger('notifer: complete.');
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
76
Zotlabs/Daemon/Onedirsync.php
Normal file
76
Zotlabs/Daemon/Onedirsync.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/dir_fns.php');
|
||||
|
||||
|
||||
class Onedirsync {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
logger('onedirsync: start ' . intval($argv[1]));
|
||||
|
||||
if(($argc > 1) && (intval($argv[1])))
|
||||
$update_id = intval($argv[1]);
|
||||
|
||||
if(! $update_id) {
|
||||
logger('onedirsync: no update');
|
||||
return;
|
||||
}
|
||||
|
||||
$r = q("select * from updates where ud_id = %d limit 1",
|
||||
intval($update_id)
|
||||
);
|
||||
|
||||
if(! $r)
|
||||
return;
|
||||
if(($r[0]['ud_flags'] & UPDATE_FLAGS_UPDATED) || (! $r[0]['ud_addr']))
|
||||
return;
|
||||
|
||||
// Have we probed this channel more recently than the other directory server
|
||||
// (where we received this update from) ?
|
||||
// If we have, we don't need to do anything except mark any older entries updated
|
||||
|
||||
$x = q("select * from updates where ud_addr = '%s' and ud_date > '%s' and ( ud_flags & %d )>0 order by ud_date desc limit 1",
|
||||
dbesc($r[0]['ud_addr']),
|
||||
dbesc($r[0]['ud_date']),
|
||||
intval(UPDATE_FLAGS_UPDATED)
|
||||
);
|
||||
if($x) {
|
||||
$y = q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 and ud_date != '%s'",
|
||||
intval(UPDATE_FLAGS_UPDATED),
|
||||
dbesc($r[0]['ud_addr']),
|
||||
intval(UPDATE_FLAGS_UPDATED),
|
||||
dbesc($x[0]['ud_date'])
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// ignore doing an update if this ud_addr refers to a known dead hubloc
|
||||
|
||||
$h = q("select * from hubloc where hubloc_addr = '%s' limit 1",
|
||||
dbesc($r[0]['ud_addr'])
|
||||
);
|
||||
if(($h) && ($h[0]['hubloc_status'] & HUBLOC_OFFLINE)) {
|
||||
$y = q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 ",
|
||||
intval(UPDATE_FLAGS_UPDATED),
|
||||
dbesc($r[0]['ud_addr']),
|
||||
intval(UPDATE_FLAGS_UPDATED)
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// we might have to pull this out some day, but for now update_directory_entry()
|
||||
// runs zot_finger() and is kind of zot specific
|
||||
|
||||
if($h && $h[0]['hubloc_network'] !== 'zot')
|
||||
return;
|
||||
|
||||
update_directory_entry($r[0]);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
154
Zotlabs/Daemon/Onepoll.php
Normal file
154
Zotlabs/Daemon/Onepoll.php
Normal file
@@ -0,0 +1,154 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/socgraph.php');
|
||||
|
||||
|
||||
class Onepoll {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
logger('onepoll: start');
|
||||
|
||||
if(($argc > 1) && (intval($argv[1])))
|
||||
$contact_id = intval($argv[1]);
|
||||
|
||||
if(! $contact_id) {
|
||||
logger('onepoll: no contact');
|
||||
return;
|
||||
}
|
||||
|
||||
$d = datetime_convert();
|
||||
|
||||
$contacts = q("SELECT abook.*, xchan.*, account.*
|
||||
FROM abook LEFT JOIN account on abook_account = account_id left join xchan on xchan_hash = abook_xchan
|
||||
where abook_id = %d
|
||||
and abook_pending = 0 and abook_archived = 0 and abook_blocked = 0 and abook_ignored = 0
|
||||
AND (( account_flags = %d ) OR ( account_flags = %d )) limit 1",
|
||||
intval($contact_id),
|
||||
intval(ACCOUNT_OK),
|
||||
intval(ACCOUNT_UNVERIFIED)
|
||||
);
|
||||
|
||||
if(! $contacts) {
|
||||
logger('onepoll: abook_id not found: ' . $contact_id);
|
||||
return;
|
||||
}
|
||||
|
||||
$contact = $contacts[0];
|
||||
|
||||
$t = $contact['abook_updated'];
|
||||
|
||||
$importer_uid = $contact['abook_channel'];
|
||||
|
||||
$r = q("SELECT * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1",
|
||||
intval($importer_uid)
|
||||
);
|
||||
|
||||
if(! $r)
|
||||
return;
|
||||
|
||||
$importer = $r[0];
|
||||
|
||||
logger("onepoll: poll: ({$contact['id']}) IMPORTER: {$importer['xchan_name']}, CONTACT: {$contact['xchan_name']}");
|
||||
|
||||
$last_update = ((($contact['abook_updated'] === $contact['abook_created']) || ($contact['abook_updated'] === NULL_DATE))
|
||||
? datetime_convert('UTC','UTC','now - 7 days')
|
||||
: datetime_convert('UTC','UTC',$contact['abook_updated'] . ' - 2 days')
|
||||
);
|
||||
|
||||
if($contact['xchan_network'] === 'rss') {
|
||||
logger('onepoll: processing feed ' . $contact['xchan_name'], LOGGER_DEBUG);
|
||||
handle_feed($importer['channel_id'],$contact_id,$contact['xchan_hash']);
|
||||
q("update abook set abook_connected = '%s' where abook_id = %d",
|
||||
dbesc(datetime_convert()),
|
||||
intval($contact['abook_id'])
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if($contact['xchan_network'] !== 'zot')
|
||||
return;
|
||||
|
||||
// update permissions
|
||||
|
||||
$x = zot_refresh($contact,$importer);
|
||||
|
||||
$responded = false;
|
||||
$updated = datetime_convert();
|
||||
$connected = datetime_convert();
|
||||
if(! $x) {
|
||||
// mark for death by not updating abook_connected, this is caught in include/poller.php
|
||||
q("update abook set abook_updated = '%s' where abook_id = %d",
|
||||
dbesc($updated),
|
||||
intval($contact['abook_id'])
|
||||
);
|
||||
}
|
||||
else {
|
||||
q("update abook set abook_updated = '%s', abook_connected = '%s' where abook_id = %d",
|
||||
dbesc($updated),
|
||||
dbesc($connected),
|
||||
intval($contact['abook_id'])
|
||||
);
|
||||
$responded = true;
|
||||
}
|
||||
|
||||
if(! $responded)
|
||||
return;
|
||||
|
||||
if($contact['xchan_connurl']) {
|
||||
$fetch_feed = true;
|
||||
$x = null;
|
||||
|
||||
$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) {
|
||||
|
||||
$feedurl = str_replace('/poco/','/zotfeed/',$contact['xchan_connurl']);
|
||||
$feedurl .= '?f=&mindate=' . urlencode($last_update);
|
||||
|
||||
$x = z_fetch_url($feedurl);
|
||||
|
||||
logger('feed_update: ' . print_r($x,true), LOGGER_DATA);
|
||||
|
||||
}
|
||||
|
||||
if(($x) && ($x['success'])) {
|
||||
$total = 0;
|
||||
logger('onepoll: feed update ' . $contact['xchan_name'] . ' ' . $feedurl);
|
||||
|
||||
$j = json_decode($x['body'],true);
|
||||
if($j['success'] && $j['messages']) {
|
||||
foreach($j['messages'] as $message) {
|
||||
$results = process_delivery(array('hash' => $contact['xchan_hash']), get_item_elements($message),
|
||||
array(array('hash' => $importer['xchan_hash'])), false);
|
||||
logger('onepoll: feed_update: process_delivery: ' . print_r($results,true), LOGGER_DATA);
|
||||
$total ++;
|
||||
}
|
||||
logger("onepoll: $total messages processed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// update the poco details for this connection
|
||||
|
||||
if($contact['xchan_connurl']) {
|
||||
$r = q("SELECT xlink_id from xlink
|
||||
where xlink_xchan = '%s' and xlink_updated > %s - INTERVAL %s and xlink_static = 0 limit 1",
|
||||
intval($contact['xchan_hash']),
|
||||
db_utcnow(), db_quoteinterval('1 DAY')
|
||||
);
|
||||
if(! $r) {
|
||||
poco_load($contact['xchan_hash'],$contact['xchan_connurl']);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
202
Zotlabs/Daemon/Poller.php
Normal file
202
Zotlabs/Daemon/Poller.php
Normal file
@@ -0,0 +1,202 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
class Poller {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
$maxsysload = intval(get_config('system','maxloadavg'));
|
||||
if($maxsysload < 1)
|
||||
$maxsysload = 50;
|
||||
if(function_exists('sys_getloadavg')) {
|
||||
$load = sys_getloadavg();
|
||||
if(intval($load[0]) > $maxsysload) {
|
||||
logger('system: load ' . $load . ' too high. Poller deferred to next scheduled run.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$interval = intval(get_config('system','poll_interval'));
|
||||
if(! $interval)
|
||||
$interval = ((get_config('system','delivery_interval') === false) ? 3 : intval(get_config('system','delivery_interval')));
|
||||
|
||||
// Check for a lockfile. If it exists, but is over an hour old, it's stale. Ignore it.
|
||||
$lockfile = 'store/[data]/poller';
|
||||
if((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 3600))
|
||||
&& (! get_config('system','override_poll_lockfile'))) {
|
||||
logger("poller: Already running");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a lockfile. Needs two vars, but $x doesn't need to contain anything.
|
||||
file_put_contents($lockfile, $x);
|
||||
|
||||
logger('poller: start');
|
||||
|
||||
$manual_id = 0;
|
||||
$generation = 0;
|
||||
|
||||
$force = false;
|
||||
$restart = false;
|
||||
|
||||
if(($argc > 1) && ($argv[1] == 'force'))
|
||||
$force = true;
|
||||
|
||||
if(($argc > 1) && ($argv[1] == 'restart')) {
|
||||
$restart = true;
|
||||
$generation = intval($argv[2]);
|
||||
if(! $generation)
|
||||
killme();
|
||||
}
|
||||
|
||||
if(($argc > 1) && intval($argv[1])) {
|
||||
$manual_id = intval($argv[1]);
|
||||
$force = true;
|
||||
}
|
||||
|
||||
|
||||
$sql_extra = (($manual_id) ? " AND abook_id = " . intval($manual_id) . " " : "");
|
||||
|
||||
reload_plugins();
|
||||
|
||||
$d = datetime_convert();
|
||||
|
||||
// Only poll from those with suitable relationships
|
||||
|
||||
$abandon_sql = (($abandon_days)
|
||||
? sprintf(" AND account_lastlog > %s - INTERVAL %s ", db_utcnow(), db_quoteinterval(intval($abandon_days).' DAY'))
|
||||
: ''
|
||||
);
|
||||
|
||||
$randfunc = db_getfunc('RAND');
|
||||
|
||||
$contacts = q("SELECT * FROM abook LEFT JOIN xchan on abook_xchan = xchan_hash
|
||||
LEFT JOIN account on abook_account = account_id
|
||||
where abook_self = 0
|
||||
$sql_extra
|
||||
AND (( account_flags = %d ) OR ( account_flags = %d )) $abandon_sql ORDER BY $randfunc",
|
||||
intval(ACCOUNT_OK),
|
||||
intval(ACCOUNT_UNVERIFIED) // FIXME
|
||||
|
||||
);
|
||||
|
||||
if($contacts) {
|
||||
|
||||
foreach($contacts as $contact) {
|
||||
|
||||
$update = false;
|
||||
|
||||
$t = $contact['abook_updated'];
|
||||
$c = $contact['abook_connected'];
|
||||
|
||||
if(intval($contact['abook_feed'])) {
|
||||
$min = service_class_fetch($contact['abook_channel'],'minimum_feedcheck_minutes');
|
||||
if(! $min)
|
||||
$min = intval(get_config('system','minimum_feedcheck_minutes'));
|
||||
if(! $min)
|
||||
$min = 60;
|
||||
$x = datetime_convert('UTC','UTC',"now - $min minutes");
|
||||
if($c < $x) {
|
||||
Master::Summon(array('Onepoll',$contact['abook_id']));
|
||||
if($interval)
|
||||
@time_sleep_until(microtime(true) + (float) $interval);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if($contact['xchan_network'] !== 'zot')
|
||||
continue;
|
||||
|
||||
if($c == $t) {
|
||||
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day"))
|
||||
$update = true;
|
||||
}
|
||||
else {
|
||||
|
||||
// if we've never connected with them, start the mark for death countdown from now
|
||||
|
||||
if($c == NULL_DATE) {
|
||||
$r = q("update abook set abook_connected = '%s' where abook_id = %d",
|
||||
dbesc(datetime_convert()),
|
||||
intval($contact['abook_id'])
|
||||
);
|
||||
$c = datetime_convert();
|
||||
$update = true;
|
||||
}
|
||||
|
||||
// He's dead, Jim
|
||||
|
||||
if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 30 day")) > 0) {
|
||||
$r = q("update abook set abook_archived = 1 where abook_id = %d",
|
||||
intval($contact['abook_id'])
|
||||
);
|
||||
$update = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(intval($contact['abook_archived'])) {
|
||||
$update = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// might be dead, so maybe don't poll quite so often
|
||||
|
||||
// recently deceased, so keep up the regular schedule for 3 days
|
||||
|
||||
if((strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 3 day")) > 0)
|
||||
&& (strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 1 day")) > 0))
|
||||
$update = true;
|
||||
|
||||
// After that back off and put them on a morphine drip
|
||||
|
||||
if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 2 day")) > 0) {
|
||||
$update = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(intval($contact['abook_pending']) || intval($contact['abook_archived']) || intval($contact['abook_ignored']) || intval($contact['abook_blocked']))
|
||||
continue;
|
||||
|
||||
if((! $update) && (! $force))
|
||||
continue;
|
||||
|
||||
Master::Summon(array('Onepoll',$contact['abook_id']));
|
||||
if($interval)
|
||||
@time_sleep_until(microtime(true) + (float) $interval);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) {
|
||||
$r = q("SELECT u.ud_addr, u.ud_id, u.ud_last FROM updates AS u INNER JOIN (SELECT ud_addr, max(ud_id) AS ud_id FROM updates WHERE ( ud_flags & %d ) = 0 AND ud_addr != '' AND ( ud_last = '%s' OR ud_last > %s - INTERVAL %s ) GROUP BY ud_addr) AS s ON s.ud_id = u.ud_id ",
|
||||
intval(UPDATE_FLAGS_UPDATED),
|
||||
dbesc(NULL_DATE),
|
||||
db_utcnow(), db_quoteinterval('7 DAY')
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
|
||||
// If they didn't respond when we attempted before, back off to once a day
|
||||
// After 7 days we won't bother anymore
|
||||
|
||||
if($rr['ud_last'] != NULL_DATE)
|
||||
if($rr['ud_last'] > datetime_convert('UTC','UTC', 'now - 1 day'))
|
||||
continue;
|
||||
Master::Summon(array('Onedirsync',$rr['ud_id']));
|
||||
if($interval)
|
||||
@time_sleep_until(microtime(true) + (float) $interval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set_config('system','lastpoll',datetime_convert());
|
||||
|
||||
//All done - clear the lockfile
|
||||
@unlink($lockfile);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
90
Zotlabs/Daemon/Queue.php
Normal file
90
Zotlabs/Daemon/Queue.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/queue_fn.php');
|
||||
require_once('include/zot.php');
|
||||
|
||||
class Queue {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
require_once('include/items.php');
|
||||
require_once('include/bbcode.php');
|
||||
|
||||
if(argc() > 1)
|
||||
$queue_id = argv(1);
|
||||
else
|
||||
$queue_id = 0;
|
||||
|
||||
logger('queue: start');
|
||||
|
||||
// delete all queue items more than 3 days old
|
||||
// but first mark these sites dead if we haven't heard from them in a month
|
||||
|
||||
$r = q("select outq_posturl from outq where outq_created < %s - INTERVAL %s",
|
||||
db_utcnow(), db_quoteinterval('3 DAY')
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$site_url = '';
|
||||
$h = parse_url($rr['outq_posturl']);
|
||||
$desturl = $h['scheme'] . '://' . $h['host'] . (($h['port']) ? ':' . $h['port'] : '');
|
||||
q("update site set site_dead = 1 where site_dead = 0 and site_url = '%s' and site_update < %s - INTERVAL %s",
|
||||
dbesc($desturl),
|
||||
db_utcnow(), db_quoteinterval('1 MONTH')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$r = q("DELETE FROM outq WHERE outq_created < %s - INTERVAL %s",
|
||||
db_utcnow(), db_quoteinterval('3 DAY')
|
||||
);
|
||||
|
||||
if($queue_id) {
|
||||
$r = q("SELECT * FROM outq WHERE outq_hash = '%s' LIMIT 1",
|
||||
dbesc($queue_id)
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
// For the first 12 hours we'll try to deliver every 15 minutes
|
||||
// After that, we'll only attempt delivery once per hour.
|
||||
// This currently only handles the default queue drivers ('zot' or '') which we will group by posturl
|
||||
// so that we don't start off a thousand deliveries for a couple of dead hubs.
|
||||
// The zot driver will deliver everything destined for a single hub once contact is made (*if* contact is made).
|
||||
// Other drivers will have to do something different here and may need their own query.
|
||||
|
||||
// Note: this requires some tweaking as new posts to long dead hubs once a day will keep them in the
|
||||
// "every 15 minutes" category. We probably need to prioritise them when inserted into the queue
|
||||
// or just prior to this query based on recent and long-term delivery history. If we have good reason to believe
|
||||
// the site is permanently down, there's no reason to attempt delivery at all, or at most not more than once
|
||||
// or twice a day.
|
||||
|
||||
// FIXME: can we sort postgres on outq_priority and maintain the 'distinct' ?
|
||||
// The order by max(outq_priority) might be a dodgy query because of the group by.
|
||||
// The desired result is to return a sequence in the order most likely to be delivered in this run.
|
||||
// If a hub has already been sitting in the queue for a few days, they should be delivered last;
|
||||
// hence every failure should drop them further down the priority list.
|
||||
|
||||
if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
|
||||
$prefix = 'DISTINCT ON (outq_posturl)';
|
||||
$suffix = 'ORDER BY outq_posturl';
|
||||
} else {
|
||||
$prefix = '';
|
||||
$suffix = 'GROUP BY outq_posturl ORDER BY max(outq_priority)';
|
||||
}
|
||||
$r = q("SELECT $prefix * FROM outq WHERE outq_delivered = 0 and (( outq_created > %s - INTERVAL %s and outq_updated < %s - INTERVAL %s ) OR ( outq_updated < %s - INTERVAL %s )) $suffix",
|
||||
db_utcnow(), db_quoteinterval('12 HOUR'),
|
||||
db_utcnow(), db_quoteinterval('15 MINUTE'),
|
||||
db_utcnow(), db_quoteinterval('1 HOUR')
|
||||
);
|
||||
}
|
||||
if(! $r)
|
||||
return;
|
||||
|
||||
foreach($r as $rr) {
|
||||
queue_deliver($rr);
|
||||
}
|
||||
}
|
||||
}
|
||||
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.
|
||||
|
||||
113
Zotlabs/Daemon/Ratenotif.php
Normal file
113
Zotlabs/Daemon/Ratenotif.php
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/queue_fn.php');
|
||||
|
||||
|
||||
class Ratenotif {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
require_once("datetime.php");
|
||||
require_once('include/items.php');
|
||||
|
||||
if($argc < 3)
|
||||
return;
|
||||
|
||||
|
||||
logger('ratenotif: invoked: ' . print_r($argv,true), LOGGER_DEBUG);
|
||||
|
||||
$cmd = $argv[1];
|
||||
|
||||
$item_id = $argv[2];
|
||||
|
||||
|
||||
if($cmd === 'rating') {
|
||||
$r = q("select * from xlink where xlink_id = %d and xlink_static = 1 limit 1",
|
||||
intval($item_id)
|
||||
);
|
||||
if(! $r) {
|
||||
logger('rating not found');
|
||||
return;
|
||||
}
|
||||
|
||||
$encoded_item = array(
|
||||
'type' => 'rating',
|
||||
'encoding' => 'zot',
|
||||
'target' => $r[0]['xlink_link'],
|
||||
'rating' => intval($r[0]['xlink_rating']),
|
||||
'rating_text' => $r[0]['xlink_rating_text'],
|
||||
'signature' => $r[0]['xlink_sig'],
|
||||
'edited' => $r[0]['xlink_updated']
|
||||
);
|
||||
}
|
||||
|
||||
$channel = channelx_by_hash($r[0]['xlink_xchan']);
|
||||
if(! $channel) {
|
||||
logger('no channel');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$primary = get_directory_primary();
|
||||
|
||||
if(! $primary)
|
||||
return;
|
||||
|
||||
|
||||
$interval = ((get_config('system','delivery_interval') !== false)
|
||||
? intval(get_config('system','delivery_interval')) : 2 );
|
||||
|
||||
$deliveries_per_process = intval(get_config('system','delivery_batch_count'));
|
||||
|
||||
if($deliveries_per_process <= 0)
|
||||
$deliveries_per_process = 1;
|
||||
|
||||
$deliver = array();
|
||||
|
||||
$x = z_fetch_url($primary . '/regdir');
|
||||
if($x['success']) {
|
||||
$j = json_decode($x['body'],true);
|
||||
if($j && $j['success'] && is_array($j['directories'])) {
|
||||
|
||||
foreach($j['directories'] as $h) {
|
||||
if($h == z_root())
|
||||
continue;
|
||||
|
||||
$hash = random_string();
|
||||
$n = zot_build_packet($channel,'notify',null,null,$hash);
|
||||
|
||||
queue_insert(array(
|
||||
'hash' => $hash,
|
||||
'account_id' => $channel['channel_account_id'],
|
||||
'channel_id' => $channel['channel_id'],
|
||||
'posturl' => $h . '/post',
|
||||
'notify' => $n,
|
||||
'msg' => json_encode($encoded_item)
|
||||
));
|
||||
|
||||
$deliver[] = $hash;
|
||||
|
||||
if(count($deliver) >= $deliveries_per_process) {
|
||||
Master::Summon(array('Deliver',$deliver));
|
||||
$deliver = array();
|
||||
if($interval)
|
||||
@time_sleep_until(microtime(true) + (float) $interval);
|
||||
}
|
||||
}
|
||||
|
||||
// catch any stragglers
|
||||
|
||||
if(count($deliver)) {
|
||||
Master::Summon(array('Deliver',$deliver));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger('ratenotif: complete.');
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ class Hook {
|
||||
$function = serialize($function);
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM `hook` WHERE `hook` = '%s' AND `file` = '%s' AND `function` = '%s' and priority = %d and hook_version = %d LIMIT 1",
|
||||
$r = q("SELECT * FROM `hook` WHERE `hook` = '%s' AND `file` = '%s' AND `fn` = '%s' and priority = %d and hook_version = %d LIMIT 1",
|
||||
dbesc($hook),
|
||||
dbesc($file),
|
||||
dbesc($function),
|
||||
@@ -23,13 +23,13 @@ class Hook {
|
||||
// To aid in upgrade and transition, remove old settings for any registered hooks that match in all respects except
|
||||
// for priority or hook_version
|
||||
|
||||
$r = q("DELETE FROM `hook` where `hook` = '%s' and `file` = '%s' and `function` = '%s'",
|
||||
$r = q("DELETE FROM `hook` where `hook` = '%s' and `file` = '%s' and `fn` = '%s'",
|
||||
dbesc($hook),
|
||||
dbesc($file),
|
||||
dbesc($function)
|
||||
);
|
||||
|
||||
$r = q("INSERT INTO `hook` (`hook`, `file`, `function`, `priority`, `hook_version`) VALUES ( '%s', '%s', '%s', %d, %d )",
|
||||
$r = q("INSERT INTO `hook` (`hook`, `file`, `fn`, `priority`, `hook_version`) VALUES ( '%s', '%s', '%s', %d, %d )",
|
||||
dbesc($hook),
|
||||
dbesc($file),
|
||||
dbesc($function),
|
||||
@@ -44,7 +44,7 @@ class Hook {
|
||||
if(is_array($function)) {
|
||||
$function = serialize($function);
|
||||
}
|
||||
$r = q("DELETE FROM hook WHERE hook = '%s' AND `file` = '%s' AND `function` = '%s' and priority = %d and hook_version = %d",
|
||||
$r = q("DELETE FROM hook WHERE hook = '%s' AND `file` = '%s' AND `fn` = '%s' and priority = %d and hook_version = %d",
|
||||
dbesc($hook),
|
||||
dbesc($file),
|
||||
dbesc($function),
|
||||
|
||||
25
Zotlabs/Lib/AConfig.php
Normal file
25
Zotlabs/Lib/AConfig.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
// account configuration storage is built on top of the under-utilised xconfig
|
||||
|
||||
class AConfig {
|
||||
|
||||
static public function Load($account_id) {
|
||||
return XConfig::Load('a_' . $account_id);
|
||||
}
|
||||
|
||||
static public function Get($account_id,$family,$key) {
|
||||
return XConfig::Get('a_' . $account_id,$family,$key);
|
||||
}
|
||||
|
||||
static public function Set($account_id,$family,$key,$value) {
|
||||
return XConfig::Get('a_' . $account_id,$family,$key,$value);
|
||||
}
|
||||
|
||||
static public function Delete($account_id,$family,$key) {
|
||||
return XConfig::Delete('a_' . $account_id,$family,$key);
|
||||
}
|
||||
|
||||
}
|
||||
75
Zotlabs/Lib/AbConfig.php
Normal file
75
Zotlabs/Lib/AbConfig.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
|
||||
class AbConfig {
|
||||
|
||||
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($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)
|
||||
);
|
||||
if($r) {
|
||||
return ((preg_match('|^a:[0-9]+:{.*}$|s', $r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
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($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),
|
||||
dbesc($dbvalue)
|
||||
);
|
||||
}
|
||||
else {
|
||||
$r = q("update abconfig set v = '%s' where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' ",
|
||||
dbesc($dbvalue),
|
||||
dbesc($chan),
|
||||
dbesc($xhash),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
}
|
||||
|
||||
if($r)
|
||||
return $value;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static public function Delete($chan,$xhash,$family,$key) {
|
||||
|
||||
$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)
|
||||
);
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
}
|
||||
709
Zotlabs/Lib/Apps.php
Normal file
709
Zotlabs/Lib/Apps.php
Normal file
@@ -0,0 +1,709 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
/**
|
||||
* Apps
|
||||
*
|
||||
*/
|
||||
|
||||
require_once('include/plugin.php');
|
||||
require_once('include/channel.php');
|
||||
|
||||
|
||||
class Apps {
|
||||
|
||||
static public $installed_system_apps = null;
|
||||
|
||||
static public function get_system_apps($translate = true) {
|
||||
|
||||
$ret = array();
|
||||
if(is_dir('apps'))
|
||||
$files = glob('apps/*.apd');
|
||||
else
|
||||
$files = glob('app/*.apd');
|
||||
if($files) {
|
||||
foreach($files as $f) {
|
||||
$x = self::parse_app_description($f,$translate);
|
||||
if($x) {
|
||||
$ret[] = $x;
|
||||
}
|
||||
}
|
||||
}
|
||||
$files = glob('addon/*/*.apd');
|
||||
if($files) {
|
||||
foreach($files as $f) {
|
||||
$path = explode('/',$f);
|
||||
$plugin = $path[1];
|
||||
if(plugin_is_installed($plugin)) {
|
||||
$x = self::parse_app_description($f,$translate);
|
||||
if($x) {
|
||||
$ret[] = $x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static public function import_system_apps() {
|
||||
if(! local_channel())
|
||||
return;
|
||||
$apps = self::get_system_apps(false);
|
||||
|
||||
|
||||
self::$installed_system_apps = q("select * from app where app_system = 1 and app_channel = %d",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
if($apps) {
|
||||
foreach($apps as $app) {
|
||||
$id = self::check_install_system_app($app);
|
||||
// $id will be boolean true or false to install an app, or an integer id to update an existing app
|
||||
if($id === false)
|
||||
continue;
|
||||
if($id !== true) {
|
||||
// if we already installed this app, but it changed, preserve any categories we created
|
||||
$s = '';
|
||||
$r = q("select * from term where otype = %d and oid = d",
|
||||
intval(TERM_OBJ_APP),
|
||||
intval($id)
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $t) {
|
||||
if($s)
|
||||
$s .= ',';
|
||||
$s .= $t['term'];
|
||||
}
|
||||
$app['categories'] = $s;
|
||||
}
|
||||
}
|
||||
$app['uid'] = local_channel();
|
||||
$app['guid'] = hash('whirlpool',$app['name']);
|
||||
$app['system'] = 1;
|
||||
self::app_install(local_channel(),$app);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Install the system app if no system apps have been installed, or if a new system app
|
||||
* is discovered, or if the version of a system app changes.
|
||||
*/
|
||||
|
||||
static public function check_install_system_app($app) {
|
||||
if((! is_array(self::$installed_system_apps)) || (! count(self::$installed_system_apps))) {
|
||||
return true;
|
||||
}
|
||||
$notfound = true;
|
||||
foreach(self::$installed_system_apps as $iapp) {
|
||||
if($iapp['app_id'] == hash('whirlpool',$app['name'])) {
|
||||
$notfound = false;
|
||||
if($iapp['app_version'] != $app['version']) {
|
||||
return intval($iapp['app_id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $notfound;
|
||||
}
|
||||
|
||||
|
||||
static public function app_name_compare($a,$b) {
|
||||
return strcmp($a['name'],$b['name']);
|
||||
}
|
||||
|
||||
|
||||
static public function parse_app_description($f,$translate = true) {
|
||||
$ret = array();
|
||||
|
||||
$baseurl = z_root();
|
||||
$channel = \App::get_channel();
|
||||
$address = (($channel) ? $channel['channel_address'] : '');
|
||||
|
||||
//future expansion
|
||||
|
||||
$observer = \App::get_observer();
|
||||
|
||||
|
||||
$lines = @file($f);
|
||||
if($lines) {
|
||||
foreach($lines as $x) {
|
||||
if(preg_match('/^([a-zA-Z].*?):(.*?)$/ism',$x,$matches)) {
|
||||
$ret[$matches[1]] = trim(str_replace(array('$baseurl','$nick'),array($baseurl,$address),$matches[2]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(! $ret['photo'])
|
||||
$ret['photo'] = $baseurl . '/' . get_default_profile_photo(80);
|
||||
|
||||
$ret['type'] = 'system';
|
||||
|
||||
foreach($ret as $k => $v) {
|
||||
if(strpos($v,'http') === 0)
|
||||
$ret[$k] = zid($v);
|
||||
}
|
||||
|
||||
if(array_key_exists('desc',$ret))
|
||||
$ret['desc'] = str_replace(array('\'','"'),array(''','&dquot;'),$ret['desc']);
|
||||
|
||||
if(array_key_exists('target',$ret))
|
||||
$ret['target'] = str_replace(array('\'','"'),array(''','&dquot;'),$ret['target']);
|
||||
|
||||
if(array_key_exists('version',$ret))
|
||||
$ret['version'] = str_replace(array('\'','"'),array(''','&dquot;'),$ret['version']);
|
||||
|
||||
|
||||
if(array_key_exists('requires',$ret)) {
|
||||
$requires = explode(',',$ret['requires']);
|
||||
foreach($requires as $require) {
|
||||
$require = trim(strtolower($require));
|
||||
switch($require) {
|
||||
case 'nologin':
|
||||
if(local_channel())
|
||||
unset($ret);
|
||||
break;
|
||||
case 'admin':
|
||||
if(! is_site_admin())
|
||||
unset($ret);
|
||||
break;
|
||||
case 'local_channel':
|
||||
if(! local_channel())
|
||||
unset($ret);
|
||||
break;
|
||||
case 'public_profile':
|
||||
if(! is_public_profile())
|
||||
unset($ret);
|
||||
break;
|
||||
case 'observer':
|
||||
if(! $observer)
|
||||
unset($ret);
|
||||
break;
|
||||
default:
|
||||
if(! (local_channel() && feature_enabled(local_channel(),$require)))
|
||||
unset($ret);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if($ret) {
|
||||
if($translate)
|
||||
self::translate_system_apps($ret);
|
||||
return $ret;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static public function translate_system_apps(&$arr) {
|
||||
$apps = array(
|
||||
'Site Admin' => t('Site Admin'),
|
||||
'Bug Report' => t('Bug Report'),
|
||||
'View Bookmarks' => t('View Bookmarks'),
|
||||
'My Chatrooms' => t('My Chatrooms'),
|
||||
'Connections' => t('Connections'),
|
||||
'Firefox Share' => t('Firefox Share'),
|
||||
'Remote Diagnostics' => t('Remote Diagnostics'),
|
||||
'Suggest Channels' => t('Suggest Channels'),
|
||||
'Login' => t('Login'),
|
||||
'Channel Manager' => t('Channel Manager'),
|
||||
'Grid' => t('Grid'),
|
||||
'Settings' => t('Settings'),
|
||||
'Files' => t('Files'),
|
||||
'Webpages' => t('Webpages'),
|
||||
'Wiki' => t('Wiki'),
|
||||
'Channel Home' => t('Channel Home'),
|
||||
'View Profile' => t('View Profile'),
|
||||
'Photos' => t('Photos'),
|
||||
'Events' => t('Events'),
|
||||
'Directory' => t('Directory'),
|
||||
'Help' => t('Help'),
|
||||
'Mail' => t('Mail'),
|
||||
'Mood' => t('Mood'),
|
||||
'Poke' => t('Poke'),
|
||||
'Chat' => t('Chat'),
|
||||
'Search' => t('Search'),
|
||||
'Probe' => t('Probe'),
|
||||
'Suggest' => t('Suggest'),
|
||||
'Random Channel' => t('Random Channel'),
|
||||
'Invite' => t('Invite'),
|
||||
'Features' => t('Features'),
|
||||
'Language' => t('Language'),
|
||||
'Post' => t('Post'),
|
||||
'Profile Photo' => t('Profile Photo')
|
||||
);
|
||||
|
||||
if(array_key_exists($arr['name'],$apps))
|
||||
$arr['name'] = $apps[$arr['name']];
|
||||
|
||||
}
|
||||
|
||||
|
||||
// papp is a portable app
|
||||
|
||||
static public function app_render($papp,$mode = 'view') {
|
||||
|
||||
/**
|
||||
* modes:
|
||||
* view: normal mode for viewing an app via bbcode from a conversation or page
|
||||
* provides install/update button if you're logged in locally
|
||||
* list: normal mode for viewing an app on the app page
|
||||
* no buttons are shown
|
||||
* edit: viewing the app page in editing mode provides a delete button
|
||||
*/
|
||||
|
||||
$installed = false;
|
||||
|
||||
if(! $papp)
|
||||
return;
|
||||
|
||||
if(! $papp['photo'])
|
||||
$papp['photo'] = z_root() . '/' . get_default_profile_photo(80);
|
||||
|
||||
self::translate_system_apps($papp);
|
||||
|
||||
$papp['papp'] = self::papp_encode($papp);
|
||||
|
||||
if(! strstr($papp['url'],'://'))
|
||||
$papp['url'] = z_root() . ((strpos($papp['url'],'/') === 0) ? '' : '/') . $papp['url'];
|
||||
|
||||
foreach($papp as $k => $v) {
|
||||
if(strpos($v,'http') === 0 && $k != 'papp')
|
||||
$papp[$k] = zid($v);
|
||||
if($k === 'desc')
|
||||
$papp['desc'] = str_replace(array('\'','"'),array(''','&dquot;'),$papp['desc']);
|
||||
|
||||
if($k === 'requires') {
|
||||
$requires = explode(',',$v);
|
||||
foreach($requires as $require) {
|
||||
$require = trim(strtolower($require));
|
||||
switch($require) {
|
||||
case 'nologin':
|
||||
if(local_channel())
|
||||
return '';
|
||||
break;
|
||||
case 'admin':
|
||||
if(! is_site_admin())
|
||||
return '';
|
||||
break;
|
||||
case 'local_channel':
|
||||
if(! local_channel())
|
||||
return '';
|
||||
break;
|
||||
case 'public_profile':
|
||||
if(! is_public_profile())
|
||||
return '';
|
||||
break;
|
||||
case 'observer':
|
||||
$observer = \App::get_observer();
|
||||
if(! $observer)
|
||||
return '';
|
||||
break;
|
||||
default:
|
||||
if(! (local_channel() && feature_enabled(local_channel(),$require)))
|
||||
return '';
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$hosturl = '';
|
||||
|
||||
if(local_channel()) {
|
||||
$installed = self::app_installed(local_channel(),$papp);
|
||||
$hosturl = z_root() . '/';
|
||||
}
|
||||
elseif(remote_channel()) {
|
||||
$observer = \App::get_observer();
|
||||
if($observer && $observer['xchan_network'] === 'zot') {
|
||||
// some folks might have xchan_url redirected offsite, use the connurl
|
||||
$x = parse_url($observer['xchan_connurl']);
|
||||
if($x) {
|
||||
$hosturl = $x['scheme'] . '://' . $x['host'] . '/';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$install_action = (($installed) ? t('Update') : t('Install'));
|
||||
|
||||
return replace_macros(get_markup_template('app.tpl'),array(
|
||||
'$app' => $papp,
|
||||
'$hosturl' => $hosturl,
|
||||
'$purchase' => (($papp['page'] && (! $installed)) ? t('Purchase') : ''),
|
||||
'$install' => (($hosturl && $mode == 'view') ? $install_action : ''),
|
||||
'$edit' => ((local_channel() && $installed && $mode == 'edit') ? t('Edit') : ''),
|
||||
'$delete' => ((local_channel() && $installed && $mode == 'edit') ? t('Delete') : '')
|
||||
));
|
||||
}
|
||||
|
||||
static public function app_install($uid,$app) {
|
||||
$app['uid'] = $uid;
|
||||
|
||||
if(self::app_installed($uid,$app))
|
||||
$x = self::app_update($app);
|
||||
else
|
||||
$x = self::app_store($app);
|
||||
|
||||
if($x['success']) {
|
||||
$r = q("select * from app where app_id = '%s' and app_channel = %d limit 1",
|
||||
dbesc($x['app_id']),
|
||||
intval($uid)
|
||||
);
|
||||
if($r) {
|
||||
if(! $r[0]['app_system']) {
|
||||
if($app['categories'] && (! $app['term'])) {
|
||||
$r[0]['term'] = q("select * from term where otype = %d and oid = d",
|
||||
intval(TERM_OBJ_APP),
|
||||
intval($r[0]['id'])
|
||||
);
|
||||
build_sync_packet($uid,array('app' => $r[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
return $x['app_id'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static public function app_destroy($uid,$app) {
|
||||
|
||||
|
||||
if($uid && $app['guid']) {
|
||||
|
||||
$x = q("select * from app where app_id = '%s' and app_channel = %d limit 1",
|
||||
dbesc($app['guid']),
|
||||
intval($uid)
|
||||
);
|
||||
if($x) {
|
||||
$x[0]['app_deleted'] = 1;
|
||||
q("delete from term where otype = %d and oid = %d",
|
||||
intval(TERM_OBJ_APP),
|
||||
intval($x[0]['id'])
|
||||
);
|
||||
if($x[0]['app_system']) {
|
||||
$r = q("update app set app_deleted = 1 where app_id = '%s' and app_channel = %d",
|
||||
dbesc($app['guid']),
|
||||
intval($uid)
|
||||
);
|
||||
}
|
||||
else {
|
||||
$r = q("delete from app where app_id = '%s' and app_channel = %d",
|
||||
dbesc($app['guid']),
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
// we don't sync system apps - they may be completely different on the other system
|
||||
build_sync_packet($uid,array('app' => $x));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static public function app_installed($uid,$app) {
|
||||
|
||||
$r = q("select id from app where app_id = '%s' and app_version = '%s' and app_channel = %d limit 1",
|
||||
dbesc((array_key_exists('guid',$app)) ? $app['guid'] : ''),
|
||||
dbesc((array_key_exists('version',$app)) ? $app['version'] : ''),
|
||||
intval($uid)
|
||||
);
|
||||
return(($r) ? true : false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static public function app_list($uid, $deleted = false, $cat = '') {
|
||||
if($deleted)
|
||||
$sql_extra = " and app_deleted = 1 ";
|
||||
else
|
||||
$sql_extra = " and app_deleted = 0 ";
|
||||
|
||||
if($cat) {
|
||||
$r = q("select oid from term where otype = %d and term = '%s'",
|
||||
intval(TERM_OBJ_APP),
|
||||
dbesc($cat)
|
||||
);
|
||||
if(! $r)
|
||||
return $r;
|
||||
$sql_extra .= " and app.id in ( ";
|
||||
$s = '';
|
||||
foreach($r as $rr) {
|
||||
if($s)
|
||||
$s .= ',';
|
||||
$s .= intval($rr['oid']);
|
||||
}
|
||||
$sql_extra .= $s . ') ';
|
||||
}
|
||||
|
||||
$r = q("select * from app where app_channel = %d $sql_extra order by app_name asc",
|
||||
intval($uid)
|
||||
);
|
||||
if($r) {
|
||||
for($x = 0; $x < count($r); $x ++) {
|
||||
if(! $r[$x]['app_system'])
|
||||
$r[$x]['type'] = 'personal';
|
||||
$r[$x]['term'] = q("select * from term where otype = %d and oid = %d",
|
||||
intval(TERM_OBJ_APP),
|
||||
intval($r[$x]['id'])
|
||||
);
|
||||
}
|
||||
}
|
||||
return($r);
|
||||
}
|
||||
|
||||
|
||||
static public function app_decode($s) {
|
||||
$x = base64_decode(str_replace(array('<br />',"\r","\n",' '),array('','','',''),$s));
|
||||
return json_decode($x,true);
|
||||
}
|
||||
|
||||
|
||||
static public function app_store($arr) {
|
||||
|
||||
// logger('app_store: ' . print_r($arr,true));
|
||||
|
||||
$darray = array();
|
||||
$ret = array('success' => false);
|
||||
|
||||
$darray['app_url'] = ((x($arr,'url')) ? $arr['url'] : '');
|
||||
$darray['app_channel'] = ((x($arr,'uid')) ? $arr['uid'] : 0);
|
||||
|
||||
if((! $darray['app_url']) || (! $darray['app_channel']))
|
||||
return $ret;
|
||||
|
||||
if($arr['photo'] && ! strstr($arr['photo'],z_root())) {
|
||||
$x = import_xchan_photo($arr['photo'],get_observer_hash(),true);
|
||||
$arr['photo'] = $x[1];
|
||||
}
|
||||
|
||||
|
||||
$darray['app_id'] = ((x($arr,'guid')) ? $arr['guid'] : random_string(). '.' . \App::get_hostname());
|
||||
$darray['app_sig'] = ((x($arr,'sig')) ? $arr['sig'] : '');
|
||||
$darray['app_author'] = ((x($arr,'author')) ? $arr['author'] : get_observer_hash());
|
||||
$darray['app_name'] = ((x($arr,'name')) ? escape_tags($arr['name']) : t('Unknown'));
|
||||
$darray['app_desc'] = ((x($arr,'desc')) ? escape_tags($arr['desc']) : '');
|
||||
$darray['app_photo'] = ((x($arr,'photo')) ? $arr['photo'] : z_root() . '/' . get_default_profile_photo(80));
|
||||
$darray['app_version'] = ((x($arr,'version')) ? escape_tags($arr['version']) : '');
|
||||
$darray['app_addr'] = ((x($arr,'addr')) ? escape_tags($arr['addr']) : '');
|
||||
$darray['app_price'] = ((x($arr,'price')) ? escape_tags($arr['price']) : '');
|
||||
$darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : '');
|
||||
$darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : '');
|
||||
$darray['app_system'] = ((x($arr,'system')) ? intval($arr['system']) : 0);
|
||||
$darray['app_deleted'] = ((x($arr,'deleted')) ? intval($arr['deleted']) : 0);
|
||||
|
||||
$created = datetime_convert();
|
||||
|
||||
$r = q("insert into app ( app_id, app_sig, app_author, app_name, app_desc, app_url, app_photo, app_version, app_channel, app_addr, app_price, app_page, app_requires, app_created, app_edited, app_system, app_deleted ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, %d )",
|
||||
dbesc($darray['app_id']),
|
||||
dbesc($darray['app_sig']),
|
||||
dbesc($darray['app_author']),
|
||||
dbesc($darray['app_name']),
|
||||
dbesc($darray['app_desc']),
|
||||
dbesc($darray['app_url']),
|
||||
dbesc($darray['app_photo']),
|
||||
dbesc($darray['app_version']),
|
||||
intval($darray['app_channel']),
|
||||
dbesc($darray['app_addr']),
|
||||
dbesc($darray['app_price']),
|
||||
dbesc($darray['app_page']),
|
||||
dbesc($darray['app_requires']),
|
||||
dbesc($created),
|
||||
dbesc($created),
|
||||
intval($darray['app_system']),
|
||||
intval($darray['app_deleted'])
|
||||
);
|
||||
if($r) {
|
||||
$ret['success'] = true;
|
||||
$ret['app_id'] = $darray['app_id'];
|
||||
}
|
||||
if($arr['categories']) {
|
||||
$x = q("select id from app where app_id = '%s' and app_channel = %d limit 1",
|
||||
dbesc($darray['app_id']),
|
||||
intval($darray['app_channel'])
|
||||
);
|
||||
$y = explode(',',$arr['categories']);
|
||||
if($y) {
|
||||
foreach($y as $t) {
|
||||
$t = trim($t);
|
||||
if($t) {
|
||||
store_item_tag($darray['app_channel'],$x[0]['id'],TERM_OBJ_APP,TERM_CATEGORY,escape_tags($t),escape_tags(z_root() . '/apps/?f=&cat=' . escape_tags($t)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
static public function app_update($arr) {
|
||||
|
||||
$darray = array();
|
||||
$ret = array('success' => false);
|
||||
|
||||
$darray['app_url'] = ((x($arr,'url')) ? $arr['url'] : '');
|
||||
$darray['app_channel'] = ((x($arr,'uid')) ? $arr['uid'] : 0);
|
||||
$darray['app_id'] = ((x($arr,'guid')) ? $arr['guid'] : 0);
|
||||
|
||||
if((! $darray['app_url']) || (! $darray['app_channel']) || (! $darray['app_id']))
|
||||
return $ret;
|
||||
|
||||
if($arr['photo'] && ! strstr($arr['photo'],z_root())) {
|
||||
$x = import_xchan_photo($arr['photo'],get_observer_hash(),true);
|
||||
$arr['photo'] = $x[1];
|
||||
}
|
||||
|
||||
$darray['app_sig'] = ((x($arr,'sig')) ? $arr['sig'] : '');
|
||||
$darray['app_author'] = ((x($arr,'author')) ? $arr['author'] : get_observer_hash());
|
||||
$darray['app_name'] = ((x($arr,'name')) ? escape_tags($arr['name']) : t('Unknown'));
|
||||
$darray['app_desc'] = ((x($arr,'desc')) ? escape_tags($arr['desc']) : '');
|
||||
$darray['app_photo'] = ((x($arr,'photo')) ? $arr['photo'] : z_root() . '/' . get_default_profile_photo(80));
|
||||
$darray['app_version'] = ((x($arr,'version')) ? escape_tags($arr['version']) : '');
|
||||
$darray['app_addr'] = ((x($arr,'addr')) ? escape_tags($arr['addr']) : '');
|
||||
$darray['app_price'] = ((x($arr,'price')) ? escape_tags($arr['price']) : '');
|
||||
$darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : '');
|
||||
$darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : '');
|
||||
$darray['app_system'] = ((x($arr,'system')) ? intval($arr['system']) : 0);
|
||||
$darray['app_deleted'] = ((x($arr,'deleted')) ? intval($arr['deleted']) : 0);
|
||||
|
||||
$edited = datetime_convert();
|
||||
|
||||
$r = q("update app set app_sig = '%s', app_author = '%s', app_name = '%s', app_desc = '%s', app_url = '%s', app_photo = '%s', app_version = '%s', app_addr = '%s', app_price = '%s', app_page = '%s', app_requires = '%s', app_edited = '%s', app_system = %d, app_deleted = %d where app_id = '%s' and app_channel = %d",
|
||||
dbesc($darray['app_sig']),
|
||||
dbesc($darray['app_author']),
|
||||
dbesc($darray['app_name']),
|
||||
dbesc($darray['app_desc']),
|
||||
dbesc($darray['app_url']),
|
||||
dbesc($darray['app_photo']),
|
||||
dbesc($darray['app_version']),
|
||||
dbesc($darray['app_addr']),
|
||||
dbesc($darray['app_price']),
|
||||
dbesc($darray['app_page']),
|
||||
dbesc($darray['app_requires']),
|
||||
dbesc($edited),
|
||||
intval($darray['app_system']),
|
||||
intval($darray['app_deleted']),
|
||||
dbesc($darray['app_id']),
|
||||
intval($darray['app_channel'])
|
||||
);
|
||||
if($r) {
|
||||
$ret['success'] = true;
|
||||
$ret['app_id'] = $darray['app_id'];
|
||||
}
|
||||
|
||||
$x = q("select id from app where app_id = '%s' and app_channel = %d limit 1",
|
||||
dbesc($darray['app_id']),
|
||||
intval($darray['app_channel'])
|
||||
);
|
||||
if($x) {
|
||||
q("delete from term where otype = %d and oid = %d",
|
||||
intval(TERM_OBJ_APP),
|
||||
intval($x[0]['id'])
|
||||
);
|
||||
if($arr['categories']) {
|
||||
$y = explode(',',$arr['categories']);
|
||||
if($y) {
|
||||
foreach($y as $t) {
|
||||
$t = trim($t);
|
||||
if($t) {
|
||||
store_item_tag($darray['app_channel'],$x[0]['id'],TERM_OBJ_APP,TERM_CATEGORY,escape_tags($t),escape_tags(z_root() . '/apps/?f=&cat=' . escape_tags($t)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static public function app_encode($app,$embed = false) {
|
||||
|
||||
$ret = array();
|
||||
|
||||
$ret['type'] = 'personal';
|
||||
|
||||
if($app['app_id'])
|
||||
$ret['guid'] = $app['app_id'];
|
||||
|
||||
if($app['app_id'])
|
||||
$ret['guid'] = $app['app_id'];
|
||||
|
||||
if($app['app_sig'])
|
||||
$ret['sig'] = $app['app_sig'];
|
||||
|
||||
if($app['app_author'])
|
||||
$ret['author'] = $app['app_author'];
|
||||
|
||||
if($app['app_name'])
|
||||
$ret['name'] = $app['app_name'];
|
||||
|
||||
if($app['app_desc'])
|
||||
$ret['desc'] = $app['app_desc'];
|
||||
|
||||
if($app['app_url'])
|
||||
$ret['url'] = $app['app_url'];
|
||||
|
||||
if($app['app_photo'])
|
||||
$ret['photo'] = $app['app_photo'];
|
||||
|
||||
if($app['app_version'])
|
||||
$ret['version'] = $app['app_version'];
|
||||
|
||||
if($app['app_addr'])
|
||||
$ret['addr'] = $app['app_addr'];
|
||||
|
||||
if($app['app_price'])
|
||||
$ret['price'] = $app['app_price'];
|
||||
|
||||
if($app['app_page'])
|
||||
$ret['page'] = $app['app_page'];
|
||||
|
||||
if($app['app_requires'])
|
||||
$ret['requires'] = $app['app_requires'];
|
||||
|
||||
if($app['app_system'])
|
||||
$ret['system'] = $app['app_system'];
|
||||
|
||||
if($app['app_deleted'])
|
||||
$ret['deleted'] = $app['app_deleted'];
|
||||
|
||||
if($app['term']) {
|
||||
$s = '';
|
||||
foreach($app['term'] as $t) {
|
||||
if($s)
|
||||
$s .= ',';
|
||||
$s .= $t['term'];
|
||||
}
|
||||
$ret['categories'] = $s;
|
||||
}
|
||||
|
||||
|
||||
if(! $embed)
|
||||
return $ret;
|
||||
|
||||
if(array_key_exists('categories',$ret))
|
||||
unset($ret['categories']);
|
||||
|
||||
$j = json_encode($ret);
|
||||
return '[app]' . chunk_split(base64_encode($j),72,"\n") . '[/app]';
|
||||
|
||||
}
|
||||
|
||||
|
||||
static public function papp_encode($papp) {
|
||||
return chunk_split(base64_encode(json_encode($papp)),72,"\n");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
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")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
267
Zotlabs/Lib/Chatroom.php
Normal file
267
Zotlabs/Lib/Chatroom.php
Normal file
@@ -0,0 +1,267 @@
|
||||
<?php
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
/**
|
||||
* @brief Chat related functions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
class Chatroom {
|
||||
/**
|
||||
* @brief Creates a chatroom.
|
||||
*
|
||||
* @param array $channel
|
||||
* @param array $arr
|
||||
* @return An associative array containing:
|
||||
* - success: A boolean
|
||||
* - message: (optional) A string
|
||||
*/
|
||||
|
||||
static public function create($channel, $arr) {
|
||||
|
||||
$ret = array('success' => false);
|
||||
|
||||
$name = trim($arr['name']);
|
||||
if(! $name) {
|
||||
$ret['message'] = t('Missing room name');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$r = q("select cr_id from chatroom where cr_uid = %d and cr_name = '%s' limit 1",
|
||||
intval($channel['channel_id']),
|
||||
dbesc($name)
|
||||
);
|
||||
if($r) {
|
||||
$ret['message'] = t('Duplicate room name');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$r = q("select count(cr_id) as total from chatroom where cr_aid = %d",
|
||||
intval($channel['channel_account_id'])
|
||||
);
|
||||
if($r)
|
||||
$limit = service_class_fetch($channel['channel_id'], 'chatrooms');
|
||||
|
||||
if(($r) && ($limit !== false) && ($r[0]['total'] >= $limit)) {
|
||||
$ret['message'] = upgrade_message();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if(! array_key_exists('expire', $arr))
|
||||
$arr['expire'] = 120; // minutes, e.g. 2 hours
|
||||
|
||||
$created = datetime_convert();
|
||||
|
||||
$x = q("insert into chatroom ( cr_aid, cr_uid, cr_name, cr_created, cr_edited, cr_expire, allow_cid, allow_gid, deny_cid, deny_gid )
|
||||
values ( %d, %d , '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s' ) ",
|
||||
intval($channel['channel_account_id']),
|
||||
intval($channel['channel_id']),
|
||||
dbesc($name),
|
||||
dbesc($created),
|
||||
dbesc($created),
|
||||
intval($arr['expire']),
|
||||
dbesc($arr['allow_cid']),
|
||||
dbesc($arr['allow_gid']),
|
||||
dbesc($arr['deny_cid']),
|
||||
dbesc($arr['deny_gid'])
|
||||
);
|
||||
|
||||
if($x)
|
||||
$ret['success'] = true;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
static public function destroy($channel,$arr) {
|
||||
|
||||
$ret = array('success' => false);
|
||||
|
||||
if(intval($arr['cr_id']))
|
||||
$sql_extra = " and cr_id = " . intval($arr['cr_id']) . " ";
|
||||
elseif(trim($arr['cr_name']))
|
||||
$sql_extra = " and cr_name = '" . protect_sprintf(dbesc(trim($arr['cr_name']))) . "' ";
|
||||
else {
|
||||
$ret['message'] = t('Invalid room specifier.');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$r = q("select * from chatroom where cr_uid = %d $sql_extra limit 1",
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if(! $r) {
|
||||
$ret['message'] = t('Invalid room specifier.');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
build_sync_packet($channel['channel_id'],array('chatroom' => $r));
|
||||
|
||||
q("delete from chatroom where cr_id = %d",
|
||||
intval($r[0]['cr_id'])
|
||||
);
|
||||
if($r[0]['cr_id']) {
|
||||
q("delete from chatpresence where cp_room = %d",
|
||||
intval($r[0]['cr_id'])
|
||||
);
|
||||
q("delete from chat where chat_room = %d",
|
||||
intval($r[0]['cr_id'])
|
||||
);
|
||||
}
|
||||
|
||||
$ret['success'] = true;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
static public function enter($observer_xchan, $room_id, $status, $client) {
|
||||
|
||||
if(! $room_id || ! $observer_xchan)
|
||||
return;
|
||||
|
||||
$r = q("select * from chatroom where cr_id = %d limit 1",
|
||||
intval($room_id)
|
||||
);
|
||||
if(! $r) {
|
||||
notice( t('Room not found.') . EOL);
|
||||
return false;
|
||||
}
|
||||
require_once('include/security.php');
|
||||
$sql_extra = permissions_sql($r[0]['cr_uid']);
|
||||
|
||||
$x = q("select * from chatroom where cr_id = %d and cr_uid = %d $sql_extra limit 1",
|
||||
intval($room_id),
|
||||
intval($r[0]['cr_uid'])
|
||||
);
|
||||
if(! $x) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return false;
|
||||
}
|
||||
|
||||
$limit = service_class_fetch($r[0]['cr_uid'], 'chatters_inroom');
|
||||
if($limit !== false) {
|
||||
$y = q("select count(*) as total from chatpresence where cp_room = %d",
|
||||
intval($room_id)
|
||||
);
|
||||
if($y && $y[0]['total'] > $limit) {
|
||||
notice( t('Room is full') . EOL);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(intval($x[0]['cr_expire'])) {
|
||||
$r = q("delete from chat where created < %s - INTERVAL %s and chat_room = %d",
|
||||
db_utcnow(),
|
||||
db_quoteinterval( intval($x[0]['cr_expire']) . ' MINUTE' ),
|
||||
intval($x[0]['cr_id'])
|
||||
);
|
||||
}
|
||||
|
||||
$r = q("select * from chatpresence where cp_xchan = '%s' and cp_room = %d limit 1",
|
||||
dbesc($observer_xchan),
|
||||
intval($room_id)
|
||||
);
|
||||
if($r) {
|
||||
q("update chatpresence set cp_last = '%s' where cp_id = %d and cp_client = '%s'",
|
||||
dbesc(datetime_convert()),
|
||||
intval($r[0]['cp_id']),
|
||||
dbesc($client)
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
$r = q("insert into chatpresence ( cp_room, cp_xchan, cp_last, cp_status, cp_client )
|
||||
values ( %d, '%s', '%s', '%s', '%s' )",
|
||||
intval($room_id),
|
||||
dbesc($observer_xchan),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($status),
|
||||
dbesc($client)
|
||||
);
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
function leave($observer_xchan, $room_id, $client) {
|
||||
if(! $room_id || ! $observer_xchan)
|
||||
return;
|
||||
|
||||
$r = q("select * from chatpresence where cp_xchan = '%s' and cp_room = %d and cp_client = '%s' limit 1",
|
||||
dbesc($observer_xchan),
|
||||
intval($room_id),
|
||||
dbesc($client)
|
||||
);
|
||||
if($r) {
|
||||
q("delete from chatpresence where cp_id = %d",
|
||||
intval($r[0]['cp_id'])
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static public function roomlist($uid) {
|
||||
require_once('include/security.php');
|
||||
$sql_extra = permissions_sql($uid);
|
||||
|
||||
$r = q("select allow_cid, allow_gid, deny_cid, deny_gid, cr_name, cr_expire, cr_id, count(cp_id) as cr_inroom from chatroom left join chatpresence on cr_id = cp_room where cr_uid = %d $sql_extra group by cr_name, cr_id order by cr_name",
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
static public function list_count($uid) {
|
||||
require_once('include/security.php');
|
||||
$sql_extra = permissions_sql($uid);
|
||||
|
||||
$r = q("select count(*) as total from chatroom where cr_uid = %d $sql_extra",
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
return $r[0]['total'];
|
||||
}
|
||||
|
||||
/**
|
||||
* create a chat message via API.
|
||||
* It is the caller's responsibility to enter the room.
|
||||
*/
|
||||
|
||||
static public function message($uid, $room_id, $xchan, $text) {
|
||||
|
||||
$ret = array('success' => false);
|
||||
|
||||
if(! $text)
|
||||
return;
|
||||
|
||||
$sql_extra = permissions_sql($uid);
|
||||
|
||||
$r = q("select * from chatroom where cr_uid = %d and cr_id = %d $sql_extra",
|
||||
intval($uid),
|
||||
intval($room_id)
|
||||
);
|
||||
if(! $r)
|
||||
return $ret;
|
||||
|
||||
$arr = array(
|
||||
'chat_room' => $room_id,
|
||||
'chat_xchan' => $xchan,
|
||||
'chat_text' => $text
|
||||
);
|
||||
|
||||
call_hooks('chat_message', $arr);
|
||||
|
||||
$x = q("insert into chat ( chat_room, chat_xchan, created, chat_text )
|
||||
values( %d, '%s', '%s', '%s' )",
|
||||
intval($room_id),
|
||||
dbesc($xchan),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($arr['chat_text'])
|
||||
);
|
||||
|
||||
$ret['success'] = true;
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
166
Zotlabs/Lib/Config.php
Normal file
166
Zotlabs/Lib/Config.php
Normal file
@@ -0,0 +1,166 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
|
||||
class Config {
|
||||
|
||||
/**
|
||||
* @brief Loads the hub's configuration from database to a cached storage.
|
||||
*
|
||||
* Retrieve a category ($family) of config variables from database to a cached
|
||||
* storage in the global App::$config[$family].
|
||||
*
|
||||
* @param string $family
|
||||
* The category of the configuration value
|
||||
*/
|
||||
|
||||
static public function Load($family) {
|
||||
if(! array_key_exists($family, \App::$config))
|
||||
\App::$config[$family] = array();
|
||||
|
||||
if(! array_key_exists('config_loaded', \App::$config[$family])) {
|
||||
$r = q("SELECT * FROM config WHERE cat = '%s'", dbesc($family));
|
||||
if($r !== false) {
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$k = $rr['k'];
|
||||
\App::$config[$family][$k] = $rr['v'];
|
||||
}
|
||||
}
|
||||
\App::$config[$family]['config_loaded'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a configuration value for the hub.
|
||||
*
|
||||
* Stores a config value ($value) in the category ($family) under the key ($key).
|
||||
*
|
||||
* @param string $family
|
||||
* The category of the configuration value
|
||||
* @param string $key
|
||||
* The configuration key to set
|
||||
* @param mixed $value
|
||||
* The value to store in the configuration
|
||||
* @return mixed
|
||||
* Return the set value, or false if the database update failed
|
||||
*/
|
||||
|
||||
static public function Set($family,$key,$value) {
|
||||
// manage array value
|
||||
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
|
||||
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
|
||||
|
||||
if(get_config($family, $key) === false || (! self::get_from_storage($family, $key))) {
|
||||
$ret = q("INSERT INTO config ( cat, k, v ) VALUES ( '%s', '%s', '%s' ) ",
|
||||
dbesc($family),
|
||||
dbesc($key),
|
||||
dbesc($dbvalue)
|
||||
);
|
||||
if($ret) {
|
||||
\App::$config[$family][$key] = $value;
|
||||
$ret = $value;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$ret = q("UPDATE config SET v = '%s' WHERE cat = '%s' AND k = '%s'",
|
||||
dbesc($dbvalue),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
if($ret) {
|
||||
\App::$config[$family][$key] = $value;
|
||||
$ret = $value;
|
||||
}
|
||||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a particular config variable given the category name ($family)
|
||||
* and a key.
|
||||
*
|
||||
* Get a particular config variable from the given category ($family) and the
|
||||
* $key from a cached storage in App::$config[$family]. If a key is found in the
|
||||
* DB but does not exist in local config cache, pull it into the cache so we
|
||||
* do not have to hit the DB again for this item.
|
||||
*
|
||||
* Returns false if not set.
|
||||
*
|
||||
* @param string $family
|
||||
* The category of the configuration value
|
||||
* @param string $key
|
||||
* The configuration key to query
|
||||
* @return mixed Return value or false on error or if not set
|
||||
*/
|
||||
|
||||
static public function Get($family,$key) {
|
||||
if((! array_key_exists($family, \App::$config)) || (! array_key_exists('config_loaded', \App::$config[$family])))
|
||||
self::Load($family);
|
||||
|
||||
if(array_key_exists('config_loaded', \App::$config[$family])) {
|
||||
if(! array_key_exists($key, \App::$config[$family])) {
|
||||
return false;
|
||||
}
|
||||
return ((! is_array(\App::$config[$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$family][$key]))
|
||||
? unserialize(\App::$config[$family][$key])
|
||||
: \App::$config[$family][$key]
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deletes the given key from the hub's configuration database.
|
||||
*
|
||||
* Removes the configured value from the stored cache in App::$config[$family]
|
||||
* and removes it from the database.
|
||||
*
|
||||
* @param string $family
|
||||
* The category of the configuration value
|
||||
* @param string $key
|
||||
* The configuration key to delete
|
||||
* @return mixed
|
||||
*/
|
||||
|
||||
static public function Delete($family,$key) {
|
||||
|
||||
$ret = false;
|
||||
|
||||
if(array_key_exists($family, \App::$config) && array_key_exists($key, \App::$config[$family]))
|
||||
unset(\App::$config[$family][$key]);
|
||||
$ret = q("DELETE FROM config WHERE cat = '%s' AND k = '%s'",
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Returns a value directly from the database configuration storage.
|
||||
*
|
||||
* This function queries directly the database and bypasses the chached storage
|
||||
* from get_config($family, $key).
|
||||
*
|
||||
* @param string $family
|
||||
* The category of the configuration value
|
||||
* @param string $key
|
||||
* The configuration key to query
|
||||
* @return mixed
|
||||
*/
|
||||
|
||||
static private function get_from_storage($family,$key) {
|
||||
$ret = q("SELECT * FROM config WHERE cat = '%s' AND k = '%s' LIMIT 1",
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
}
|
||||
685
Zotlabs/Lib/Enotify.php
Normal file
685
Zotlabs/Lib/Enotify.php
Normal file
@@ -0,0 +1,685 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
/**
|
||||
* @brief File with functions and a class for generating system and email notifications.
|
||||
*/
|
||||
|
||||
|
||||
class Enotify {
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param array $params an assoziative array with:
|
||||
* * \e string \b from_xchan sender xchan hash
|
||||
* * \e string \b to_xchan recipient xchan hash
|
||||
* * \e array \b item an assoziative array
|
||||
* * \e int \b type one of the NOTIFY_* constants from boot.php
|
||||
* * \e string \b link
|
||||
* * \e string \b parent_mid
|
||||
* * \e string \b otype
|
||||
* * \e string \b verb
|
||||
* * \e string \b activity
|
||||
*/
|
||||
|
||||
|
||||
static public function submit($params) {
|
||||
|
||||
logger('notification: entry', LOGGER_DEBUG);
|
||||
|
||||
// throw a small amount of entropy into the system to breakup duplicates arriving at the same precise instant.
|
||||
usleep(mt_rand(0, 10000));
|
||||
|
||||
if ($params['from_xchan']) {
|
||||
$x = q("select * from xchan where xchan_hash = '%s' limit 1",
|
||||
dbesc($params['from_xchan'])
|
||||
);
|
||||
}
|
||||
if ($params['to_xchan']) {
|
||||
$y = q("select channel.*, account.* from channel left join account on channel_account_id = account_id
|
||||
where channel_hash = '%s' and channel_removed = 0 limit 1",
|
||||
dbesc($params['to_xchan'])
|
||||
);
|
||||
}
|
||||
if ($x & $y) {
|
||||
$sender = $x[0];
|
||||
$recip = $y[0];
|
||||
} else {
|
||||
logger('notification: no sender or recipient.');
|
||||
logger('sender: ' . $params['from_xchan']);
|
||||
logger('recip: ' . $params['to_xchan']);
|
||||
return;
|
||||
}
|
||||
|
||||
// from here on everything is in the recipients language
|
||||
|
||||
push_lang($recip['account_language']); // should probably have a channel language
|
||||
|
||||
$banner = t('$Projectname Notification');
|
||||
$product = t('$projectname'); // PLATFORM_NAME;
|
||||
$siteurl = z_root();
|
||||
$thanks = t('Thank You,');
|
||||
$sitename = get_config('system','sitename');
|
||||
$site_admin = sprintf( t('%s Administrator'), $sitename);
|
||||
|
||||
$sender_name = $product;
|
||||
$hostname = \App::get_hostname();
|
||||
if(strpos($hostname,':'))
|
||||
$hostname = substr($hostname,0,strpos($hostname,':'));
|
||||
|
||||
// Do not translate 'noreply' as it must be a legal 7-bit email address
|
||||
$sender_email = 'noreply' . '@' . $hostname;
|
||||
|
||||
$additional_mail_header = "";
|
||||
|
||||
if(array_key_exists('item', $params)) {
|
||||
require_once('include/conversation.php');
|
||||
// if it's a normal item...
|
||||
if (array_key_exists('verb', $params['item'])) {
|
||||
// localize_item() alters the original item so make a copy first
|
||||
$i = $params['item'];
|
||||
logger('calling localize');
|
||||
localize_item($i);
|
||||
$title = $i['title'];
|
||||
$body = $i['body'];
|
||||
$private = (($i['item_private']) || intval($i['item_obscured']));
|
||||
}
|
||||
else {
|
||||
$title = $params['item']['title'];
|
||||
$body = $params['item']['body'];
|
||||
}
|
||||
}
|
||||
else {
|
||||
$title = $body = '';
|
||||
}
|
||||
|
||||
|
||||
// e.g. "your post", "David's photo", etc.
|
||||
$possess_desc = t('%s <!item_type!>');
|
||||
|
||||
if ($params['type'] == NOTIFY_MAIL) {
|
||||
logger('notification: mail');
|
||||
$subject = sprintf( t('[Hubzilla:Notify] New mail received at %s'),$sitename);
|
||||
|
||||
$preamble = sprintf( t('%1$s, %2$s sent you a new private message at %3$s.'),$recip['channel_name'], $sender['xchan_name'],$sitename);
|
||||
$epreamble = sprintf( t('%1$s sent you %2$s.'),'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', '[zrl=$itemlink]' . t('a private message') . '[/zrl]');
|
||||
$sitelink = t('Please visit %s to view and/or reply to your private messages.');
|
||||
$tsitelink = sprintf( $sitelink, $siteurl . '/mail/' . $params['item']['id'] );
|
||||
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '/mail/' . $params['item']['id'] . '">' . $sitename . '</a>');
|
||||
$itemlink = $siteurl . '/mail/' . $params['item']['id'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_COMMENT) {
|
||||
// logger("notification: params = " . print_r($params, true), LOGGER_DEBUG);
|
||||
|
||||
$itemlink = $params['link'];
|
||||
|
||||
// ignore like/unlike activity on posts - they probably require a sepearate notification preference
|
||||
|
||||
if (array_key_exists('item',$params) && (! visible_activity($params['item'])))
|
||||
return;
|
||||
|
||||
$parent_mid = $params['parent_mid'];
|
||||
|
||||
// Check to see if there was already a notify for this post.
|
||||
// If so don't create a second notification
|
||||
|
||||
$p = null;
|
||||
$p = q("select id from notify where link = '%s' and uid = %d limit 1",
|
||||
dbesc($params['link']),
|
||||
intval($recip['channel_id'])
|
||||
);
|
||||
if ($p) {
|
||||
logger('notification: comment already notified');
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// if it's a post figure out who's post it is.
|
||||
|
||||
$p = null;
|
||||
|
||||
if($params['otype'] === 'item' && $parent_mid) {
|
||||
$p = q("select * from item where mid = '%s' and uid = %d limit 1",
|
||||
dbesc($parent_mid),
|
||||
intval($recip['channel_id'])
|
||||
);
|
||||
}
|
||||
|
||||
xchan_query($p);
|
||||
|
||||
|
||||
$item_post_type = item_post_type($p[0]);
|
||||
// $private = $p[0]['item_private'];
|
||||
$parent_id = $p[0]['id'];
|
||||
|
||||
$parent_item = $p[0];
|
||||
|
||||
//$possess_desc = str_replace('<!item_type!>',$possess_desc);
|
||||
|
||||
// "a post"
|
||||
$dest_str = sprintf(t('%1$s, %2$s commented on [zrl=%3$s]a %4$s[/zrl]'),
|
||||
$recip['channel_name'],
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
|
||||
$itemlink,
|
||||
$item_post_type);
|
||||
|
||||
// "George Bull's post"
|
||||
if($p)
|
||||
$dest_str = sprintf(t('%1$s, %2$s commented on [zrl=%3$s]%4$s\'s %5$s[/zrl]'),
|
||||
$recip['channel_name'],
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
|
||||
$itemlink,
|
||||
$p[0]['author']['xchan_name'],
|
||||
$item_post_type);
|
||||
|
||||
// "your post"
|
||||
if($p[0]['owner']['xchan_name'] == $p[0]['author']['xchan_name'] && intval($p[0]['item_wall']))
|
||||
$dest_str = sprintf(t('%1$s, %2$s commented on [zrl=%3$s]your %4$s[/zrl]'),
|
||||
$recip['channel_name'],
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
|
||||
$itemlink,
|
||||
$item_post_type);
|
||||
|
||||
// Some mail softwares relies on subject field for threading.
|
||||
// So, we cannot have different subjects for notifications of the same thread.
|
||||
// Before this we have the name of the replier on the subject rendering
|
||||
// differents subjects for messages on the same thread.
|
||||
|
||||
$subject = sprintf( t('[Hubzilla:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
|
||||
$preamble = sprintf( t('%1$s, %2$s commented on an item/conversation you have been following.'), $recip['channel_name'], $sender['xchan_name']);
|
||||
$epreamble = $dest_str;
|
||||
|
||||
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
|
||||
$tsitelink = sprintf( $sitelink, $siteurl );
|
||||
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
|
||||
}
|
||||
|
||||
if($params['type'] == NOTIFY_WALL) {
|
||||
$subject = sprintf( t('[Hubzilla:Notify] %s posted to your profile wall') , $sender['xchan_name']);
|
||||
|
||||
$preamble = sprintf( t('%1$s, %2$s posted to your profile wall at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename);
|
||||
|
||||
$epreamble = sprintf( t('%1$s, %2$s posted to [zrl=%3$s]your wall[/zrl]') ,
|
||||
$recip['channel_name'],
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
|
||||
$params['link']);
|
||||
|
||||
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
|
||||
$tsitelink = sprintf( $sitelink, $siteurl );
|
||||
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_TAGSELF) {
|
||||
|
||||
$p = null;
|
||||
$p = q("select id from notify where link = '%s' and uid = %d limit 1",
|
||||
dbesc($params['link']),
|
||||
intval($recip['channel_id'])
|
||||
);
|
||||
if ($p) {
|
||||
logger('enotify: tag: already notified about this post');
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
|
||||
$subject = sprintf( t('[Hubzilla:Notify] %s tagged you') , $sender['xchan_name']);
|
||||
$preamble = sprintf( t('%1$s, %2$s tagged you at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename);
|
||||
$epreamble = sprintf( t('%1$s, %2$s [zrl=%3$s]tagged you[/zrl].') ,
|
||||
$recip['channel_name'],
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
|
||||
$params['link']);
|
||||
|
||||
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
|
||||
$tsitelink = sprintf( $sitelink, $siteurl );
|
||||
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_POKE) {
|
||||
$subject = sprintf( t('[Hubzilla:Notify] %1$s poked you') , $sender['xchan_name']);
|
||||
$preamble = sprintf( t('%1$s, %2$s poked you at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename);
|
||||
$epreamble = sprintf( t('%1$s, %2$s [zrl=%2$s]poked you[/zrl].') ,
|
||||
$recip['channel_name'],
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
|
||||
$params['link']);
|
||||
|
||||
$subject = str_replace('poked', t($params['activity']), $subject);
|
||||
$preamble = str_replace('poked', t($params['activity']), $preamble);
|
||||
$epreamble = str_replace('poked', t($params['activity']), $epreamble);
|
||||
|
||||
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
|
||||
$tsitelink = sprintf( $sitelink, $siteurl );
|
||||
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_TAGSHARE) {
|
||||
$subject = sprintf( t('[Hubzilla:Notify] %s tagged your post') , $sender['xchan_name']);
|
||||
$preamble = sprintf( t('%1$s, %2$s tagged your post at %3$s') , $recip['channel_name'],$sender['xchan_name'], $sitename);
|
||||
$epreamble = sprintf( t('%1$s, %2$s tagged [zrl=%3$s]your post[/zrl]') ,
|
||||
$recip['channel_name'],
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
|
||||
$itemlink);
|
||||
|
||||
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
|
||||
$tsitelink = sprintf( $sitelink, $siteurl );
|
||||
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_INTRO) {
|
||||
$subject = sprintf( t('[Hubzilla:Notify] Introduction received'));
|
||||
$preamble = sprintf( t('%1$s, you\'ve received an new connection request from \'%2$s\' at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename);
|
||||
$epreamble = sprintf( t('%1$s, you\'ve received [zrl=%2$s]a new connection request[/zrl] from %3$s.'),
|
||||
$recip['channel_name'],
|
||||
$siteurl . '/connections/ifpending',
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]');
|
||||
$body = sprintf( t('You may visit their profile at %s'),$sender['xchan_url']);
|
||||
|
||||
$sitelink = t('Please visit %s to approve or reject the connection request.');
|
||||
$tsitelink = sprintf( $sitelink, $siteurl . '/connections/ifpending');
|
||||
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '/connections/ifpending">' . $sitename . '</a>');
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_SUGGEST) {
|
||||
$subject = sprintf( t('[Hubzilla:Notify] Friend suggestion received'));
|
||||
$preamble = sprintf( t('%1$s, you\'ve received a friend suggestion from \'%2$s\' at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename);
|
||||
$epreamble = sprintf( t('%1$s, you\'ve received [zrl=%2$s]a friend suggestion[/zrl] for %3$s from %4$s.'),
|
||||
$recip['channel_name'],
|
||||
$itemlink,
|
||||
'[zrl=' . $params['item']['url'] . ']' . $params['item']['name'] . '[/zrl]',
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]');
|
||||
|
||||
$body = t('Name:') . ' ' . $params['item']['name'] . "\n";
|
||||
$body .= t('Photo:') . ' ' . $params['item']['photo'] . "\n";
|
||||
$body .= sprintf( t('You may visit their profile at %s'),$params['item']['url']);
|
||||
|
||||
$sitelink = t('Please visit %s to approve or reject the suggestion.');
|
||||
$tsitelink = sprintf( $sitelink, $siteurl );
|
||||
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_CONFIRM) {
|
||||
// ?
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_SYSTEM) {
|
||||
// ?
|
||||
}
|
||||
|
||||
$h = array(
|
||||
'params' => $params,
|
||||
'subject' => $subject,
|
||||
'preamble' => $preamble,
|
||||
'epreamble' => $epreamble,
|
||||
'body' => $body,
|
||||
'sitelink' => $sitelink,
|
||||
'sitename' => $sitename,
|
||||
'tsitelink' => $tsitelink,
|
||||
'hsitelink' => $hsitelink,
|
||||
'itemlink' => $itemlink,
|
||||
'sender' => $sender,
|
||||
'recipient' => $recip
|
||||
);
|
||||
|
||||
call_hooks('enotify', $h);
|
||||
|
||||
$subject = $h['subject'];
|
||||
$preamble = $h['preamble'];
|
||||
$epreamble = $h['epreamble'];
|
||||
$body = $h['body'];
|
||||
$sitelink = $h['sitelink'];
|
||||
$tsitelink = $h['tsitelink'];
|
||||
$hsitelink = $h['hsitelink'];
|
||||
$itemlink = $h['itemlink'];
|
||||
|
||||
|
||||
require_once('include/html2bbcode.php');
|
||||
|
||||
do {
|
||||
$dups = false;
|
||||
$hash = random_string();
|
||||
$r = q("SELECT `id` FROM `notify` WHERE `hash` = '%s' LIMIT 1",
|
||||
dbesc($hash));
|
||||
if ($r)
|
||||
$dups = true;
|
||||
} while ($dups === true);
|
||||
|
||||
|
||||
$datarray = array();
|
||||
$datarray['hash'] = $hash;
|
||||
$datarray['sender_hash'] = $sender['xchan_hash'];
|
||||
$datarray['xname'] = $sender['xchan_name'];
|
||||
$datarray['url'] = $sender['xchan_url'];
|
||||
$datarray['photo'] = $sender['xchan_photo_s'];
|
||||
$datarray['created'] = datetime_convert();
|
||||
$datarray['aid'] = $recip['channel_account_id'];
|
||||
$datarray['uid'] = $recip['channel_id'];
|
||||
$datarray['link'] = $itemlink;
|
||||
$datarray['parent'] = $parent_mid;
|
||||
$datarray['parent_item'] = $parent_item;
|
||||
$datarray['ntype'] = $params['type'];
|
||||
$datarray['verb'] = $params['verb'];
|
||||
$datarray['otype'] = $params['otype'];
|
||||
$datarray['abort'] = false;
|
||||
|
||||
$datarray['item'] = $params['item'];
|
||||
|
||||
call_hooks('enotify_store', $datarray);
|
||||
|
||||
if ($datarray['abort']) {
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// create notification entry in DB
|
||||
$seen = 0;
|
||||
|
||||
// Mark some notifications as seen right away
|
||||
// Note! The notification have to be created, because they are used to send emails
|
||||
// So easiest solution to hide them from Notices is to mark them as seen right away.
|
||||
// Another option would be to not add them to the DB, and change how emails are handled (probably would be better that way)
|
||||
$always_show_in_notices = get_pconfig($recip['channel_id'],'system','always_show_in_notices');
|
||||
if (!$always_show_in_notices) {
|
||||
if (($params['type'] == NOTIFY_WALL) || ($params['type'] == NOTIFY_MAIL) || ($params['type'] == NOTIFY_INTRO)) {
|
||||
$seen = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$r = q("insert into notify (hash,xname,url,photo,created,aid,uid,link,parent,seen,ntype,verb,otype)
|
||||
values('%s','%s','%s','%s','%s',%d,%d,'%s','%s',%d,%d,'%s','%s')",
|
||||
dbesc($datarray['hash']),
|
||||
dbesc($datarray['xname']),
|
||||
dbesc($datarray['url']),
|
||||
dbesc($datarray['photo']),
|
||||
dbesc($datarray['created']),
|
||||
intval($datarray['aid']),
|
||||
intval($datarray['uid']),
|
||||
dbesc($datarray['link']),
|
||||
dbesc($datarray['parent']),
|
||||
intval($seen),
|
||||
intval($datarray['ntype']),
|
||||
dbesc($datarray['verb']),
|
||||
dbesc($datarray['otype'])
|
||||
);
|
||||
|
||||
$r = q("select id from notify where hash = '%s' and uid = %d limit 1",
|
||||
dbesc($hash),
|
||||
intval($recip['channel_id'])
|
||||
);
|
||||
if ($r) {
|
||||
$notify_id = $r[0]['id'];
|
||||
} else {
|
||||
logger('notification not found.');
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
|
||||
$itemlink = z_root() . '/notify/view/' . $notify_id;
|
||||
$msg = str_replace('$itemlink',$itemlink,$epreamble);
|
||||
|
||||
// wretched hack, but we don't want to duplicate all the preamble variations and we also don't want to screw up a translation
|
||||
|
||||
if ((\App::$language === 'en' || (! \App::$language)) && strpos($msg,', '))
|
||||
$msg = substr($msg,strpos($msg,', ')+1);
|
||||
|
||||
$r = q("update notify set msg = '%s' where id = %d and uid = %d",
|
||||
dbesc($msg),
|
||||
intval($notify_id),
|
||||
intval($datarray['uid'])
|
||||
);
|
||||
|
||||
// send email notification if notification preferences permit
|
||||
|
||||
require_once('bbcode.php');
|
||||
if ((intval($recip['channel_notifyflags']) & intval($params['type'])) || $params['type'] == NOTIFY_SYSTEM) {
|
||||
|
||||
logger('notification: sending notification email');
|
||||
|
||||
$hn = get_pconfig($recip['channel_id'],'system','email_notify_host');
|
||||
if($hn && (! stristr(\App::get_hostname(),$hn))) {
|
||||
// this isn't the email notification host
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
|
||||
$textversion = strip_tags(html_entity_decode(bbcode(stripslashes(str_replace(array("\\r", "\\n"), array( "", "\n"), $body))),ENT_QUOTES,'UTF-8'));
|
||||
|
||||
$htmlversion = bbcode(stripslashes(str_replace(array("\\r","\\n"), array("","<br />\n"),$body)));
|
||||
|
||||
|
||||
// use $_SESSION['zid_override'] to force zid() to use
|
||||
// the recipient address instead of the current observer
|
||||
|
||||
$_SESSION['zid_override'] = $recip['channel_address'] . '@' . \App::get_hostname();
|
||||
$_SESSION['zrl_override'] = z_root() . '/channel/' . $recip['channel_address'];
|
||||
|
||||
$textversion = zidify_links($textversion);
|
||||
$htmlversion = zidify_links($htmlversion);
|
||||
|
||||
// unset when done to revert to normal behaviour
|
||||
|
||||
unset($_SESSION['zid_override']);
|
||||
unset($_SESSION['zrl_override']);
|
||||
|
||||
$datarray = array();
|
||||
$datarray['banner'] = $banner;
|
||||
$datarray['product'] = $product;
|
||||
$datarray['preamble'] = $preamble;
|
||||
$datarray['sitename'] = $sitename;
|
||||
$datarray['siteurl'] = $siteurl;
|
||||
$datarray['type'] = $params['type'];
|
||||
$datarray['parent'] = $params['parent_mid'];
|
||||
$datarray['source_name'] = $sender['xchan_name'];
|
||||
$datarray['source_link'] = $sender['xchan_url'];
|
||||
$datarray['source_photo'] = $sender['xchan_photo_s'];
|
||||
$datarray['uid'] = $recip['channel_id'];
|
||||
$datarray['username'] = $recip['channel_name'];
|
||||
$datarray['hsitelink'] = $hsitelink;
|
||||
$datarray['tsitelink'] = $tsitelink;
|
||||
$datarray['hitemlink'] = '<a href="' . $itemlink . '">' . $itemlink . '</a>';
|
||||
$datarray['titemlink'] = $itemlink;
|
||||
$datarray['thanks'] = $thanks;
|
||||
$datarray['site_admin'] = $site_admin;
|
||||
$datarray['title'] = stripslashes($title);
|
||||
$datarray['htmlversion'] = $htmlversion;
|
||||
$datarray['textversion'] = $textversion;
|
||||
$datarray['subject'] = $subject;
|
||||
$datarray['headers'] = $additional_mail_header;
|
||||
$datarray['email_secure'] = false;
|
||||
|
||||
call_hooks('enotify_mail', $datarray);
|
||||
|
||||
// Default to private - don't disclose message contents over insecure channels (such as email)
|
||||
// Might be interesting to use GPG,PGP,S/MIME encryption instead
|
||||
// but we'll save that for a clever plugin developer to implement
|
||||
|
||||
$private_activity = false;
|
||||
|
||||
if (! $datarray['email_secure']) {
|
||||
switch ($params['type']) {
|
||||
case NOTIFY_WALL:
|
||||
case NOTIFY_TAGSELF:
|
||||
case NOTIFY_POKE:
|
||||
case NOTIFY_COMMENT:
|
||||
if (! $private)
|
||||
break;
|
||||
$private_activity = true;
|
||||
case NOTIFY_MAIL:
|
||||
$datarray['textversion'] = $datarray['htmlversion'] = $datarray['title'] = '';
|
||||
$datarray['subject'] = preg_replace('/' . preg_quote(t('[Hubzilla:Notify]')) . '/','$0*',$datarray['subject']);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($private_activity
|
||||
&& intval(get_pconfig($datarray['uid'], 'system', 'ignore_private_notifications'))) {
|
||||
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
|
||||
// load the template for private message notifications
|
||||
$tpl = get_markup_template('email_notify_html.tpl');
|
||||
$email_html_body = replace_macros($tpl,array(
|
||||
'$banner' => $datarray['banner'],
|
||||
'$notify_icon' => \Zotlabs\Lib\System::get_notify_icon(),
|
||||
'$product' => $datarray['product'],
|
||||
'$preamble' => $datarray['preamble'],
|
||||
'$sitename' => $datarray['sitename'],
|
||||
'$siteurl' => $datarray['siteurl'],
|
||||
'$source_name' => $datarray['source_name'],
|
||||
'$source_link' => $datarray['source_link'],
|
||||
'$source_photo' => $datarray['source_photo'],
|
||||
'$username' => $datarray['to_name'],
|
||||
'$hsitelink' => $datarray['hsitelink'],
|
||||
'$hitemlink' => $datarray['hitemlink'],
|
||||
'$thanks' => $datarray['thanks'],
|
||||
'$site_admin' => $datarray['site_admin'],
|
||||
'$title' => $datarray['title'],
|
||||
'$htmlversion' => $datarray['htmlversion'],
|
||||
));
|
||||
|
||||
// load the template for private message notifications
|
||||
$tpl = get_markup_template('email_notify_text.tpl');
|
||||
$email_text_body = replace_macros($tpl, array(
|
||||
'$banner' => $datarray['banner'],
|
||||
'$product' => $datarray['product'],
|
||||
'$preamble' => $datarray['preamble'],
|
||||
'$sitename' => $datarray['sitename'],
|
||||
'$siteurl' => $datarray['siteurl'],
|
||||
'$source_name' => $datarray['source_name'],
|
||||
'$source_link' => $datarray['source_link'],
|
||||
'$source_photo' => $datarray['source_photo'],
|
||||
'$username' => $datarray['to_name'],
|
||||
'$tsitelink' => $datarray['tsitelink'],
|
||||
'$titemlink' => $datarray['titemlink'],
|
||||
'$thanks' => $datarray['thanks'],
|
||||
'$site_admin' => $datarray['site_admin'],
|
||||
'$title' => $datarray['title'],
|
||||
'$textversion' => $datarray['textversion'],
|
||||
));
|
||||
|
||||
// logger('text: ' . $email_text_body);
|
||||
|
||||
// use the EmailNotification library to send the message
|
||||
|
||||
self::send(array(
|
||||
'fromName' => $sender_name,
|
||||
'fromEmail' => $sender_email,
|
||||
'replyTo' => $sender_email,
|
||||
'toEmail' => $recip['account_email'],
|
||||
'messageSubject' => $datarray['subject'],
|
||||
'htmlVersion' => $email_html_body,
|
||||
'textVersion' => $email_text_body,
|
||||
'additionalMailHeader' => $datarray['headers'],
|
||||
));
|
||||
}
|
||||
|
||||
pop_lang();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Send a multipart/alternative message with Text and HTML versions.
|
||||
*
|
||||
* @param array $params an assoziative array with:
|
||||
* * \e string \b fromName name of the sender
|
||||
* * \e string \b fromEmail email of the sender
|
||||
* * \e string \b replyTo replyTo address to direct responses
|
||||
* * \e string \b toEmail destination email address
|
||||
* * \e string \b messageSubject subject of the message
|
||||
* * \e string \b htmlVersion html version of the message
|
||||
* * \e string \b textVersion text only version of the message
|
||||
* * \e string \b additionalMailHeader additions to the smtp mail header
|
||||
*/
|
||||
static public function send($params) {
|
||||
|
||||
$fromName = email_header_encode(html_entity_decode($params['fromName'],ENT_QUOTES,'UTF-8'),'UTF-8');
|
||||
$messageSubject = email_header_encode(html_entity_decode($params['messageSubject'],ENT_QUOTES,'UTF-8'),'UTF-8');
|
||||
|
||||
// generate a mime boundary
|
||||
$mimeBoundary = rand(0, 9) . "-"
|
||||
.rand(10000000000, 9999999999) . "-"
|
||||
.rand(10000000000, 9999999999) . "=:"
|
||||
.rand(10000, 99999);
|
||||
|
||||
// generate a multipart/alternative message header
|
||||
$messageHeader =
|
||||
$params['additionalMailHeader'] .
|
||||
"From: $fromName <{$params['fromEmail']}>\n" .
|
||||
"Reply-To: $fromName <{$params['replyTo']}>\n" .
|
||||
"MIME-Version: 1.0\n" .
|
||||
"Content-Type: multipart/alternative; boundary=\"{$mimeBoundary}\"";
|
||||
|
||||
// assemble the final multipart message body with the text and html types included
|
||||
$textBody = chunk_split(base64_encode($params['textVersion']));
|
||||
$htmlBody = chunk_split(base64_encode($params['htmlVersion']));
|
||||
|
||||
$multipartMessageBody =
|
||||
"--" . $mimeBoundary . "\n" . // plain text section
|
||||
"Content-Type: text/plain; charset=UTF-8\n" .
|
||||
"Content-Transfer-Encoding: base64\n\n" .
|
||||
$textBody . "\n" .
|
||||
"--" . $mimeBoundary . "\n" . // text/html section
|
||||
"Content-Type: text/html; charset=UTF-8\n" .
|
||||
"Content-Transfer-Encoding: base64\n\n" .
|
||||
$htmlBody . "\n" .
|
||||
"--" . $mimeBoundary . "--\n"; // message ending
|
||||
|
||||
// send the message
|
||||
$res = mail(
|
||||
$params['toEmail'], // send to address
|
||||
$messageSubject, // subject
|
||||
$multipartMessageBody, // message body
|
||||
$messageHeader // message headers
|
||||
);
|
||||
logger("notification: enotify::send returns " . $res, LOGGER_DEBUG);
|
||||
}
|
||||
|
||||
static public function format($item) {
|
||||
|
||||
$ret = '';
|
||||
|
||||
require_once('include/conversation.php');
|
||||
|
||||
// Call localize_item with the "brief" flag to get a one line status for activities.
|
||||
// This should set $item['localized'] to indicate we have a brief summary.
|
||||
|
||||
localize_item($item);
|
||||
|
||||
if($item_localize) {
|
||||
$itemem_text = $item['localize'];
|
||||
}
|
||||
else {
|
||||
$itemem_text = (($item['item_thread_top'])
|
||||
? t('created a new post')
|
||||
: sprintf( t('commented on %s\'s post'), $item['owner']['xchan_name']));
|
||||
}
|
||||
|
||||
// convert this logic into a json array just like the system notifications
|
||||
|
||||
return array(
|
||||
'notify_link' => $item['llink'],
|
||||
'name' => $item['author']['xchan_name'],
|
||||
'url' => $item['author']['xchan_url'],
|
||||
'photo' => $item['author']['xchan_photo_s'],
|
||||
'when' => relative_date($item['created']),
|
||||
'class' => (intval($item['item_unseen']) ? 'notify-unseen' : 'notify-seen'),
|
||||
'message' => strip_tags(bbcode($itemem_text))
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
165
Zotlabs/Lib/IConfig.php
Normal file
165
Zotlabs/Lib/IConfig.php
Normal file
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
|
||||
|
||||
class IConfig {
|
||||
|
||||
static public function Load(&$item) {
|
||||
return;
|
||||
}
|
||||
|
||||
static public function Get(&$item, $family, $key) {
|
||||
|
||||
$is_item = false;
|
||||
|
||||
if(is_array($item)) {
|
||||
$is_item = true;
|
||||
if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig'])))
|
||||
$item['iconfig'] = array();
|
||||
|
||||
if(array_key_exists('item_id',$item))
|
||||
$iid = $item['item_id'];
|
||||
else
|
||||
$iid = $item['id'];
|
||||
}
|
||||
elseif(intval($item))
|
||||
$iid = $item;
|
||||
|
||||
if(! $iid)
|
||||
return false;
|
||||
|
||||
if(is_array($item) && array_key_exists('iconfig',$item) && is_array($item['iconfig'])) {
|
||||
foreach($item['iconfig'] as $c) {
|
||||
if($c['iid'] == $iid && $c['cat'] == $family && $c['k'] == $key)
|
||||
return $c['v'];
|
||||
}
|
||||
}
|
||||
|
||||
$r = q("select * from iconfig where iid = %d and cat = '%s' and k = '%s' limit 1",
|
||||
intval($iid),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
if($r) {
|
||||
$r[0]['v'] = ((preg_match('|^a:[0-9]+:{.*}$|s',$r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']);
|
||||
if($is_item)
|
||||
$item['iconfig'][] = $r[0];
|
||||
return $r[0]['v'];
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* IConfig::Set(&$item, $family, $key, $value, $sharing = false);
|
||||
*
|
||||
* $item - item array or item id. If passed an array the iconfig meta information is
|
||||
* added to the item structure (which will need to be saved with item_store eventually).
|
||||
* If passed an id, the DB is updated, but may not be federated and/or cloned.
|
||||
* $family - namespace of meta variable
|
||||
* $key - key of meta variable
|
||||
* $value - value of meta variable
|
||||
* $sharing - boolean (default false); if true the meta information is propagated with the item
|
||||
* to other sites/channels, mostly useful when $item is an array and has not yet been stored/delivered.
|
||||
* If the meta information is added after delivery and you wish it to be shared, it may be necessary to
|
||||
* alter the item edited timestamp and invoke the delivery process on the updated item. The edited
|
||||
* timestamp needs to be altered in order to trigger an item_store_update() at the receiving end.
|
||||
*/
|
||||
|
||||
|
||||
static public function Set(&$item, $family, $key, $value, $sharing = false) {
|
||||
|
||||
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
|
||||
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
|
||||
|
||||
$is_item = false;
|
||||
$idx = null;
|
||||
|
||||
if(is_array($item)) {
|
||||
$is_item = true;
|
||||
if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig'])))
|
||||
$item['iconfig'] = array();
|
||||
elseif($item['iconfig']) {
|
||||
for($x = 0; $x < count($item['iconfig']); $x ++) {
|
||||
if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) {
|
||||
$idx = $x;
|
||||
}
|
||||
}
|
||||
}
|
||||
$entry = array('cat' => $family, 'k' => $key, 'v' => $value, 'sharing' => $sharing);
|
||||
|
||||
if(is_null($idx))
|
||||
$item['iconfig'][] = $entry;
|
||||
else
|
||||
$item['iconfig'][$idx] = $entry;
|
||||
return $value;
|
||||
}
|
||||
|
||||
if(intval($item))
|
||||
$iid = intval($item);
|
||||
|
||||
if(! $iid)
|
||||
return false;
|
||||
|
||||
if(self::Get($item, $family, $key) === false) {
|
||||
$r = q("insert into iconfig( iid, cat, k, v, sharing ) values ( %d, '%s', '%s', '%s', %d ) ",
|
||||
intval($iid),
|
||||
dbesc($family),
|
||||
dbesc($key),
|
||||
dbesc($dbvalue),
|
||||
intval($sharing)
|
||||
);
|
||||
}
|
||||
else {
|
||||
$r = q("update iconfig set v = '%s', sharing = %d where iid = %d and cat = '%s' and k = '%s' ",
|
||||
dbesc($dbvalue),
|
||||
intval($sharing),
|
||||
intval($iid),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
}
|
||||
|
||||
if(! $r)
|
||||
return false;
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static public function Delete(&$item, $family, $key) {
|
||||
|
||||
|
||||
$is_item = false;
|
||||
$idx = null;
|
||||
|
||||
if(is_array($item)) {
|
||||
$is_item = true;
|
||||
if(is_array($item['iconfig'])) {
|
||||
for($x = 0; $x < count($item['iconfig']); $x ++) {
|
||||
if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) {
|
||||
unset($item['iconfig'][$x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if(intval($item))
|
||||
$iid = intval($item);
|
||||
|
||||
if(! $iid)
|
||||
return false;
|
||||
|
||||
return q("delete from iconfig where iid = %d and cat = '%s' and k = '%s' ",
|
||||
intval($iid),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
200
Zotlabs/Lib/PConfig.php
Normal file
200
Zotlabs/Lib/PConfig.php
Normal file
@@ -0,0 +1,200 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
|
||||
class PConfig {
|
||||
|
||||
/**
|
||||
* @brief Loads all configuration values of a channel into a cached storage.
|
||||
*
|
||||
* All configuration values of the given channel are stored in global cache
|
||||
* which is available under the global variable App::$config[$uid].
|
||||
*
|
||||
* @param string $uid
|
||||
* The channel_id
|
||||
* @return void|false Nothing or false if $uid is false
|
||||
*/
|
||||
|
||||
static public function Load($uid) {
|
||||
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)
|
||||
);
|
||||
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$k = $rr['k'];
|
||||
$c = $rr['cat'];
|
||||
if(! array_key_exists($c, \App::$config[$uid])) {
|
||||
\App::$config[$uid][$c] = array();
|
||||
\App::$config[$uid][$c]['config_loaded'] = true;
|
||||
}
|
||||
\App::$config[$uid][$c][$k] = $rr['v'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a particular channel's config variable given the category name
|
||||
* ($family) and a key.
|
||||
*
|
||||
* Get a particular channel's config value from the given category ($family)
|
||||
* and the $key from a cached storage in App::$config[$uid].
|
||||
*
|
||||
* Returns false if not set.
|
||||
*
|
||||
* @param string $uid
|
||||
* The channel_id
|
||||
* @param string $family
|
||||
* The category of the configuration value
|
||||
* @param string $key
|
||||
* The configuration key to query
|
||||
* @param boolean $instore (deprecated, without function)
|
||||
* @return mixed Stored value or false if it does not exist
|
||||
*/
|
||||
|
||||
static public function Get($uid,$family,$key,$instore = false) {
|
||||
|
||||
if(is_null($uid) || $uid === false)
|
||||
return false;
|
||||
|
||||
if(! array_key_exists($uid, \App::$config))
|
||||
self::Load($uid);
|
||||
|
||||
if((! array_key_exists($family, \App::$config[$uid])) || (! array_key_exists($key, \App::$config[$uid][$family])))
|
||||
return false;
|
||||
|
||||
return ((! is_array(\App::$config[$uid][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$uid][$family][$key]))
|
||||
? unserialize(\App::$config[$uid][$family][$key])
|
||||
: \App::$config[$uid][$family][$key]
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a configuration value for a channel.
|
||||
*
|
||||
* Stores a config value ($value) in the category ($family) under the key ($key)
|
||||
* for the channel_id $uid.
|
||||
*
|
||||
* @param string $uid
|
||||
* The channel_id
|
||||
* @param string $family
|
||||
* The category of the configuration value
|
||||
* @param string $key
|
||||
* The configuration key to set
|
||||
* @param string $value
|
||||
* The value to store
|
||||
* @return mixed Stored $value or false
|
||||
*/
|
||||
|
||||
static public function Set($uid, $family, $key, $value) {
|
||||
|
||||
// this catches subtle errors where this function has been called
|
||||
// with local_channel() when not logged in (which returns false)
|
||||
// and throws an error in array_key_exists below.
|
||||
// we provide a function backtrace in the logs so that we can find
|
||||
// and fix the calling function.
|
||||
|
||||
if(is_null($uid) || $uid === false) {
|
||||
btlogger('UID is FALSE!', LOGGER_NORMAL, LOG_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
// manage array value
|
||||
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
|
||||
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
|
||||
|
||||
if(get_pconfig($uid, $family, $key) === false) {
|
||||
if(! array_key_exists($uid, \App::$config))
|
||||
\App::$config[$uid] = array();
|
||||
if(! array_key_exists($family, \App::$config[$uid]))
|
||||
\App::$config[$uid][$family] = array();
|
||||
|
||||
$ret = q("INSERT INTO pconfig ( uid, cat, k, v ) VALUES ( %d, '%s', '%s', '%s' ) ",
|
||||
intval($uid),
|
||||
dbesc($family),
|
||||
dbesc($key),
|
||||
dbesc($dbvalue)
|
||||
);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
$ret = q("UPDATE pconfig SET v = '%s' WHERE uid = %d and cat = '%s' AND k = '%s'",
|
||||
dbesc($dbvalue),
|
||||
intval($uid),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
// keep a separate copy for all variables which were
|
||||
// set in the life of this page. We need this to
|
||||
// synchronise channel clones.
|
||||
|
||||
if(! array_key_exists('transient', \App::$config[$uid]))
|
||||
\App::$config[$uid]['transient'] = array();
|
||||
if(! array_key_exists($family, \App::$config[$uid]['transient']))
|
||||
\App::$config[$uid]['transient'][$family] = array();
|
||||
|
||||
\App::$config[$uid][$family][$key] = $value;
|
||||
\App::$config[$uid]['transient'][$family][$key] = $value;
|
||||
|
||||
if($ret)
|
||||
return $value;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Deletes the given key from the channel's configuration.
|
||||
*
|
||||
* Removes the configured value from the stored cache in App::$config[$uid]
|
||||
* and removes it from the database.
|
||||
*
|
||||
* @param string $uid
|
||||
* The channel_id
|
||||
* @param string $family
|
||||
* The category of the configuration value
|
||||
* @param string $key
|
||||
* The configuration key to delete
|
||||
* @return mixed
|
||||
*/
|
||||
|
||||
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]))
|
||||
unset(\App::$config[$uid][$family][$key]);
|
||||
$ret = q("DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s'",
|
||||
intval($uid),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -117,11 +108,7 @@ class PermissionDescription {
|
||||
case PERMS_NETWORK: return t('Anybody in the $Projectname network');
|
||||
case PERMS_SITE: return sprintf(t('Any account on %s'), \App::get_hostname());
|
||||
case PERMS_CONTACTS: return t('Any of my connections');
|
||||
case PERMS_SPECIFIC:
|
||||
// Because we're describing the permissions of an item with an empty ACL,
|
||||
// the owner will be the only person able to see it if the permissions are
|
||||
// set to "only specified connections".
|
||||
return t('Only me (only specified contacts and me)');
|
||||
case PERMS_SPECIFIC: return t('Only connections I specifically allow');
|
||||
case PERMS_AUTHED: return t('Anybody authenticated (could include visitors from other networks)');
|
||||
case PERMS_PENDING: return t('Any connections including those who haven\'t yet been approved');
|
||||
default: return $this->fallback_description;
|
||||
@@ -143,11 +130,7 @@ class PermissionDescription {
|
||||
case PERMS_NETWORK: return 'fa-share-alt-square'; // fa-share-alt-square is very similiar to the hubzilla logo, but we should create our own logo class to use
|
||||
case PERMS_SITE: return 'fa-sitemap';
|
||||
case PERMS_CONTACTS: return 'fa-group';
|
||||
case PERMS_SPECIFIC:
|
||||
// Because we're describing the permissions of an item with an empty ACL,
|
||||
// the owner will be the only person able to see it if the permissions are
|
||||
// set to "only specified connections".
|
||||
return 'fa-eye-slash';
|
||||
case PERMS_SPECIFIC: return 'fa-list';
|
||||
case PERMS_AUTHED: return '';
|
||||
case PERMS_PENDING: return '';
|
||||
default: return '';
|
||||
19
Zotlabs/Lib/ProtoDriver.php
Normal file
19
Zotlabs/Lib/ProtoDriver.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
/*
|
||||
* Abstraction class for dealing with alternate networks (which of course do not exist, hence the abstraction)
|
||||
*/
|
||||
|
||||
|
||||
abstract class ProtoDriver {
|
||||
abstract protected function discover($channel,$location);
|
||||
abstract protected function deliver($item,$channel,$recipients);
|
||||
abstract protected function collect($channel,$connection);
|
||||
abstract protected function change_permissions($permissions,$channel,$recipient);
|
||||
abstract protected function acknowledge_permissions($permissions,$channel,$recipient);
|
||||
abstract protected function deliver_private($item,$channel,$recipients);
|
||||
abstract protected function collect_private($channel,$connection);
|
||||
|
||||
}
|
||||
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));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Project;
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
class System {
|
||||
|
||||
static public function get_platform_name() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['platform_name'])
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && array_key_exists('platform_name',\App::$config['system']))
|
||||
return \App::$config['system']['platform_name'];
|
||||
return PLATFORM_NAME;
|
||||
}
|
||||
@@ -43,9 +43,9 @@ class System {
|
||||
|
||||
|
||||
static public function get_server_role() {
|
||||
if(UNO)
|
||||
return 'basic';
|
||||
return 'advanced';
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['server_role'])
|
||||
return \App::$config['system']['server_role'];
|
||||
return 'pro';
|
||||
}
|
||||
|
||||
static public function get_std_version() {
|
||||
781
Zotlabs/Lib/ThreadItem.php
Normal file
781
Zotlabs/Lib/ThreadItem.php
Normal file
@@ -0,0 +1,781 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
require_once('include/text.php');
|
||||
|
||||
/**
|
||||
* A thread item
|
||||
*/
|
||||
|
||||
class ThreadItem {
|
||||
|
||||
public $data = array();
|
||||
private $template = 'conv_item.tpl';
|
||||
private $comment_box_template = 'comment_item.tpl';
|
||||
private $commentable = false;
|
||||
// list of supported reaction emojis - a site can over-ride this via config system.reactions
|
||||
private $reactions = ['1f60a','1f44f','1f37e','1f48b','1f61e','2665','1f606','1f62e','1f634','1f61c','1f607','1f608'];
|
||||
private $toplevel = false;
|
||||
private $children = array();
|
||||
private $parent = null;
|
||||
private $conversation = null;
|
||||
private $redirect_url = null;
|
||||
private $owner_url = '';
|
||||
private $owner_photo = '';
|
||||
private $owner_name = '';
|
||||
private $wall_to_wall = false;
|
||||
private $threaded = false;
|
||||
private $visiting = false;
|
||||
private $channel = null;
|
||||
private $display_mode = 'normal';
|
||||
|
||||
|
||||
public function __construct($data) {
|
||||
|
||||
$this->data = $data;
|
||||
$this->toplevel = ($this->get_id() == $this->get_data_value('parent'));
|
||||
|
||||
// Prepare the children
|
||||
if(count($data['children'])) {
|
||||
foreach($data['children'] as $item) {
|
||||
|
||||
/*
|
||||
* Only add those that will be displayed
|
||||
*/
|
||||
|
||||
if((! visible_activity($item)) || array_key_exists('author_blocked',$item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$child = new ThreadItem($item);
|
||||
$this->add_child($child);
|
||||
}
|
||||
}
|
||||
|
||||
// allow a site to configure the order and content of the reaction emoji list
|
||||
if($this->toplevel) {
|
||||
$x = get_config('system','reactions');
|
||||
if($x && is_array($x) && count($x)) {
|
||||
$this->reactions = $x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data in a form usable by a conversation template
|
||||
*
|
||||
* Returns:
|
||||
* _ The data requested on success
|
||||
* _ false on failure
|
||||
*/
|
||||
|
||||
public function get_template_data($conv_responses, $thread_level=1) {
|
||||
|
||||
$result = array();
|
||||
|
||||
$item = $this->get_data();
|
||||
|
||||
$commentww = '';
|
||||
$sparkle = '';
|
||||
$buttons = '';
|
||||
$dropping = false;
|
||||
$star = false;
|
||||
$isstarred = "unstarred fa-star-o";
|
||||
$indent = '';
|
||||
$osparkle = '';
|
||||
$total_children = $this->count_descendants();
|
||||
$unseen_comments = (($item['real_uid']) ? 0 : $this->count_unseen_descendants());
|
||||
|
||||
$conv = $this->get_conversation();
|
||||
$observer = $conv->get_observer();
|
||||
|
||||
$lock = ((($item['item_private'] == 1) || (($item['uid'] == local_channel()) && (strlen($item['allow_cid']) || strlen($item['allow_gid'])
|
||||
|| strlen($item['deny_cid']) || strlen($item['deny_gid']))))
|
||||
? t('Private Message')
|
||||
: false);
|
||||
$shareable = ((($conv->get_profile_owner() == local_channel() && local_channel()) && ($item['item_private'] != 1)) ? true : false);
|
||||
|
||||
// allow an exemption for sharing stuff from your private feeds
|
||||
if($item['author']['xchan_network'] === 'rss')
|
||||
$shareable = true;
|
||||
|
||||
$mode = $conv->get_mode();
|
||||
|
||||
if(local_channel() && $observer['xchan_hash'] === $item['author_xchan'])
|
||||
$edpost = array(z_root()."/editpost/".$item['id'], t("Edit"));
|
||||
else
|
||||
$edpost = false;
|
||||
|
||||
|
||||
if($observer['xchan_hash'] == $this->get_data_value('author_xchan')
|
||||
|| $observer['xchan_hash'] == $this->get_data_value('owner_xchan')
|
||||
|| $this->get_data_value('uid') == local_channel())
|
||||
$dropping = true;
|
||||
|
||||
|
||||
if(array_key_exists('real_uid',$item)) {
|
||||
$edpost = false;
|
||||
$dropping = false;
|
||||
}
|
||||
|
||||
|
||||
if($dropping) {
|
||||
$drop = array(
|
||||
'dropping' => $dropping,
|
||||
'delete' => t('Delete'),
|
||||
);
|
||||
}
|
||||
// FIXME
|
||||
if($observer_is_pageowner) {
|
||||
$multidrop = array(
|
||||
'select' => t('Select'),
|
||||
);
|
||||
}
|
||||
|
||||
$filer = ((($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) ? t("Save to Folder") : false);
|
||||
|
||||
$profile_avatar = $item['author']['xchan_photo_m'];
|
||||
$profile_link = chanlink_url($item['author']['xchan_url']);
|
||||
$profile_name = $item['author']['xchan_name'];
|
||||
|
||||
$location = format_location($item);
|
||||
$isevent = false;
|
||||
$attend = null;
|
||||
$canvote = false;
|
||||
|
||||
// process action responses - e.g. like/dislike/attend/agree/whatever
|
||||
$response_verbs = array('like');
|
||||
if(feature_enabled($conv->get_profile_owner(),'dislike'))
|
||||
$response_verbs[] = 'dislike';
|
||||
if($item['obj_type'] === ACTIVITY_OBJ_EVENT) {
|
||||
$response_verbs[] = 'attendyes';
|
||||
$response_verbs[] = 'attendno';
|
||||
$response_verbs[] = 'attendmaybe';
|
||||
if($this->is_commentable()) {
|
||||
$isevent = true;
|
||||
$attend = array( t('I will attend'), t('I will not attend'), t('I might attend'));
|
||||
}
|
||||
}
|
||||
|
||||
$consensus = (intval($item['item_consensus']) ? true : false);
|
||||
if($consensus) {
|
||||
$response_verbs[] = 'agree';
|
||||
$response_verbs[] = 'disagree';
|
||||
$response_verbs[] = 'abstain';
|
||||
if($this->is_commentable()) {
|
||||
$conlabels = array( t('I agree'), t('I disagree'), t('I abstain'));
|
||||
$canvote = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(! feature_enabled($conv->get_profile_owner(),'dislike'))
|
||||
unset($conv_responses['dislike']);
|
||||
|
||||
$responses = get_responses($conv_responses,$response_verbs,$this,$item);
|
||||
|
||||
$like_count = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid']] : '');
|
||||
$like_list = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid'] . '-l'] : '');
|
||||
if (count($like_list) > MAX_LIKERS) {
|
||||
$like_list_part = array_slice($like_list, 0, MAX_LIKERS);
|
||||
array_push($like_list_part, '<a href="#" data-toggle="modal" data-target="#likeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>');
|
||||
} else {
|
||||
$like_list_part = '';
|
||||
}
|
||||
$like_button_label = tt('Like','Likes',$like_count,'noun');
|
||||
|
||||
if (feature_enabled($conv->get_profile_owner(),'dislike')) {
|
||||
$dislike_count = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid']] : '');
|
||||
$dislike_list = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid'] . '-l'] : '');
|
||||
$dislike_button_label = tt('Dislike','Dislikes',$dislike_count,'noun');
|
||||
if (count($dislike_list) > MAX_LIKERS) {
|
||||
$dislike_list_part = array_slice($dislike_list, 0, MAX_LIKERS);
|
||||
array_push($dislike_list_part, '<a href="#" data-toggle="modal" data-target="#dislikeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>');
|
||||
} else {
|
||||
$dislike_list_part = '';
|
||||
}
|
||||
}
|
||||
|
||||
$showlike = ((x($conv_responses['like'],$item['mid'])) ? format_like($conv_responses['like'][$item['mid']],$conv_responses['like'][$item['mid'] . '-l'],'like',$item['mid']) : '');
|
||||
$showdislike = ((x($conv_responses['dislike'],$item['mid']) && feature_enabled($conv->get_profile_owner(),'dislike'))
|
||||
? format_like($conv_responses['dislike'][$item['mid']],$conv_responses['dislike'][$item['mid'] . '-l'],'dislike',$item['mid']) : '');
|
||||
|
||||
/*
|
||||
* We should avoid doing this all the time, but it depends on the conversation mode
|
||||
* And the conv mode may change when we change the conv, or it changes its mode
|
||||
* Maybe we should establish a way to be notified about conversation changes
|
||||
*/
|
||||
|
||||
$this->check_wall_to_wall();
|
||||
|
||||
if($this->is_toplevel()) {
|
||||
// FIXME check this permission
|
||||
if(($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) {
|
||||
|
||||
// FIXME we don't need all this stuff, some can be done in the template
|
||||
|
||||
$star = array(
|
||||
'do' => t("Add Star"),
|
||||
'undo' => t("Remove Star"),
|
||||
'toggle' => t("Toggle Star Status"),
|
||||
'classdo' => (intval($item['item_starred']) ? "hidden" : ""),
|
||||
'classundo' => (intval($item['item_starred']) ? "" : "hidden"),
|
||||
'isstarred' => (intval($item['item_starred']) ? "starred fa-star" : "unstarred fa-star-o"),
|
||||
'starred' => t('starred'),
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
$indent = 'comment';
|
||||
}
|
||||
|
||||
|
||||
$verified = (intval($item['item_verified']) ? t('Message signature validated') : '');
|
||||
$forged = ((($item['sig']) && (! intval($item['item_verified']))) ? t('Message signature incorrect') : '');
|
||||
$unverified = '' ; // (($this->is_wall_to_wall() && (! intval($item['item_verified']))) ? t('Message cannot be verified') : '');
|
||||
|
||||
|
||||
|
||||
// FIXME - check this permission
|
||||
if($conv->get_profile_owner() == local_channel()) {
|
||||
$tagger = array(
|
||||
'tagit' => t("Add Tag"),
|
||||
'classtagger' => "",
|
||||
);
|
||||
}
|
||||
|
||||
$server_role = get_config('system','server_role');
|
||||
$has_bookmarks = false;
|
||||
if(is_array($item['term'])) {
|
||||
foreach($item['term'] as $t) {
|
||||
if(($server_role != 'basic') && ($t['ttype'] == TERM_BOOKMARK))
|
||||
$has_bookmarks = true;
|
||||
}
|
||||
}
|
||||
|
||||
$has_event = false;
|
||||
if(($item['obj_type'] === ACTIVITY_OBJ_EVENT) && $conv->get_profile_owner() == local_channel())
|
||||
$has_event = true;
|
||||
|
||||
if($this->is_commentable()) {
|
||||
$like = array( t("I like this \x28toggle\x29"), t("like"));
|
||||
$dislike = array( t("I don't like this \x28toggle\x29"), t("dislike"));
|
||||
}
|
||||
|
||||
if ($shareable)
|
||||
$share = array( t('Share This'), t('share'));
|
||||
|
||||
$dreport = '';
|
||||
|
||||
$keep_reports = intval(get_config('system','expire_delivery_reports'));
|
||||
if($keep_reports === 0)
|
||||
$keep_reports = 30;
|
||||
|
||||
if((! get_config('system','disable_dreport')) && strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC',"now - $keep_reports days")) > 0)
|
||||
$dreport = t('Delivery Report');
|
||||
|
||||
if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0)
|
||||
$indent .= ' shiny';
|
||||
|
||||
|
||||
localize_item($item);
|
||||
|
||||
$body = prepare_body($item,true);
|
||||
|
||||
// $viewthread (below) is only valid in list mode. If this is a channel page, build the thread viewing link
|
||||
// since we can't depend on llink or plink pointing to the right local location.
|
||||
|
||||
$owner_address = substr($item['owner']['xchan_addr'],0,strpos($item['owner']['xchan_addr'],'@'));
|
||||
$viewthread = $item['llink'];
|
||||
if($conv->get_mode() === 'channel')
|
||||
$viewthread = z_root() . '/channel/' . $owner_address . '?f=&mid=' . $item['mid'];
|
||||
|
||||
$comment_count_txt = sprintf( tt('%d comment','%d comments',$total_children),$total_children );
|
||||
$list_unseen_txt = (($unseen_comments) ? sprintf('%d unseen',$unseen_comments) : '');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
$children = $this->get_children();
|
||||
|
||||
$has_tags = (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false);
|
||||
|
||||
$tmp_item = array(
|
||||
'template' => $this->get_template(),
|
||||
'mode' => $mode,
|
||||
'type' => implode("",array_slice(explode("/",$item['verb']),-1)),
|
||||
'body' => $body['html'],
|
||||
'tags' => $body['tags'],
|
||||
'categories' => $body['categories'],
|
||||
'mentions' => $body['mentions'],
|
||||
'attachments' => $body['attachments'],
|
||||
'folders' => $body['folders'],
|
||||
'text' => strip_tags($body['html']),
|
||||
'id' => $this->get_id(),
|
||||
'mid' => $item['mid'],
|
||||
'isevent' => $isevent,
|
||||
'attend' => $attend,
|
||||
'consensus' => $consensus,
|
||||
'conlabels' => $conlabels,
|
||||
'canvote' => $canvote,
|
||||
'linktitle' => sprintf( t('View %s\'s profile - %s'), $profile_name, $item['author']['xchan_addr']),
|
||||
'olinktitle' => sprintf( t('View %s\'s profile - %s'), $this->get_owner_name(), $item['owner']['xchan_addr']),
|
||||
'llink' => $item['llink'],
|
||||
'viewthread' => $viewthread,
|
||||
'to' => t('to'),
|
||||
'via' => t('via'),
|
||||
'wall' => t('Wall-to-Wall'),
|
||||
'vwall' => t('via Wall-To-Wall:'),
|
||||
'profile_url' => $profile_link,
|
||||
'item_photo_menu' => item_photo_menu($item),
|
||||
'dreport' => $dreport,
|
||||
'name' => $profile_name,
|
||||
'thumb' => $profile_avatar,
|
||||
'osparkle' => $osparkle,
|
||||
'sparkle' => $sparkle,
|
||||
'title' => $item['title'],
|
||||
'title_tosource' => get_pconfig($conv->get_profile_owner(),'system','title_tosource'),
|
||||
'ago' => relative_date($item['created']),
|
||||
'app' => $item['app'],
|
||||
'str_app' => sprintf( t('from %s'), $item['app']),
|
||||
'isotime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'c'),
|
||||
'localtime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'r'),
|
||||
'editedtime' => (($item['edited'] != $item['created']) ? sprintf( t('last edited: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['edited'], 'r')) : ''),
|
||||
'expiretime' => (($item['expires'] !== NULL_DATE) ? sprintf( t('Expires: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['expires'], 'r')):''),
|
||||
'lock' => $lock,
|
||||
'verified' => $verified,
|
||||
'unverified' => $unverified,
|
||||
'forged' => $forged,
|
||||
'location' => $location,
|
||||
'indent' => $indent,
|
||||
'owner_url' => $this->get_owner_url(),
|
||||
'owner_photo' => $this->get_owner_photo(),
|
||||
'owner_name' => $this->get_owner_name(),
|
||||
'photo' => $body['photo'],
|
||||
'event' => $body['event'],
|
||||
'has_tags' => $has_tags,
|
||||
'reactions' => $this->reactions,
|
||||
// Item toolbar buttons
|
||||
'emojis' => (($this->is_toplevel() && $this->is_commentable() && feature_enabled($conv->get_profile_owner(),'emojis')) ? '1' : ''),
|
||||
'like' => $like,
|
||||
'dislike' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike : ''),
|
||||
'share' => $share,
|
||||
'rawmid' => $item['mid'],
|
||||
'plink' => get_plink($item),
|
||||
'edpost' => $edpost, // ((feature_enabled($conv->get_profile_owner(),'edit_posts')) ? $edpost : ''),
|
||||
'star' => ((feature_enabled($conv->get_profile_owner(),'star_posts')) ? $star : ''),
|
||||
'tagger' => ((feature_enabled($conv->get_profile_owner(),'commtag')) ? $tagger : ''),
|
||||
'filer' => ((feature_enabled($conv->get_profile_owner(),'filing')) ? $filer : ''),
|
||||
'bookmark' => (($conv->get_profile_owner() == local_channel() && local_channel() && $has_bookmarks) ? t('Save Bookmarks') : ''),
|
||||
'addtocal' => (($has_event) ? t('Add to Calendar') : ''),
|
||||
'drop' => $drop,
|
||||
'multidrop' => ((feature_enabled($conv->get_profile_owner(),'multi_delete')) ? $multidrop : ''),
|
||||
// end toolbar buttons
|
||||
|
||||
'unseen_comments' => $unseen_comments,
|
||||
'comment_count' => $total_children,
|
||||
'comment_count_txt' => $comment_count_txt,
|
||||
'list_unseen_txt' => $list_unseen_txt,
|
||||
'markseen' => t('Mark all seen'),
|
||||
'responses' => $responses,
|
||||
'like_count' => $like_count,
|
||||
'like_list' => $like_list,
|
||||
'like_list_part' => $like_list_part,
|
||||
'like_button_label' => $like_button_label,
|
||||
'like_modal_title' => t('Likes','noun'),
|
||||
'dislike_modal_title' => t('Dislikes','noun'),
|
||||
'dislike_count' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_count : ''),
|
||||
'dislike_list' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_list : ''),
|
||||
'dislike_list_part' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_list_part : ''),
|
||||
'dislike_button_label' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_button_label : ''),
|
||||
'modal_dismiss' => t('Close'),
|
||||
'showlike' => $showlike,
|
||||
'showdislike' => $showdislike,
|
||||
'comment' => $this->get_comment_box($indent),
|
||||
'previewing' => ($conv->is_preview() ? ' preview ' : ''),
|
||||
'wait' => t('Please wait'),
|
||||
'thread_level' => $thread_level
|
||||
);
|
||||
|
||||
$arr = array('item' => $item, 'output' => $tmp_item);
|
||||
call_hooks('display_item', $arr);
|
||||
|
||||
$result = $arr['output'];
|
||||
|
||||
$result['children'] = array();
|
||||
$nb_children = count($children);
|
||||
|
||||
$visible_comments = get_config('system','expanded_comments');
|
||||
if($visible_comments === false)
|
||||
$visible_comments = 3;
|
||||
|
||||
if(($this->get_display_mode() === 'normal') && ($nb_children > 0)) {
|
||||
foreach($children as $child) {
|
||||
$result['children'][] = $child->get_template_data($conv_responses, $thread_level + 1);
|
||||
}
|
||||
// Collapse
|
||||
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'] = sprintf( t('%s show all'), '<i class="fa fa-chevron-down"></i>');
|
||||
if($thread_level > 1) {
|
||||
$result['children'][$nb_children - 1]['comment_lastcollapsed'] = true;
|
||||
}
|
||||
else {
|
||||
$result['children'][$nb_children - ($visible_comments + 1)]['comment_lastcollapsed'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result['private'] = $item['item_private'];
|
||||
$result['toplevel'] = ($this->is_toplevel() ? 'toplevel_item' : '');
|
||||
|
||||
if($this->is_threaded()) {
|
||||
$result['flatten'] = false;
|
||||
$result['threaded'] = true;
|
||||
}
|
||||
else {
|
||||
$result['flatten'] = true;
|
||||
$result['threaded'] = false;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function get_id() {
|
||||
return $this->get_data_value('id');
|
||||
}
|
||||
|
||||
public function get_display_mode() {
|
||||
return $this->display_mode;
|
||||
}
|
||||
|
||||
public function set_display_mode($mode) {
|
||||
$this->display_mode = $mode;
|
||||
}
|
||||
|
||||
public function is_threaded() {
|
||||
return $this->threaded;
|
||||
}
|
||||
|
||||
public function set_commentable($val) {
|
||||
$this->commentable = $val;
|
||||
foreach($this->get_children() as $child)
|
||||
$child->set_commentable($val);
|
||||
}
|
||||
|
||||
public function is_commentable() {
|
||||
return $this->commentable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a child item
|
||||
*/
|
||||
public function add_child($item) {
|
||||
$item_id = $item->get_id();
|
||||
if(!$item_id) {
|
||||
logger('[ERROR] Item::add_child : Item has no ID!!', LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
if($this->get_child($item->get_id())) {
|
||||
logger('[WARN] Item::add_child : Item already exists ('. $item->get_id() .').', LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
* Only add what will be displayed
|
||||
*/
|
||||
|
||||
if(activity_match($item->get_data_value('verb'),ACTIVITY_LIKE) || activity_match($item->get_data_value('verb'),ACTIVITY_DISLIKE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$item->set_parent($this);
|
||||
$this->children[] = $item;
|
||||
return end($this->children);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a child by its ID
|
||||
*/
|
||||
public function get_child($id) {
|
||||
foreach($this->get_children() as $child) {
|
||||
if($child->get_id() == $id)
|
||||
return $child;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all our children
|
||||
*/
|
||||
public function get_children() {
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set our parent
|
||||
*/
|
||||
protected function set_parent($item) {
|
||||
$parent = $this->get_parent();
|
||||
if($parent) {
|
||||
$parent->remove_child($this);
|
||||
}
|
||||
$this->parent = $item;
|
||||
$this->set_conversation($item->get_conversation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove our parent
|
||||
*/
|
||||
protected function remove_parent() {
|
||||
$this->parent = null;
|
||||
$this->conversation = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a child
|
||||
*/
|
||||
public function remove_child($item) {
|
||||
$id = $item->get_id();
|
||||
foreach($this->get_children() as $key => $child) {
|
||||
if($child->get_id() == $id) {
|
||||
$child->remove_parent();
|
||||
unset($this->children[$key]);
|
||||
// Reindex the array, in order to make sure there won't be any trouble on loops using count()
|
||||
$this->children = array_values($this->children);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
logger('[WARN] Item::remove_child : Item is not a child ('. $id .').', LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parent item
|
||||
*/
|
||||
protected function get_parent() {
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* set conversation
|
||||
*/
|
||||
public function set_conversation($conv) {
|
||||
$previous_mode = ($this->conversation ? $this->conversation->get_mode() : '');
|
||||
|
||||
$this->conversation = $conv;
|
||||
|
||||
// Set it on our children too
|
||||
foreach($this->get_children() as $child)
|
||||
$child->set_conversation($conv);
|
||||
}
|
||||
|
||||
/**
|
||||
* get conversation
|
||||
*/
|
||||
public function get_conversation() {
|
||||
return $this->conversation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get raw data
|
||||
*
|
||||
* We shouldn't need this
|
||||
*/
|
||||
public function get_data() {
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a data value
|
||||
*
|
||||
* Returns:
|
||||
* _ value on success
|
||||
* _ false on failure
|
||||
*/
|
||||
public function get_data_value($name) {
|
||||
if(!isset($this->data[$name])) {
|
||||
// logger('[ERROR] Item::get_data_value : Item has no value name "'. $name .'".', LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->data[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get template
|
||||
*/
|
||||
public function get_template() {
|
||||
return $this->template;
|
||||
}
|
||||
|
||||
|
||||
public function set_template($t) {
|
||||
$this->template = $t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this is a toplevel post
|
||||
*/
|
||||
private function is_toplevel() {
|
||||
return $this->toplevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the total of our descendants
|
||||
*/
|
||||
private function count_descendants() {
|
||||
$children = $this->get_children();
|
||||
$total = count($children);
|
||||
if($total > 0) {
|
||||
foreach($children as $child) {
|
||||
$total += $child->count_descendants();
|
||||
}
|
||||
}
|
||||
return $total;
|
||||
}
|
||||
|
||||
private function count_unseen_descendants() {
|
||||
$children = $this->get_children();
|
||||
$total = count($children);
|
||||
if($total > 0) {
|
||||
$total = 0;
|
||||
foreach($children as $child) {
|
||||
if((! visible_activity($child->data)) || array_key_exists('author_blocked',$child->data)) {
|
||||
continue;
|
||||
}
|
||||
if(intval($child->data['item_unseen']))
|
||||
$total ++;
|
||||
}
|
||||
}
|
||||
return $total;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the template for the comment box
|
||||
*/
|
||||
private function get_comment_box_template() {
|
||||
return $this->comment_box_template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the comment box
|
||||
*
|
||||
* Returns:
|
||||
* _ The comment box string (empty if no comment box)
|
||||
* _ false on failure
|
||||
*/
|
||||
private function get_comment_box($indent) {
|
||||
|
||||
if(!$this->is_toplevel() && !get_config('system','thread_allow')) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$comment_box = '';
|
||||
$conv = $this->get_conversation();
|
||||
|
||||
// logger('Commentable conv: ' . $conv->is_commentable());
|
||||
|
||||
if(! $this->is_commentable())
|
||||
return;
|
||||
|
||||
$template = get_markup_template($this->get_comment_box_template());
|
||||
|
||||
$observer = $conv->get_observer();
|
||||
|
||||
$qc = ((local_channel()) ? get_pconfig(local_channel(),'system','qcomment') : null);
|
||||
$qcomment = (($qc) ? explode("\n",$qc) : null);
|
||||
|
||||
$arr = array('comment_buttons' => '','id' => $this->get_id());
|
||||
call_hooks('comment_buttons',$arr);
|
||||
$comment_buttons = $arr['comment_buttons'];
|
||||
|
||||
|
||||
$comment_box = replace_macros($template,array(
|
||||
'$return_path' => '',
|
||||
'$threaded' => $this->is_threaded(),
|
||||
'$jsreload' => '', //(($conv->get_mode() === 'display') ? $_SESSION['return_url'] : ''),
|
||||
'$type' => (($conv->get_mode() === 'channel') ? 'wall-comment' : 'net-comment'),
|
||||
'$id' => $this->get_id(),
|
||||
'$parent' => $this->get_id(),
|
||||
'$qcomment' => $qcomment,
|
||||
'$comment_buttons' => $comment_buttons,
|
||||
'$profile_uid' => $conv->get_profile_owner(),
|
||||
'$mylink' => $observer['xchan_url'],
|
||||
'$mytitle' => t('This is you'),
|
||||
'$myphoto' => $observer['xchan_photo_s'],
|
||||
'$comment' => t('Comment'),
|
||||
'$submit' => t('Submit'),
|
||||
'$edbold' => t('Bold'),
|
||||
'$editalic' => t('Italic'),
|
||||
'$eduline' => t('Underline'),
|
||||
'$edquote' => t('Quote'),
|
||||
'$edcode' => t('Code'),
|
||||
'$edimg' => t('Image'),
|
||||
'$edurl' => t('Insert Link'),
|
||||
'$edvideo' => t('Video'),
|
||||
'$preview' => t('Preview'), // ((feature_enabled($conv->get_profile_owner(),'preview')) ? t('Preview') : ''),
|
||||
'$indent' => $indent,
|
||||
'$feature_encrypt' => ((feature_enabled($conv->get_profile_owner(),'content_encrypt')) ? true : false),
|
||||
'$encrypt' => t('Encrypt text'),
|
||||
'$cipher' => $conv->get_cipher(),
|
||||
'$sourceapp' => \App::$sourcename
|
||||
|
||||
));
|
||||
|
||||
return $comment_box;
|
||||
}
|
||||
|
||||
private function get_redirect_url() {
|
||||
return $this->redirect_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we are a wall to wall item and set the relevant properties
|
||||
*/
|
||||
protected function check_wall_to_wall() {
|
||||
$conv = $this->get_conversation();
|
||||
$this->wall_to_wall = false;
|
||||
$this->owner_url = '';
|
||||
$this->owner_photo = '';
|
||||
$this->owner_name = '';
|
||||
|
||||
if($conv->get_mode() === 'channel')
|
||||
return;
|
||||
|
||||
if($this->is_toplevel() && ($this->get_data_value('author_xchan') != $this->get_data_value('owner_xchan'))) {
|
||||
$this->owner_url = chanlink_url($this->data['owner']['xchan_url']);
|
||||
$this->owner_photo = $this->data['owner']['xchan_photo_m'];
|
||||
$this->owner_name = $this->data['owner']['xchan_name'];
|
||||
$this->wall_to_wall = true;
|
||||
}
|
||||
}
|
||||
|
||||
private function is_wall_to_wall() {
|
||||
return $this->wall_to_wall;
|
||||
}
|
||||
|
||||
private function get_owner_url() {
|
||||
return $this->owner_url;
|
||||
}
|
||||
|
||||
private function get_owner_photo() {
|
||||
return $this->owner_photo;
|
||||
}
|
||||
|
||||
private function get_owner_name() {
|
||||
return $this->owner_name;
|
||||
}
|
||||
|
||||
private function is_visiting() {
|
||||
return $this->visiting;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
220
Zotlabs/Lib/ThreadStream.php
Normal file
220
Zotlabs/Lib/ThreadStream.php
Normal file
@@ -0,0 +1,220 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
require_once('boot.php');
|
||||
require_once('include/text.php');
|
||||
require_once('include/items.php');
|
||||
|
||||
/**
|
||||
* A list of threads
|
||||
*
|
||||
*/
|
||||
|
||||
class ThreadStream {
|
||||
|
||||
private $threads = array();
|
||||
private $mode = null;
|
||||
private $observer = null;
|
||||
private $writable = false;
|
||||
private $commentable = false;
|
||||
private $profile_owner = 0;
|
||||
private $preview = false;
|
||||
private $prepared_item = '';
|
||||
private $cipher = 'aes256';
|
||||
|
||||
// $prepared_item is for use by alternate conversation structures such as photos
|
||||
// wherein we've already prepared a top level item which doesn't look anything like
|
||||
// a normal "post" item
|
||||
|
||||
public function __construct($mode, $preview, $prepared_item = '') {
|
||||
$this->set_mode($mode);
|
||||
$this->preview = $preview;
|
||||
$this->prepared_item = $prepared_item;
|
||||
$c = ((local_channel()) ? get_pconfig(local_channel(),'system','default_cipher') : '');
|
||||
if($c)
|
||||
$this->cipher = $c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mode we'll be displayed on
|
||||
*/
|
||||
private function set_mode($mode) {
|
||||
if($this->get_mode() == $mode)
|
||||
return;
|
||||
|
||||
$this->observer = \App::get_observer();
|
||||
$ob_hash = (($this->observer) ? $this->observer['xchan_hash'] : '');
|
||||
|
||||
switch($mode) {
|
||||
case 'network':
|
||||
$this->profile_owner = local_channel();
|
||||
$this->writable = true;
|
||||
break;
|
||||
case 'channel':
|
||||
$this->profile_owner = \App::$profile['profile_uid'];
|
||||
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||
break;
|
||||
case 'display':
|
||||
// in this mode we set profile_owner after initialisation (from conversation()) and then
|
||||
// pull some trickery which allows us to re-invoke this function afterward
|
||||
// it's an ugly hack so FIXME
|
||||
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||
break;
|
||||
case 'page':
|
||||
$this->profile_owner = \App::$profile['uid'];
|
||||
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||
break;
|
||||
default:
|
||||
logger('[ERROR] Conversation::set_mode : Unhandled mode ('. $mode .').', LOGGER_DEBUG);
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
$this->mode = $mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mode
|
||||
*/
|
||||
public function get_mode() {
|
||||
return $this->mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if page is writable
|
||||
*/
|
||||
public function is_writable() {
|
||||
return $this->writable;
|
||||
}
|
||||
|
||||
public function is_commentable() {
|
||||
return $this->commentable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if page is a preview
|
||||
*/
|
||||
public function is_preview() {
|
||||
return $this->preview;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get profile owner
|
||||
*/
|
||||
public function get_profile_owner() {
|
||||
return $this->profile_owner;
|
||||
}
|
||||
|
||||
public function set_profile_owner($uid) {
|
||||
$this->profile_owner = $uid;
|
||||
$mode = $this->get_mode();
|
||||
$this->mode = null;
|
||||
$this->set_mode($mode);
|
||||
}
|
||||
|
||||
public function get_observer() {
|
||||
return $this->observer;
|
||||
}
|
||||
|
||||
public function get_cipher() {
|
||||
return $this->cipher;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a thread to the conversation
|
||||
*
|
||||
* Returns:
|
||||
* _ The inserted item on success
|
||||
* _ false on failure
|
||||
*/
|
||||
public function add_thread($item) {
|
||||
$item_id = $item->get_id();
|
||||
if(!$item_id) {
|
||||
logger('Item has no ID!!', LOGGER_DEBUG, LOG_ERR);
|
||||
return false;
|
||||
}
|
||||
if($this->get_thread($item->get_id())) {
|
||||
logger('Thread already exists ('. $item->get_id() .').', LOGGER_DEBUG, LOG_WARNING);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Only add things that will be displayed
|
||||
*/
|
||||
|
||||
|
||||
if(($item->get_data_value('id') != $item->get_data_value('parent')) && (activity_match($item->get_data_value('verb'),ACTIVITY_LIKE) || activity_match($item->get_data_value('verb'),ACTIVITY_DISLIKE))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$item->set_commentable(false);
|
||||
$ob_hash = (($this->observer) ? $this->observer['xchan_hash'] : '');
|
||||
|
||||
if(! comments_are_now_closed($item->get_data())) {
|
||||
if(($item->get_data_value('author_xchan') === $ob_hash) || ($item->get_data_value('owner_xchan') === $ob_hash))
|
||||
$item->set_commentable(true);
|
||||
|
||||
if(intval($item->get_data_value('item_nocomment'))) {
|
||||
$item->set_commentable(false);
|
||||
}
|
||||
elseif(($this->observer) && (! $item->is_commentable())) {
|
||||
if((array_key_exists('owner',$item->data)) && intval($item->data['owner']['abook_self']))
|
||||
$item->set_commentable(perm_is_allowed($this->profile_owner,$this->observer['xchan_hash'],'post_comments'));
|
||||
else
|
||||
$item->set_commentable(can_comment_on_post($this->observer['xchan_hash'],$item->data));
|
||||
}
|
||||
}
|
||||
require_once('include/channel.php');
|
||||
|
||||
$item->set_conversation($this);
|
||||
$this->threads[] = $item;
|
||||
return end($this->threads);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data in a form usable by a conversation template
|
||||
*
|
||||
* We should find a way to avoid using those arguments (at least most of them)
|
||||
*
|
||||
* Returns:
|
||||
* _ The data requested on success
|
||||
* _ false on failure
|
||||
*/
|
||||
public function get_template_data($conv_responses) {
|
||||
$result = array();
|
||||
|
||||
foreach($this->threads as $item) {
|
||||
|
||||
if(($item->get_data_value('id') == $item->get_data_value('parent')) && $this->prepared_item) {
|
||||
$item_data = $this->prepared_item;
|
||||
}
|
||||
else {
|
||||
$item_data = $item->get_template_data($conv_responses);
|
||||
}
|
||||
if(!$item_data) {
|
||||
logger('Failed to get item template data ('. $item->get_id() .').', LOGGER_DEBUG, LOG_ERR);
|
||||
return false;
|
||||
}
|
||||
$result[] = $item_data;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a thread based on its item id
|
||||
*
|
||||
* Returns:
|
||||
* _ The found item on success
|
||||
* _ false on failure
|
||||
*/
|
||||
private function get_thread($id) {
|
||||
foreach($this->threads as $item) {
|
||||
if($item->get_id() == $id)
|
||||
return $item;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
160
Zotlabs/Lib/XConfig.php
Normal file
160
Zotlabs/Lib/XConfig.php
Normal file
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
|
||||
class XConfig {
|
||||
|
||||
/**
|
||||
* @brief Loads a full xchan's configuration into a cached storage.
|
||||
*
|
||||
* All configuration values of the given observer hash are stored in global
|
||||
* cache which is available under the global variable App::$config[$xchan].
|
||||
*
|
||||
* @param string $xchan
|
||||
* The observer's hash
|
||||
* @return void|false Returns false if xchan is not set
|
||||
*/
|
||||
|
||||
static public function Load($xchan) {
|
||||
|
||||
if(! $xchan)
|
||||
return false;
|
||||
|
||||
if(! array_key_exists($xchan, \App::$config))
|
||||
\App::$config[$xchan] = array();
|
||||
|
||||
$r = q("SELECT * FROM xconfig WHERE xchan = '%s'",
|
||||
dbesc($xchan)
|
||||
);
|
||||
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$k = $rr['k'];
|
||||
$c = $rr['cat'];
|
||||
if(! array_key_exists($c, \App::$config[$xchan])) {
|
||||
\App::$config[$xchan][$c] = array();
|
||||
\App::$config[$xchan][$c]['config_loaded'] = true;
|
||||
}
|
||||
\App::$config[$xchan][$c][$k] = $rr['v'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a particular observer's config variable given the category
|
||||
* name ($family) and a key.
|
||||
*
|
||||
* Get a particular observer's config value from the given category ($family)
|
||||
* and the $key from a cached storage in App::$config[$xchan].
|
||||
*
|
||||
* Returns false if not set.
|
||||
*
|
||||
* @param string $xchan
|
||||
* The observer's hash
|
||||
* @param string $family
|
||||
* The category of the configuration value
|
||||
* @param string $key
|
||||
* The configuration key to query
|
||||
* @return mixed Stored $value or false if it does not exist
|
||||
*/
|
||||
|
||||
static public function Get($xchan, $family, $key) {
|
||||
|
||||
if(! $xchan)
|
||||
return false;
|
||||
|
||||
if(! array_key_exists($xchan, \App::$config))
|
||||
load_xconfig($xchan);
|
||||
|
||||
if((! array_key_exists($family, \App::$config[$xchan])) || (! array_key_exists($key, \App::$config[$xchan][$family])))
|
||||
return false;
|
||||
|
||||
return ((! is_array(\App::$config[$xchan][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$xchan][$family][$key]))
|
||||
? unserialize(\App::$config[$xchan][$family][$key])
|
||||
: \App::$config[$xchan][$family][$key]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a configuration value for an observer.
|
||||
*
|
||||
* Stores a config value ($value) in the category ($family) under the key ($key)
|
||||
* for the observer's $xchan hash.
|
||||
*
|
||||
*
|
||||
* @param string $xchan
|
||||
* The observer's hash
|
||||
* @param string $family
|
||||
* The category of the configuration value
|
||||
* @param string $key
|
||||
* The configuration key to set
|
||||
* @param string $value
|
||||
* The value to store
|
||||
* @return mixed Stored $value or false
|
||||
*/
|
||||
|
||||
static public function Set($xchan, $family, $key, $value) {
|
||||
|
||||
// manage array value
|
||||
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
|
||||
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
|
||||
|
||||
if(self::Get($xchan, $family, $key) === false) {
|
||||
if(! array_key_exists($xchan, \App::$config))
|
||||
\App::$config[$xchan] = array();
|
||||
if(! array_key_exists($family, \App::$config[$xchan]))
|
||||
\App::$config[$xchan][$family] = array();
|
||||
|
||||
$ret = q("INSERT INTO xconfig ( xchan, cat, k, v ) VALUES ( '%s', '%s', '%s', '%s' ) ",
|
||||
dbesc($xchan),
|
||||
dbesc($family),
|
||||
dbesc($key),
|
||||
dbesc($dbvalue)
|
||||
);
|
||||
}
|
||||
else {
|
||||
$ret = q("UPDATE xconfig SET v = '%s' WHERE xchan = '%s' and cat = '%s' AND k = '%s'",
|
||||
dbesc($dbvalue),
|
||||
dbesc($xchan),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
}
|
||||
|
||||
\App::$config[$xchan][$family][$key] = $value;
|
||||
|
||||
if($ret)
|
||||
return $value;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deletes the given key from the observer's config.
|
||||
*
|
||||
* Removes the configured value from the stored cache in App::$config[$xchan]
|
||||
* and removes it from the database.
|
||||
*
|
||||
* @param string $xchan
|
||||
* The observer's hash
|
||||
* @param string $family
|
||||
* The category of the configuration value
|
||||
* @param string $key
|
||||
* The configuration key to delete
|
||||
* @return mixed
|
||||
*/
|
||||
|
||||
static public function Delete($xchan, $family, $key) {
|
||||
|
||||
if(x(\App::$config[$xchan][$family], $key))
|
||||
unset(\App::$config[$xchan][$family][$key]);
|
||||
$ret = q("DELETE FROM xconfig WHERE xchan = '%s' AND cat = '%s' AND k = '%s'",
|
||||
dbesc($xchan),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
}
|
||||
30
Zotlabs/Lib/ZotDriver.php
Normal file
30
Zotlabs/Lib/ZotDriver.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
|
||||
class ZotDriver extends ProtoDriver {
|
||||
|
||||
protected function discover($channel,$location) {
|
||||
|
||||
}
|
||||
protected function deliver($item,$channel,$recipients) {
|
||||
|
||||
}
|
||||
protected function collect($channel,$connection) {
|
||||
|
||||
}
|
||||
protected function change_permissions($permissions,$channel,$recipient) {
|
||||
|
||||
}
|
||||
protected function acknowledge_permissions($permissions,$channel,$recipient) {
|
||||
|
||||
}
|
||||
protected function deliver_private($item,$channel,$recipients) {
|
||||
|
||||
}
|
||||
protected function collect_private($channel,$connection) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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,36 +102,38 @@ 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`.`name`
|
||||
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`.`name`
|
||||
GROUP BY groups.id
|
||||
ORDER BY groups.gname
|
||||
LIMIT %d OFFSET %d",
|
||||
intval(local_channel()),
|
||||
intval($count),
|
||||
intval($start)
|
||||
);
|
||||
|
||||
foreach($r as $g){
|
||||
// logger('acl: group: ' . $g['name'] . ' members: ' . group_get_members_xchan($g['id']));
|
||||
$groups[] = array(
|
||||
"type" => "g",
|
||||
"photo" => "images/twopeople.png",
|
||||
"name" => $g['name'],
|
||||
"id" => $g['id'],
|
||||
"xid" => $g['hash'],
|
||||
"uids" => group_get_members_xchan($g['id']),
|
||||
"link" => ''
|
||||
);
|
||||
|
||||
if($r) {
|
||||
foreach($r as $g){
|
||||
// logger('acl: group: ' . $g['gname'] . ' members: ' . group_get_members_xchan($g['id']));
|
||||
$groups[] = array(
|
||||
"type" => "g",
|
||||
"photo" => "images/twopeople.png",
|
||||
"name" => $g['gname'],
|
||||
"id" => $g['id'],
|
||||
"xid" => $g['hash'],
|
||||
"uids" => group_get_members_xchan($g['id']),
|
||||
"link" => ''
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -94,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
|
||||
@@ -158,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
|
||||
@@ -204,14 +292,14 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
else
|
||||
$r = array();
|
||||
|
||||
if(count($r)) {
|
||||
if($r) {
|
||||
foreach($r as $g){
|
||||
|
||||
// remove RSS feeds from ACLs - they are inaccessible
|
||||
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",
|
||||
@@ -260,7 +348,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
|
||||
// logger('navbar_complete');
|
||||
|
||||
if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
|
||||
if(observer_prohibited()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -294,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) : '');
|
||||
|
||||
@@ -32,8 +32,8 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
case 'site':
|
||||
$this->admin_page_site_post($a);
|
||||
break;
|
||||
case 'users':
|
||||
$this->admin_page_users_post($a);
|
||||
case 'accounts':
|
||||
$this->admin_page_accounts_post($a);
|
||||
break;
|
||||
case 'channels':
|
||||
$this->admin_page_channels_post($a);
|
||||
@@ -127,8 +127,8 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
case 'site':
|
||||
$o = $this->admin_page_site($a);
|
||||
break;
|
||||
case 'users':
|
||||
$o = $this->admin_page_users($a);
|
||||
case 'accounts':
|
||||
$o = $this->admin_page_accounts($a);
|
||||
break;
|
||||
case 'channels':
|
||||
$o = $this->admin_page_channels($a);
|
||||
@@ -872,20 +872,20 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle POST actions on users admin page.
|
||||
* @brief Handle POST actions on accounts admin page.
|
||||
*
|
||||
* This function is called when on the admin user/account page the form was
|
||||
* submitted to handle multiple operations at once. If one of the icons next
|
||||
* to an entry are pressed the function admin_page_users() will handle this.
|
||||
* to an entry are pressed the function admin_page_accounts() will handle this.
|
||||
*
|
||||
* @param App $a
|
||||
*/
|
||||
function admin_page_users_post($a) {
|
||||
function admin_page_accounts_post($a) {
|
||||
$pending = ( x($_POST, 'pending') ? $_POST['pending'] : array() );
|
||||
$users = ( x($_POST, 'user') ? $_POST['user'] : array() );
|
||||
$blocked = ( x($_POST, 'blocked') ? $_POST['blocked'] : array() );
|
||||
|
||||
check_form_security_token_redirectOnErr('/admin/users', 'admin_users');
|
||||
check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts');
|
||||
|
||||
// change to switch structure?
|
||||
// account block/unblock button was submitted
|
||||
@@ -901,8 +901,7 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
notice( sprintf( tt("%s account blocked/unblocked", "%s account blocked/unblocked", count($users)), count($users)) );
|
||||
}
|
||||
// account delete button was submitted
|
||||
if (x($_POST, 'page_users_delete')) {
|
||||
require_once('include/Contact.php');
|
||||
if (x($_POST, 'page_accounts_delete')) {
|
||||
foreach ($users as $uid){
|
||||
account_remove($uid, true, false);
|
||||
}
|
||||
@@ -921,20 +920,20 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
goaway(z_root() . '/admin/users' );
|
||||
goaway(z_root() . '/admin/accounts' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Generate users admin page and handle single item operations.
|
||||
* @brief Generate accounts admin page and handle single item operations.
|
||||
*
|
||||
* This function generates the users/account admin page and handles the actions
|
||||
* This function generates the accounts/account admin page and handles the actions
|
||||
* if an icon next to an entry was clicked. If several items were selected and
|
||||
* the form was submitted it is handled by the function admin_page_users_post().
|
||||
* the form was submitted it is handled by the function admin_page_accounts_post().
|
||||
*
|
||||
* @param App &$a
|
||||
* @return string
|
||||
*/
|
||||
function admin_page_users(&$a){
|
||||
function admin_page_accounts(&$a){
|
||||
if (argc() > 2) {
|
||||
$uid = argv(3);
|
||||
$account = q("SELECT * FROM account WHERE account_id = %d",
|
||||
@@ -943,15 +942,14 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
|
||||
if (! $account) {
|
||||
notice( t('Account not found') . EOL);
|
||||
goaway(z_root() . '/admin/users' );
|
||||
goaway(z_root() . '/admin/accounts' );
|
||||
}
|
||||
|
||||
check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
|
||||
check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts', 't');
|
||||
|
||||
switch (argv(2)){
|
||||
case 'delete':
|
||||
// delete user
|
||||
require_once('include/Contact.php');
|
||||
account_remove($uid,true,false);
|
||||
|
||||
notice( sprintf(t("Account '%s' deleted"), $account[0]['account_email']) . EOL);
|
||||
@@ -974,7 +972,7 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
break;
|
||||
}
|
||||
|
||||
goaway(z_root() . '/admin/users' );
|
||||
goaway(z_root() . '/admin/accounts' );
|
||||
}
|
||||
|
||||
/* get pending */
|
||||
@@ -982,7 +980,7 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
intval(ACCOUNT_PENDING)
|
||||
);
|
||||
|
||||
/* get users */
|
||||
/* get accounts */
|
||||
|
||||
$total = q("SELECT count(*) as total FROM account");
|
||||
if (count($total)) {
|
||||
@@ -990,22 +988,20 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
\App::set_pager_itemspage(100);
|
||||
}
|
||||
|
||||
|
||||
// We'll still need to link email addresses to admin/users/channels or some such, but this bit doesn't exist yet.
|
||||
// That's where we need to be doing last post/channel flags/etc, not here.
|
||||
|
||||
$serviceclass = (($_REQUEST['class']) ? " and account_service_class = '" . dbesc($_REQUEST['class']) . "' " : '');
|
||||
|
||||
$key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'account_id');
|
||||
$dir = 'asc';
|
||||
if(array_key_exists('dir',$_REQUEST))
|
||||
$dir = ((intval($_REQUEST['dir'])) ? 'asc' : 'desc');
|
||||
|
||||
$base = z_root() . '/admin/accounts?f=';
|
||||
$odir = (($dir === 'asc') ? '0' : '1');
|
||||
|
||||
$order = " order by account_email asc ";
|
||||
if($_REQUEST['order'] === 'expires')
|
||||
$order = " order by account_expires desc ";
|
||||
if($_REQUEST['order'] === 'created')
|
||||
$order = " order by account_created desc ";
|
||||
|
||||
$users = q("SELECT `account_id` , `account_email`, `account_lastlog`, `account_created`, `account_expires`, " . "`account_service_class`, ( account_flags & %d )>0 as `blocked`, " .
|
||||
$users = q("SELECT `account_id` , `account_email`, `account_lastlog`, `account_created`, `account_expires`, " . "`account_service_class`, ( account_flags & %d ) > 0 as `blocked`, " .
|
||||
"(SELECT %s FROM channel as ch " .
|
||||
"WHERE ch.channel_account_id = ac.account_id and ch.channel_removed = 0 ) as `channels` " .
|
||||
"FROM account as ac where true $serviceclass $order limit %d offset %d ",
|
||||
"FROM account as ac where true $serviceclass order by $key $dir limit %d offset %d ",
|
||||
intval(ACCOUNT_BLOCKED),
|
||||
db_concat('ch.channel_address', ' '),
|
||||
intval(\App::$pager['itemspage']),
|
||||
@@ -1028,14 +1024,14 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
// }
|
||||
// $users = array_map("_setup_users", $users);
|
||||
|
||||
$t = get_markup_template('admin_users.tpl');
|
||||
$t = get_markup_template('admin_accounts.tpl');
|
||||
$o = replace_macros($t, array(
|
||||
// strings //
|
||||
'$title' => t('Administration'),
|
||||
'$page' => t('Users'),
|
||||
'$page' => t('Accounts'),
|
||||
'$submit' => t('Submit'),
|
||||
'$select_all' => t('select all'),
|
||||
'$h_pending' => t('User registrations waiting for confirm'),
|
||||
'$h_pending' => t('Registrations waiting for confirm'),
|
||||
'$th_pending' => array( t('Request date'), t('Email') ),
|
||||
'$no_pending' => t('No registrations.'),
|
||||
'$approve' => t('Approve'),
|
||||
@@ -1043,14 +1039,22 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
'$delete' => t('Delete'),
|
||||
'$block' => t('Block'),
|
||||
'$unblock' => t('Unblock'),
|
||||
|
||||
'$h_users' => t('Users'),
|
||||
'$th_users' => array( t('ID'), t('Email'), t('All Channels'), t('Register date'), t('Last login'), t('Expires'), t('Service Class')),
|
||||
'$odir' => $odir,
|
||||
'$base' => $base,
|
||||
'$h_users' => t('Accounts'),
|
||||
'$th_users' => array(
|
||||
[ t('ID'), 'account_id' ],
|
||||
[ t('Email'), 'account_email' ],
|
||||
[ t('All Channels'), 'channels' ],
|
||||
[ t('Register date'), 'account_created' ],
|
||||
[ t('Last login'), 'account_lastlog' ],
|
||||
[ t('Expires'), 'account_expires' ],
|
||||
[ t('Service Class'), 'account_service_class'] ),
|
||||
|
||||
'$confirm_delete_multi' => t('Selected accounts will be deleted!\n\nEverything these accounts had posted on this site will be permanently deleted!\n\nAre you sure?'),
|
||||
'$confirm_delete' => t('The account {0} will be deleted!\n\nEverything this account has posted on this site will be permanently deleted!\n\nAre you sure?'),
|
||||
|
||||
'$form_security_token' => get_form_security_token("admin_users"),
|
||||
'$form_security_token' => get_form_security_token("admin_accounts"),
|
||||
|
||||
// values //
|
||||
'$baseurl' => z_root(),
|
||||
@@ -1082,7 +1086,7 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
intval(PAGE_CENSORED),
|
||||
intval( $uid )
|
||||
);
|
||||
proc_run('php','include/directory.php',$uid,'nopush');
|
||||
\Zotlabs\Daemon\Master::Summon(array('Directory',$uid,'nopush'));
|
||||
}
|
||||
notice( sprintf( tt("%s channel censored/uncensored", "%s channels censored/uncensored", count($channels)), count($channels)) );
|
||||
}
|
||||
@@ -1096,7 +1100,6 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
notice( sprintf( tt("%s channel code allowed/disallowed", "%s channels code allowed/disallowed", count($channels)), count($channels)) );
|
||||
}
|
||||
if (x($_POST,'page_channels_delete')){
|
||||
require_once("include/Contact.php");
|
||||
foreach($channels as $uid){
|
||||
channel_remove($uid,true);
|
||||
}
|
||||
@@ -1128,7 +1131,6 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
case "delete":{
|
||||
check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels', 't');
|
||||
// delete channel
|
||||
require_once("include/Contact.php");
|
||||
channel_remove($uid,true);
|
||||
|
||||
notice( sprintf(t("Channel '%s' deleted"), $channel[0]['channel_name']) . EOL);
|
||||
@@ -1141,7 +1143,7 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
intval($pflags),
|
||||
intval( $uid )
|
||||
);
|
||||
proc_run('php','include/directory.php',$uid,'nopush');
|
||||
\Zotlabs\Daemon\Master::Summon(array('Directory',$uid,'nopush'));
|
||||
|
||||
notice( sprintf( (($pflags & PAGE_CENSORED) ? t("Channel '%s' censored"): t("Channel '%s' uncensored")) , $channel[0]['channel_name'] . ' (' . $channel[0]['channel_address'] . ')' ) . EOL);
|
||||
}; break;
|
||||
@@ -1162,6 +1164,17 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
goaway(z_root() . '/admin/channels' );
|
||||
}
|
||||
|
||||
|
||||
$key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'channel_id');
|
||||
$dir = 'asc';
|
||||
if(array_key_exists('dir',$_REQUEST))
|
||||
$dir = ((intval($_REQUEST['dir'])) ? 'asc' : 'desc');
|
||||
|
||||
$base = z_root() . '/admin/channels?f=';
|
||||
$odir = (($dir === 'asc') ? '0' : '1');
|
||||
|
||||
|
||||
|
||||
/* get channels */
|
||||
|
||||
@@ -1170,14 +1183,12 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
\App::set_pager_total($total[0]['total']);
|
||||
\App::set_pager_itemspage(100);
|
||||
}
|
||||
|
||||
$order = " order by channel_name asc ";
|
||||
|
||||
$channels = q("SELECT * from channel where channel_removed = 0 and channel_system = 0 $order limit %d offset %d ",
|
||||
|
||||
$channels = q("SELECT * from channel where channel_removed = 0 and channel_system = 0 order by $key $dir limit %d offset %d ",
|
||||
intval(\App::$pager['itemspage']),
|
||||
intval(\App::$pager['start'])
|
||||
);
|
||||
|
||||
|
||||
if($channels) {
|
||||
for($x = 0; $x < count($channels); $x ++) {
|
||||
if($channels[$x]['channel_pageflags'] & PAGE_CENSORED)
|
||||
@@ -1205,7 +1216,12 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
'$code' => t('Allow Code'),
|
||||
'$uncode' => t('Disallow Code'),
|
||||
'$h_channels' => t('Channel'),
|
||||
'$th_channels' => array( t('UID'), t('Name'), t('Address')),
|
||||
'$base' => $base,
|
||||
'$odir' => $odir,
|
||||
'$th_channels' => array(
|
||||
[ t('UID'), 'channel_id' ],
|
||||
[ t('Name'), 'channel_name' ],
|
||||
[ t('Address'), 'channel_address' ]),
|
||||
|
||||
'$confirm_delete_multi' => t('Selected channels will be deleted!\n\nEverything that was posted in these channels on this site will be permanently deleted!\n\nAre you sure?'),
|
||||
'$confirm_delete' => t('The channel {0} will be deleted!\n\nEverything that was posted in this channel on this site will be permanently deleted!\n\nAre you sure?'),
|
||||
@@ -1295,7 +1311,7 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
|
||||
$admin_form = '';
|
||||
|
||||
$r = q("select * from addon where plugin_admin = 1 and name = '%s' limit 1",
|
||||
$r = q("select * from addon where plugin_admin = 1 and aname = '%s' limit 1",
|
||||
dbesc($plugin)
|
||||
);
|
||||
|
||||
@@ -1408,7 +1424,9 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
'$plugins' => $plugins,
|
||||
'$disabled' => t('Disabled - version incompatibility'),
|
||||
'$form_security_token' => get_form_security_token('admin_plugins'),
|
||||
'$addrepo' => t('Add Plugin Repo'),
|
||||
'$managerepos' => t('Manage Repos'),
|
||||
'$installedtitle' => t('Installed Plugin Repositories'),
|
||||
'$addnewrepotitle' => t('Install a New Plugin Repository'),
|
||||
'$expandform' => false,
|
||||
'$form' => $admin_plugins_add_repo_form,
|
||||
'$newRepoModal' => $newRepoModal,
|
||||
@@ -1423,13 +1441,15 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
function listAddonRepos() {
|
||||
$addonrepos = [];
|
||||
$addonDir = __DIR__ . '/../../extend/addon/';
|
||||
if ($handle = opendir($addonDir)) {
|
||||
while (false !== ($entry = readdir($handle))) {
|
||||
if ($entry != "." && $entry != "..") {
|
||||
$addonrepos[] = $entry;
|
||||
if(is_dir($addonDir)) {
|
||||
if ($handle = opendir($addonDir)) {
|
||||
while (false !== ($entry = readdir($handle))) {
|
||||
if ($entry != "." && $entry != "..") {
|
||||
$addonrepos[] = $entry;
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
return $addonrepos;
|
||||
}
|
||||
@@ -1547,8 +1567,8 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
|
||||
// Toggle theme status
|
||||
|
||||
toggle_theme($themes, $theme, $result);
|
||||
$s = rebuild_theme_table($themes);
|
||||
$this->toggle_theme($themes, $theme, $result);
|
||||
$s = $this->rebuild_theme_table($themes);
|
||||
if($result)
|
||||
info( sprintf('Theme %s enabled.', $theme));
|
||||
else
|
||||
@@ -1561,7 +1581,7 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
// display theme details
|
||||
require_once('library/markdown.php');
|
||||
|
||||
if (theme_status($themes,$theme)) {
|
||||
if ($this->theme_status($themes,$theme)) {
|
||||
$status="on"; $action= t("Disable");
|
||||
} else {
|
||||
$status="off"; $action= t("Enable");
|
||||
@@ -1718,7 +1738,7 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
|
||||
// name, label, value, help string, extra data...
|
||||
'$debugging' => array('debugging', t("Debugging"),get_config('system','debugging'), ""),
|
||||
'$logfile' => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your Red top-level directory.")),
|
||||
'$logfile' => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your top-level webserver directory.")),
|
||||
'$loglevel' => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices),
|
||||
|
||||
'$form_security_token' => get_form_security_token('admin_logs'),
|
||||
@@ -1733,7 +1753,20 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
} else {
|
||||
json_return_and_die(array('message' => 'No repo name provided.', 'success' => false));
|
||||
}
|
||||
$repoDir = __DIR__ . '/../../store/git/sys/extend/addon/' . $repoName;
|
||||
$extendDir = __DIR__ . '/../../store/[data]/git/sys/extend';
|
||||
$addonDir = $extendDir . '/addon';
|
||||
if (!file_exists($extendDir)) {
|
||||
if (!mkdir($extendDir, 0770, true)) {
|
||||
logger('Error creating extend folder: ' . $extendDir);
|
||||
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
|
||||
} else {
|
||||
if (!symlink(__DIR__ . '/../../extend/addon', $addonDir)) {
|
||||
logger('Error creating symlink to addon folder: ' . $addonDir);
|
||||
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
|
||||
}
|
||||
}
|
||||
}
|
||||
$repoDir = __DIR__ . '/../../store/[data]/git/sys/extend/addon/' . $repoName;
|
||||
if (!is_dir($repoDir)) {
|
||||
logger('Repo directory does not exist: ' . $repoDir);
|
||||
json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false));
|
||||
@@ -1745,6 +1778,18 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
$git = new GitRepo('sys', null, false, $repoName, $repoDir);
|
||||
try {
|
||||
if ($git->pull()) {
|
||||
$files = array_diff(scandir($repoDir), array('.', '..'));
|
||||
foreach ($files as $file) {
|
||||
if (is_dir($repoDir . '/' . $file) && $file !== '.git') {
|
||||
$source = '../extend/addon/' . $repoName . '/' . $file;
|
||||
$target = realpath(__DIR__ . '/../../addon/') . '/' . $file;
|
||||
unlink($target);
|
||||
if (!symlink($source, $target)) {
|
||||
logger('Error linking addons to /addon');
|
||||
json_return_and_die(array('message' => 'Error linking addons to /addon', 'success' => false));
|
||||
}
|
||||
}
|
||||
}
|
||||
json_return_and_die(array('message' => 'Repo updated.', 'success' => true));
|
||||
} else {
|
||||
json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false));
|
||||
@@ -1758,7 +1803,20 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
} else {
|
||||
json_return_and_die(array('message' => 'No repo name provided.', 'success' => false));
|
||||
}
|
||||
$repoDir = __DIR__ . '/../../store/git/sys/extend/addon/' . $repoName;
|
||||
$extendDir = __DIR__ . '/../../store/[data]/git/sys/extend';
|
||||
$addonDir = $extendDir . '/addon';
|
||||
if (!file_exists($extendDir)) {
|
||||
if (!mkdir($extendDir, 0770, true)) {
|
||||
logger('Error creating extend folder: ' . $extendDir);
|
||||
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
|
||||
} else {
|
||||
if (!symlink(__DIR__ . '/../../extend/addon', $addonDir)) {
|
||||
logger('Error creating symlink to addon folder: ' . $addonDir);
|
||||
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
|
||||
}
|
||||
}
|
||||
}
|
||||
$repoDir = __DIR__ . '/../../store/[data]/git/sys/extend/addon/' . $repoName;
|
||||
if (!is_dir($repoDir)) {
|
||||
logger('Repo directory does not exist: ' . $repoDir);
|
||||
json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false));
|
||||
@@ -1778,7 +1836,7 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
if (array_key_exists('repoURL', $_REQUEST)) {
|
||||
require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies
|
||||
$repoURL = $_REQUEST['repoURL'];
|
||||
$extendDir = __DIR__ . '/../../store/git/sys/extend';
|
||||
$extendDir = __DIR__ . '/../../store/[data]/git/sys/extend';
|
||||
$addonDir = $extendDir . '/addon';
|
||||
if (!file_exists($extendDir)) {
|
||||
if (!mkdir($extendDir, 0770, true)) {
|
||||
@@ -1806,7 +1864,7 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
json_return_and_die(array('message' => 'Invalid git repo', 'success' => false));
|
||||
}
|
||||
$repoDir = $addonDir . '/' . $repoName;
|
||||
$tempRepoBaseDir = __DIR__ . '/../../store/git/sys/temp/';
|
||||
$tempRepoBaseDir = __DIR__ . '/../../store/[data]/git/sys/temp/';
|
||||
$tempAddonDir = $tempRepoBaseDir . $repoName;
|
||||
|
||||
if (!is_writable($addonDir) || !is_writable($tempAddonDir)) {
|
||||
@@ -1840,9 +1898,9 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
if (array_key_exists('repoURL', $_REQUEST)) {
|
||||
require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies
|
||||
$repoURL = $_REQUEST['repoURL'];
|
||||
$extendDir = __DIR__ . '/../../store/git/sys/extend';
|
||||
$extendDir = __DIR__ . '/../../store/[data]/git/sys/extend';
|
||||
$addonDir = $extendDir . '/addon';
|
||||
$tempAddonDir = __DIR__ . '/../../store/git/sys/temp';
|
||||
$tempAddonDir = __DIR__ . '/../../store/[data]/git/sys/temp';
|
||||
if (!file_exists($extendDir)) {
|
||||
if (!mkdir($extendDir, 0770, true)) {
|
||||
logger('Error creating extend folder: ' . $extendDir);
|
||||
@@ -1854,6 +1912,12 @@ class Admin extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is_dir($tempAddonDir)) {
|
||||
if (!mkdir($tempAddonDir, 0770, true)) {
|
||||
logger('Error creating temp plugin repo folder: ' . $tempAddonDir);
|
||||
json_return_and_die(array('message' => 'Error creating temp plugin repo folder: ' . $tempAddonDir, 'success' => false));
|
||||
}
|
||||
}
|
||||
$repoName = null;
|
||||
if (array_key_exists('repoName', $_REQUEST) && $_REQUEST['repoName'] !== '') {
|
||||
$repoName = $_REQUEST['repoName'];
|
||||
|
||||
@@ -107,7 +107,7 @@ class Api extends \Zotlabs\Web\Controller {
|
||||
$r = q("SELECT `clients`.*
|
||||
FROM `clients`, `tokens`
|
||||
WHERE `clients`.`client_id`=`tokens`.`client_id`
|
||||
AND `tokens`.`id`='%s' AND `tokens`.`scope`='request'",
|
||||
AND `tokens`.`id`='%s' AND `tokens`.`auth_scope`='request'",
|
||||
dbesc($token));
|
||||
|
||||
if (!count($r))
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/apps.php');
|
||||
//require_once('include/apps.php');
|
||||
|
||||
use \Zotlabs\Lib as Zlib;
|
||||
|
||||
class Appman extends \Zotlabs\Web\Controller {
|
||||
|
||||
@@ -30,16 +31,16 @@ class Appman extends \Zotlabs\Web\Controller {
|
||||
'categories' => escape_tags($_REQUEST['categories'])
|
||||
);
|
||||
|
||||
$_REQUEST['appid'] = app_install(local_channel(),$arr);
|
||||
$_REQUEST['appid'] = Zlib\Apps::app_install(local_channel(),$arr);
|
||||
|
||||
if(app_installed(local_channel(),$arr))
|
||||
if(Zlib\Apps::app_installed(local_channel(),$arr))
|
||||
info( t('App installed.') . EOL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$papp = app_decode($_POST['papp']);
|
||||
$papp = Zlib\Apps::app_decode($_POST['papp']);
|
||||
|
||||
if(! is_array($papp)) {
|
||||
notice( t('Malformed app.') . EOL);
|
||||
@@ -47,13 +48,13 @@ class Appman extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
if($_POST['install']) {
|
||||
app_install(local_channel(),$papp);
|
||||
if(app_installed(local_channel(),$papp))
|
||||
Zlib\Apps::app_install(local_channel(),$papp);
|
||||
if(Zlib\Apps::app_installed(local_channel(),$papp))
|
||||
info( t('App installed.') . EOL);
|
||||
}
|
||||
|
||||
if($_POST['delete']) {
|
||||
app_destroy(local_channel(),$papp);
|
||||
Zlib\Apps::app_destroy(local_channel(),$papp);
|
||||
}
|
||||
|
||||
if($_POST['edit']) {
|
||||
@@ -100,7 +101,7 @@ class Appman extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
$embed = array('embed', t('Embed code'), app_encode($app,true),'', 'onclick="this.select();"');
|
||||
$embed = array('embed', t('Embed code'), Zlib\Apps::app_encode($app,true),'', 'onclick="this.select();"');
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/apps.php');
|
||||
//require_once('include/apps.php');
|
||||
|
||||
use \Zotlabs\Lib as Zlib;
|
||||
|
||||
class Apps extends \Zotlabs\Web\Controller {
|
||||
|
||||
@@ -19,25 +20,25 @@ class Apps extends \Zotlabs\Web\Controller {
|
||||
|
||||
|
||||
if(local_channel()) {
|
||||
import_system_apps();
|
||||
Zlib\Apps::import_system_apps();
|
||||
$syslist = array();
|
||||
$list = app_list(local_channel(), false, $_GET['cat']);
|
||||
$list = Zlib\Apps::app_list(local_channel(), false, $_GET['cat']);
|
||||
if($list) {
|
||||
foreach($list as $x) {
|
||||
$syslist[] = app_encode($x);
|
||||
$syslist[] = Zlib\Apps::app_encode($x);
|
||||
}
|
||||
}
|
||||
translate_system_apps($syslist);
|
||||
Zlib\Apps::translate_system_apps($syslist);
|
||||
}
|
||||
else
|
||||
$syslist = get_system_apps(true);
|
||||
$syslist = Zlib\Apps::get_system_apps(true);
|
||||
|
||||
usort($syslist,'app_name_compare');
|
||||
usort($syslist,'Zotlabs\\Lib\\Apps::app_name_compare');
|
||||
|
||||
// logger('apps: ' . print_r($syslist,true));
|
||||
|
||||
foreach($syslist as $app) {
|
||||
$apps[] = app_render($app,$mode);
|
||||
$apps[] = Zlib\Apps::app_render($app,$mode);
|
||||
}
|
||||
|
||||
return replace_macros(get_markup_template('myapps.tpl'), array(
|
||||
|
||||
@@ -40,7 +40,7 @@ class Attach extends \Zotlabs\Web\Controller {
|
||||
|
||||
header('Content-disposition: attachment; filename="' . $r['data']['filename'] . '"');
|
||||
if(intval($r['data']['os_storage'])) {
|
||||
$fname = dbunescbin($r['data']['data']);
|
||||
$fname = dbunescbin($r['data']['content']);
|
||||
if(strpos($fname,'store') !== false)
|
||||
$istream = fopen($fname,'rb');
|
||||
else
|
||||
@@ -53,7 +53,7 @@ class Attach extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
else
|
||||
echo dbunescbin($r['data']['data']);
|
||||
echo dbunescbin($r['data']['content']);
|
||||
killme();
|
||||
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/identity.php');
|
||||
require_once('include/channel.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
|
||||
@@ -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'],
|
||||
|
||||
@@ -6,14 +6,12 @@ require_once('include/bbcode.php');
|
||||
require_once('include/datetime.php');
|
||||
require_once('include/event.php');
|
||||
require_once('include/items.php');
|
||||
require_once('include/Contact.php');
|
||||
|
||||
|
||||
|
||||
class Cal extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
|
||||
if(observer_prohibited()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -22,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);
|
||||
|
||||
@@ -47,13 +45,12 @@ class Cal extends \Zotlabs\Web\Controller {
|
||||
|
||||
|
||||
|
||||
function get() {
|
||||
function get() {
|
||||
|
||||
if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
|
||||
if(observer_prohibited()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
$channel = null;
|
||||
|
||||
if(argc() > 1) {
|
||||
@@ -94,7 +91,7 @@ class Cal extends \Zotlabs\Web\Controller {
|
||||
$mode = 'view';
|
||||
$y = 0;
|
||||
$m = 0;
|
||||
$ignored = ((x($_REQUEST,'ignored')) ? " and ignored = " . intval($_REQUEST['ignored']) . " " : '');
|
||||
$ignored = ((x($_REQUEST,'ignored')) ? " and dismissed = " . intval($_REQUEST['ignored']) . " " : '');
|
||||
|
||||
// logger('args: ' . print_r(\App::$argv,true));
|
||||
|
||||
@@ -149,7 +146,7 @@ class Cal extends \Zotlabs\Web\Controller {
|
||||
$ftext = datetime_convert('UTC',$tz,$fdt);
|
||||
$ftext = substr($ftext,0,14) . "00:00";
|
||||
|
||||
$type = ((x($orig_event)) ? $orig_event['type'] : 'event');
|
||||
$type = ((x($orig_event)) ? $orig_event['etype'] : 'event');
|
||||
|
||||
$f = get_config('system','event_input_format');
|
||||
if(! $f)
|
||||
@@ -160,7 +157,7 @@ class Cal extends \Zotlabs\Web\Controller {
|
||||
|
||||
$show_bd = perm_is_allowed($channel['channel_id'], get_observer_hash(), 'view_contacts');
|
||||
if(! $show_bd) {
|
||||
$sql_extra .= " and event.type != 'birthday' ";
|
||||
$sql_extra .= " and event.etype != 'birthday' ";
|
||||
}
|
||||
|
||||
|
||||
@@ -228,8 +225,8 @@ class Cal extends \Zotlabs\Web\Controller {
|
||||
$r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan
|
||||
from event left join item on event_hash = resource_id
|
||||
where resource_type = 'event' and event.uid = %d $ignored
|
||||
AND (( adjust = 0 AND ( finish >= '%s' or nofinish = 1 ) AND start <= '%s' )
|
||||
OR ( adjust = 1 AND ( finish >= '%s' or nofinish = 1 ) AND start <= '%s' )) $sql_extra ",
|
||||
AND (( adjust = 0 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )
|
||||
OR ( adjust = 1 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )) $sql_extra ",
|
||||
intval($channel['channel_id']),
|
||||
dbesc($start),
|
||||
dbesc($finish),
|
||||
@@ -250,7 +247,7 @@ class Cal extends \Zotlabs\Web\Controller {
|
||||
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'j') : datetime_convert('UTC','UTC',$rr['start'],'j'));
|
||||
$j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'j') : datetime_convert('UTC','UTC',$rr['dtstart'],'j'));
|
||||
if(! x($links,$j))
|
||||
$links[$j] = z_root() . '/' . \App::$cmd . '#link-' . $j;
|
||||
}
|
||||
@@ -265,15 +262,15 @@ class Cal extends \Zotlabs\Web\Controller {
|
||||
|
||||
foreach($r as $rr) {
|
||||
|
||||
$j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'j') : datetime_convert('UTC','UTC',$rr['start'],'j'));
|
||||
$d = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], $fmt) : datetime_convert('UTC','UTC',$rr['start'],$fmt));
|
||||
$j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'j') : datetime_convert('UTC','UTC',$rr['dtstart'],'j'));
|
||||
$d = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], $fmt) : datetime_convert('UTC','UTC',$rr['dtstart'],$fmt));
|
||||
$d = day_translate($d);
|
||||
|
||||
$start = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'c') : datetime_convert('UTC','UTC',$rr['start'],'c'));
|
||||
$start = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'c') : datetime_convert('UTC','UTC',$rr['dtstart'],'c'));
|
||||
if ($rr['nofinish']){
|
||||
$end = null;
|
||||
} else {
|
||||
$end = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['finish'], 'c') : datetime_convert('UTC','UTC',$rr['finish'],'c'));
|
||||
$end = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtend'], 'c') : datetime_convert('UTC','UTC',$rr['dtend'],'c'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,357 +9,359 @@ 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 {
|
||||
|
||||
function init() {
|
||||
function init() {
|
||||
|
||||
$which = null;
|
||||
if(argc() > 1)
|
||||
$which = argv(1);
|
||||
if(! $which) {
|
||||
if(local_channel()) {
|
||||
$channel = \App::get_channel();
|
||||
if($channel && $channel['channel_address'])
|
||||
$which = null;
|
||||
if(argc() > 1)
|
||||
$which = argv(1);
|
||||
if(! $which) {
|
||||
if(local_channel()) {
|
||||
$channel = \App::get_channel();
|
||||
if($channel && $channel['channel_address'])
|
||||
$which = $channel['channel_address'];
|
||||
}
|
||||
}
|
||||
if(! $which) {
|
||||
notice( t('You must be logged in to see this page.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
$profile = 0;
|
||||
$channel = \App::get_channel();
|
||||
|
||||
if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
|
||||
$which = $channel['channel_address'];
|
||||
$profile = argv(1);
|
||||
}
|
||||
}
|
||||
if(! $which) {
|
||||
notice( t('You must be logged in to see this page.') . EOL );
|
||||
return;
|
||||
|
||||
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" title="' . t('Posts and comments') . '" href="' . z_root() . '/feed/' . $which . '" />' . "\r\n" ;
|
||||
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" title="' . t('Only posts') . '" href="' . z_root() . '/feed/' . $which . '?top=1" />' . "\r\n" ;
|
||||
|
||||
// Not yet ready for prime time
|
||||
// \App::$page['htmlhead'] .= '<link rel="openid.server" href="' . z_root() . '/id/' . $which .'?f=" />' . "\r\n" ;
|
||||
// \App::$page['htmlhead'] .= '<link rel="openid.delegate" href="' . z_root() . '/channel/' . $which .'" />' . "\r\n" ;
|
||||
|
||||
// Run profile_load() here to make sure the theme is set before
|
||||
// we start loading content
|
||||
|
||||
profile_load($which,$profile);
|
||||
|
||||
}
|
||||
|
||||
$profile = 0;
|
||||
$channel = \App::get_channel();
|
||||
|
||||
if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
|
||||
$which = $channel['channel_address'];
|
||||
$profile = argv(1);
|
||||
}
|
||||
|
||||
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" title="' . t('Posts and comments') . '" href="' . z_root() . '/feed/' . $which . '" />' . "\r\n" ;
|
||||
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" title="' . t('Only posts') . '" href="' . z_root() . '/feed/' . $which . '?top=1" />' . "\r\n" ;
|
||||
|
||||
// Not yet ready for prime time
|
||||
// \App::$page['htmlhead'] .= '<link rel="openid.server" href="' . z_root() . '/id/' . $which .'?f=" />' . "\r\n" ;
|
||||
// \App::$page['htmlhead'] .= '<link rel="openid.delegate" href="' . z_root() . '/channel/' . $which .'" />' . "\r\n" ;
|
||||
|
||||
// Run profile_load() here to make sure the theme is set before
|
||||
// we start loading content
|
||||
|
||||
profile_load($a,$which,$profile);
|
||||
|
||||
}
|
||||
|
||||
function get($update = 0, $load = false) {
|
||||
function get($update = 0, $load = false) {
|
||||
|
||||
|
||||
if($load)
|
||||
$_SESSION['loadtime'] = datetime_convert();
|
||||
if($load)
|
||||
$_SESSION['loadtime'] = datetime_convert();
|
||||
|
||||
$checkjs = new \Zotlabs\Web\CheckJS(1);
|
||||
$checkjs = new \Zotlabs\Web\CheckJS(1);
|
||||
|
||||
$category = $datequery = $datequery2 = '';
|
||||
$category = $datequery = $datequery2 = '';
|
||||
|
||||
$mid = ((x($_REQUEST,'mid')) ? $_REQUEST['mid'] : '');
|
||||
$mid = ((x($_REQUEST,'mid')) ? $_REQUEST['mid'] : '');
|
||||
|
||||
$datequery = ((x($_GET,'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : '');
|
||||
$datequery2 = ((x($_GET,'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : '');
|
||||
$datequery = ((x($_GET,'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : '');
|
||||
$datequery2 = ((x($_GET,'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : '');
|
||||
|
||||
if(get_config('system','block_public') && (! get_account_id()) && (! remote_channel())) {
|
||||
if(observer_prohibited(true)) {
|
||||
return login();
|
||||
}
|
||||
|
||||
$category = ((x($_REQUEST,'cat')) ? $_REQUEST['cat'] : '');
|
||||
$hashtags = ((x($_REQUEST,'tag')) ? $_REQUEST['tag'] : '');
|
||||
|
||||
$groups = array();
|
||||
|
||||
$o = '';
|
||||
|
||||
if($update) {
|
||||
// Ensure we've got a profile owner if updating.
|
||||
\App::$profile['profile_uid'] = \App::$profile_uid = $update;
|
||||
}
|
||||
else {
|
||||
if(\App::$profile['profile_uid'] == local_channel()) {
|
||||
nav_set_selected('home');
|
||||
}
|
||||
}
|
||||
|
||||
$is_owner = (((local_channel()) && (\App::$profile['profile_uid'] == local_channel())) ? true : false);
|
||||
$category = ((x($_REQUEST,'cat')) ? $_REQUEST['cat'] : '');
|
||||
$hashtags = ((x($_REQUEST,'tag')) ? $_REQUEST['tag'] : '');
|
||||
|
||||
$channel = \App::get_channel();
|
||||
$observer = \App::get_observer();
|
||||
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
|
||||
$groups = array();
|
||||
|
||||
$perms = get_all_perms(\App::$profile['profile_uid'],$ob_hash);
|
||||
$o = '';
|
||||
|
||||
if(! $perms['view_stream']) {
|
||||
if($update) {
|
||||
// Ensure we've got a profile owner if updating.
|
||||
\App::$profile['profile_uid'] = \App::$profile_uid = $update;
|
||||
}
|
||||
else {
|
||||
if(\App::$profile['profile_uid'] == local_channel()) {
|
||||
nav_set_selected('home');
|
||||
}
|
||||
}
|
||||
|
||||
$is_owner = (((local_channel()) && (\App::$profile['profile_uid'] == local_channel())) ? true : false);
|
||||
|
||||
$channel = \App::get_channel();
|
||||
$observer = \App::get_observer();
|
||||
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
|
||||
|
||||
$perms = get_all_perms(\App::$profile['profile_uid'],$ob_hash);
|
||||
|
||||
if(! $perms['view_stream']) {
|
||||
// We may want to make the target of this redirect configurable
|
||||
if($perms['view_profile']) {
|
||||
notice( t('Insufficient permissions. Request redirected to profile page.') . EOL);
|
||||
goaway (z_root() . "/profile/" . \App::$profile['channel_address']);
|
||||
}
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(! $update) {
|
||||
|
||||
$o .= profile_tabs($a, $is_owner, \App::$profile['channel_address']);
|
||||
|
||||
$o .= common_friends_visitor_widget(\App::$profile['profile_uid']);
|
||||
|
||||
if($channel && $is_owner) {
|
||||
$channel_acl = array(
|
||||
'allow_cid' => $channel['channel_allow_cid'],
|
||||
'allow_gid' => $channel['channel_allow_gid'],
|
||||
'deny_cid' => $channel['channel_deny_cid'],
|
||||
'deny_gid' => $channel['channel_deny_gid']
|
||||
);
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(! $update) {
|
||||
|
||||
$o .= profile_tabs($a, $is_owner, \App::$profile['channel_address']);
|
||||
|
||||
$o .= common_friends_visitor_widget(\App::$profile['profile_uid']);
|
||||
|
||||
if($channel && $is_owner) {
|
||||
$channel_acl = array(
|
||||
'allow_cid' => $channel['channel_allow_cid'],
|
||||
'allow_gid' => $channel['channel_allow_gid'],
|
||||
'deny_cid' => $channel['channel_deny_cid'],
|
||||
'deny_gid' => $channel['channel_deny_gid']
|
||||
);
|
||||
}
|
||||
else
|
||||
$channel_acl = array();
|
||||
|
||||
|
||||
if($perms['post_wall']) {
|
||||
|
||||
$x = array(
|
||||
'is_owner' => $is_owner,
|
||||
'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig(\App::$profile['profile_uid'],'system','use_browser_location')))) ? true : false),
|
||||
'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, \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),
|
||||
'profile_uid' => \App::$profile['profile_uid'],
|
||||
'editor_autocomplete' => true,
|
||||
'bbco_autocomplete' => 'bbcode',
|
||||
'bbcode' => true
|
||||
);
|
||||
|
||||
$o .= status_editor($a,$x);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
|
||||
*/
|
||||
|
||||
$item_normal = item_normal();
|
||||
$sql_extra = item_permissions_sql(\App::$profile['profile_uid']);
|
||||
|
||||
if(get_pconfig(\App::$profile['profile_uid'],'system','channel_list_mode') && (! $mid))
|
||||
$page_mode = 'list';
|
||||
else
|
||||
$channel_acl = array();
|
||||
$page_mode = 'client';
|
||||
|
||||
$abook_uids = " and abook.abook_channel = " . intval(\App::$profile['profile_uid']) . " ";
|
||||
|
||||
if($perms['post_wall']) {
|
||||
$simple_update = (($update) ? " AND item_unseen = 1 " : '');
|
||||
|
||||
$x = array(
|
||||
'is_owner' => $is_owner,
|
||||
'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig(\App::$profile['profile_uid'],'system','use_browser_location')))) ? true : false),
|
||||
'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') : ''),
|
||||
'showacl' => (($is_owner) ? 'yes' : ''),
|
||||
'bang' => '',
|
||||
'visitor' => (($is_owner || $observer) ? true : false),
|
||||
'profile_uid' => \App::$profile['profile_uid'],
|
||||
'editor_autocomplete' => true,
|
||||
'bbco_autocomplete' => 'bbcode',
|
||||
'bbcode' => true
|
||||
);
|
||||
|
||||
$o .= status_editor($a,$x);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
|
||||
*/
|
||||
|
||||
$item_normal = item_normal();
|
||||
$sql_extra = item_permissions_sql(\App::$profile['profile_uid']);
|
||||
|
||||
if(get_pconfig(\App::$profile['profile_uid'],'system','channel_list_mode') && (! $mid))
|
||||
$page_mode = 'list';
|
||||
else
|
||||
$page_mode = 'client';
|
||||
|
||||
$abook_uids = " and abook.abook_channel = " . intval(\App::$profile['profile_uid']) . " ";
|
||||
|
||||
$simple_update = (($update) ? " AND item_unseen = 1 " : '');
|
||||
|
||||
\App::$page['htmlhead'] .= "\r\n" . '<link rel="alternate" type="application/json+oembed" href="' . z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string) . '" title="oembed" />' . "\r\n";
|
||||
\App::$page['htmlhead'] .= "\r\n" . '<link rel="alternate" type="application/json+oembed" href="' . z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string) . '" title="oembed" />' . "\r\n";
|
||||
|
||||
if($update && $_SESSION['loadtime'])
|
||||
$simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) ";
|
||||
if($load)
|
||||
$simple_update = '';
|
||||
if($update && $_SESSION['loadtime'])
|
||||
$simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) ";
|
||||
if($load)
|
||||
$simple_update = '';
|
||||
|
||||
if(($update) && (! $load)) {
|
||||
if(($update) && (! $load)) {
|
||||
|
||||
if ($mid) {
|
||||
$r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal
|
||||
AND item_wall = 1 AND item_unseen = 1 $sql_extra limit 1",
|
||||
dbesc($mid . '%'),
|
||||
intval(\App::$profile['profile_uid'])
|
||||
);
|
||||
} else {
|
||||
$r = q("SELECT distinct parent AS `item_id`, created from item
|
||||
left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
|
||||
WHERE uid = %d $item_normal
|
||||
AND item_wall = 1 $simple_update
|
||||
AND (abook.abook_blocked = 0 or abook.abook_flags is null)
|
||||
$sql_extra
|
||||
ORDER BY created DESC",
|
||||
intval(\App::$profile['profile_uid'])
|
||||
);
|
||||
$_SESSION['loadtime'] = datetime_convert();
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
if(x($category)) {
|
||||
$sql_extra .= protect_sprintf(term_query('item', $category, TERM_CATEGORY));
|
||||
}
|
||||
if(x($hashtags)) {
|
||||
$sql_extra .= protect_sprintf(term_query('item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG));
|
||||
}
|
||||
|
||||
if($datequery) {
|
||||
$sql_extra2 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery))));
|
||||
}
|
||||
if($datequery2) {
|
||||
$sql_extra2 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2))));
|
||||
}
|
||||
|
||||
$itemspage = get_pconfig(local_channel(),'system','itemspage');
|
||||
\App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20));
|
||||
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start']));
|
||||
|
||||
if($load || ($checkjs->disabled())) {
|
||||
if ($mid) {
|
||||
$r = q("SELECT parent AS item_id from item where mid = '%s' and uid = %d $item_normal
|
||||
AND item_wall = 1 $sql_extra limit 1",
|
||||
dbesc($mid),
|
||||
if($mid) {
|
||||
$r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal
|
||||
AND item_wall = 1 AND item_unseen = 1 $sql_extra limit 1",
|
||||
dbesc($mid . '%'),
|
||||
intval(\App::$profile['profile_uid'])
|
||||
);
|
||||
if (! $r) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
}
|
||||
|
||||
} else {
|
||||
$r = q("SELECT distinct id AS item_id, created FROM item
|
||||
left join abook on item.author_xchan = abook.abook_xchan
|
||||
}
|
||||
else {
|
||||
$r = q("SELECT distinct parent AS `item_id`, created from item
|
||||
left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
|
||||
WHERE uid = %d $item_normal
|
||||
AND item_wall = 1 and item_thread_top = 1
|
||||
AND (abook_blocked = 0 or abook.abook_flags is null)
|
||||
$sql_extra $sql_extra2
|
||||
ORDER BY created DESC $pager_sql ",
|
||||
AND item_wall = 1 $simple_update
|
||||
AND (abook.abook_blocked = 0 or abook.abook_flags is null)
|
||||
$sql_extra
|
||||
ORDER BY created DESC",
|
||||
intval(\App::$profile['profile_uid'])
|
||||
);
|
||||
$_SESSION['loadtime'] = datetime_convert();
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
if(x($category)) {
|
||||
$sql_extra .= protect_sprintf(term_query('item', $category, TERM_CATEGORY));
|
||||
}
|
||||
if(x($hashtags)) {
|
||||
$sql_extra .= protect_sprintf(term_query('item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG));
|
||||
}
|
||||
|
||||
if($datequery) {
|
||||
$sql_extra2 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery))));
|
||||
}
|
||||
if($datequery2) {
|
||||
$sql_extra2 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2))));
|
||||
}
|
||||
|
||||
$itemspage = get_pconfig(local_channel(),'system','itemspage');
|
||||
\App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20));
|
||||
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start']));
|
||||
|
||||
if($load || ($checkjs->disabled())) {
|
||||
if($mid) {
|
||||
$r = q("SELECT parent AS item_id from item where mid = '%s' and uid = %d $item_normal
|
||||
AND item_wall = 1 $sql_extra limit 1",
|
||||
dbesc($mid),
|
||||
intval(\App::$profile['profile_uid'])
|
||||
);
|
||||
if (! $r) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
$r = q("SELECT distinct id AS item_id, created FROM item
|
||||
left join abook on item.author_xchan = abook.abook_xchan
|
||||
WHERE uid = %d $item_normal
|
||||
AND item_wall = 1 and item_thread_top = 1
|
||||
AND (abook_blocked = 0 or abook.abook_flags is null)
|
||||
$sql_extra $sql_extra2
|
||||
ORDER BY created DESC $pager_sql ",
|
||||
intval(\App::$profile['profile_uid'])
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$r = array();
|
||||
}
|
||||
}
|
||||
|
||||
if($r) {
|
||||
|
||||
$parents_str = ids_to_querystr($r,'item_id');
|
||||
|
||||
$items = q("SELECT `item`.*, `item`.`id` AS `item_id`
|
||||
FROM `item`
|
||||
WHERE `item`.`uid` = %d $item_normal
|
||||
AND `item`.`parent` IN ( %s )
|
||||
$sql_extra ",
|
||||
intval(\App::$profile['profile_uid']),
|
||||
dbesc($parents_str)
|
||||
);
|
||||
|
||||
xchan_query($items);
|
||||
$items = fetch_post_tags($items, true);
|
||||
$items = conv_sort($items,'created');
|
||||
|
||||
if($load && $mid && (! count($items))) {
|
||||
// This will happen if we don't have sufficient permissions
|
||||
// to view the parent item (or the item itself if it is toplevel)
|
||||
notice( t('Permission denied.') . EOL);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
$items = array();
|
||||
}
|
||||
|
||||
if((! $update) && (! $load)) {
|
||||
|
||||
// This is ugly, but we can't pass the profile_uid through the session to the ajax updater,
|
||||
// because browser prefetching might change it on us. We have to deliver it with the page.
|
||||
|
||||
$maxheight = get_pconfig(\App::$profile['profile_uid'],'system','channel_divmore_height');
|
||||
if(! $maxheight)
|
||||
$maxheight = 400;
|
||||
|
||||
$o .= '<div id="live-channel"></div>' . "\r\n";
|
||||
$o .= "<script> var profile_uid = " . \App::$profile['profile_uid']
|
||||
. "; var netargs = '?f='; var profile_page = " . \App::$pager['page']
|
||||
. "; divmore_height = " . intval($maxheight) . "; </script>\r\n";
|
||||
|
||||
\App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array(
|
||||
'$baseurl' => z_root(),
|
||||
'$pgtype' => 'channel',
|
||||
'$uid' => ((\App::$profile['profile_uid']) ? \App::$profile['profile_uid'] : '0'),
|
||||
'$gid' => '0',
|
||||
'$cid' => '0',
|
||||
'$cmin' => '0',
|
||||
'$cmax' => '0',
|
||||
'$star' => '0',
|
||||
'$liked' => '0',
|
||||
'$conv' => '0',
|
||||
'$spam' => '0',
|
||||
'$nouveau' => '0',
|
||||
'$wall' => '1',
|
||||
'$fh' => '0',
|
||||
'$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1),
|
||||
'$search' => '',
|
||||
'$order' => '',
|
||||
'$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0),
|
||||
'$file' => '',
|
||||
'$cats' => (($category) ? $category : ''),
|
||||
'$tags' => (($hashtags) ? $hashtags : ''),
|
||||
'$mid' => $mid,
|
||||
'$verb' => '',
|
||||
'$dend' => $datequery,
|
||||
'$dbegin' => $datequery2
|
||||
));
|
||||
|
||||
|
||||
}
|
||||
|
||||
$update_unseen = '';
|
||||
|
||||
if($page_mode === 'list') {
|
||||
|
||||
/**
|
||||
* in "list mode", only mark the parent item and any like activities as "seen".
|
||||
* We won't distinguish between comment likes and post likes. The important thing
|
||||
* is that the number of unseen comments will be accurate. The SQL to separate the
|
||||
* comment likes could also get somewhat hairy.
|
||||
*/
|
||||
|
||||
if($parents_str) {
|
||||
$update_unseen = " AND ( id IN ( " . dbesc($parents_str) . " )";
|
||||
$update_unseen .= " OR ( parent IN ( " . dbesc($parents_str) . " ) AND verb in ( '" . dbesc(ACTIVITY_LIKE) . "','" . dbesc(ACTIVITY_DISLIKE) . "' ))) ";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$r = array();
|
||||
}
|
||||
}
|
||||
|
||||
if($r) {
|
||||
|
||||
$parents_str = ids_to_querystr($r,'item_id');
|
||||
|
||||
$items = q("SELECT `item`.*, `item`.`id` AS `item_id`
|
||||
FROM `item`
|
||||
WHERE `item`.`uid` = %d $item_normal
|
||||
AND `item`.`parent` IN ( %s )
|
||||
$sql_extra ",
|
||||
intval(\App::$profile['profile_uid']),
|
||||
dbesc($parents_str)
|
||||
);
|
||||
|
||||
xchan_query($items);
|
||||
$items = fetch_post_tags($items, true);
|
||||
$items = conv_sort($items,'created');
|
||||
|
||||
if ($load && $mid && (! count($items))) {
|
||||
// This will happen if we don't have sufficient permissions
|
||||
// to view the parent item (or the item itself if it is toplevel)
|
||||
notice( t('Permission denied.') . EOL);
|
||||
if($parents_str) {
|
||||
$update_unseen = " AND parent IN ( " . dbesc($parents_str) . " )";
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
$items = array();
|
||||
}
|
||||
|
||||
if((! $update) && (! $load)) {
|
||||
|
||||
// This is ugly, but we can't pass the profile_uid through the session to the ajax updater,
|
||||
// because browser prefetching might change it on us. We have to deliver it with the page.
|
||||
|
||||
$maxheight = get_pconfig(\App::$profile['profile_uid'],'system','channel_divmore_height');
|
||||
if(! $maxheight)
|
||||
$maxheight = 400;
|
||||
|
||||
$o .= '<div id="live-channel"></div>' . "\r\n";
|
||||
$o .= "<script> var profile_uid = " . \App::$profile['profile_uid']
|
||||
. "; var netargs = '?f='; var profile_page = " . \App::$pager['page']
|
||||
. "; divmore_height = " . intval($maxheight) . "; </script>\r\n";
|
||||
|
||||
\App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array(
|
||||
'$baseurl' => z_root(),
|
||||
'$pgtype' => 'channel',
|
||||
'$uid' => ((\App::$profile['profile_uid']) ? \App::$profile['profile_uid'] : '0'),
|
||||
'$gid' => '0',
|
||||
'$cid' => '0',
|
||||
'$cmin' => '0',
|
||||
'$cmax' => '0',
|
||||
'$star' => '0',
|
||||
'$liked' => '0',
|
||||
'$conv' => '0',
|
||||
'$spam' => '0',
|
||||
'$nouveau' => '0',
|
||||
'$wall' => '1',
|
||||
'$fh' => '0',
|
||||
'$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1),
|
||||
'$search' => '',
|
||||
'$order' => '',
|
||||
'$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0),
|
||||
'$file' => '',
|
||||
'$cats' => (($category) ? $category : ''),
|
||||
'$tags' => (($hashtags) ? $hashtags : ''),
|
||||
'$mid' => $mid,
|
||||
'$verb' => '',
|
||||
'$dend' => $datequery,
|
||||
'$dbegin' => $datequery2
|
||||
));
|
||||
|
||||
|
||||
}
|
||||
|
||||
$update_unseen = '';
|
||||
|
||||
if($page_mode === 'list') {
|
||||
|
||||
/**
|
||||
* in "list mode", only mark the parent item and any like activities as "seen".
|
||||
* We won't distinguish between comment likes and post likes. The important thing
|
||||
* is that the number of unseen comments will be accurate. The SQL to separate the
|
||||
* comment likes could also get somewhat hairy.
|
||||
*/
|
||||
|
||||
if($parents_str) {
|
||||
$update_unseen = " AND ( id IN ( " . dbesc($parents_str) . " )";
|
||||
$update_unseen .= " OR ( parent IN ( " . dbesc($parents_str) . " ) AND verb in ( '" . dbesc(ACTIVITY_LIKE) . "','" . dbesc(ACTIVITY_DISLIKE) . "' ))) ";
|
||||
if($is_owner && $update_unseen) {
|
||||
$r = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 and item_wall = 1 AND uid = %d $update_unseen",
|
||||
intval(local_channel())
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if($parents_str) {
|
||||
$update_unseen = " AND parent IN ( " . dbesc($parents_str) . " )";
|
||||
|
||||
|
||||
if($checkjs->disabled()) {
|
||||
$o .= conversation($a,$items,'channel',$update,'traditional');
|
||||
}
|
||||
else {
|
||||
$o .= conversation($a,$items,'channel',$update,$page_mode);
|
||||
}
|
||||
|
||||
if((! $update) || ($checkjs->disabled())) {
|
||||
$o .= alt_pager($a,count($items));
|
||||
if ($mid && $items[0]['title'])
|
||||
\App::$page['title'] = $items[0]['title'] . " - " . \App::$page['title'];
|
||||
}
|
||||
|
||||
if($mid)
|
||||
$o .= '<div id="content-complete"></div>';
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
if($is_owner && $update_unseen) {
|
||||
$r = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 and item_wall = 1 AND uid = %d $update_unseen",
|
||||
intval(local_channel())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if($checkjs->disabled()) {
|
||||
$o .= conversation($a,$items,'channel',$update,'traditional');
|
||||
} else {
|
||||
$o .= conversation($a,$items,'channel',$update,$page_mode);
|
||||
}
|
||||
|
||||
if((! $update) || ($checkjs->disabled())) {
|
||||
$o .= alt_pager($a,count($items));
|
||||
if ($mid && $items[0]['title'])
|
||||
\App::$page['title'] = $items[0]['title'] . " - " . \App::$page['title'];
|
||||
}
|
||||
|
||||
if($mid)
|
||||
$o .= '<div id="content-complete"></div>';
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/Contact.php');
|
||||
require_once('include/zot.php');
|
||||
|
||||
|
||||
class Chanview extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
@@ -62,18 +60,15 @@ class Chanview extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
if($_REQUEST['address']) {
|
||||
$ret = zot_finger($_REQUEST['address'],null);
|
||||
if($ret['success']) {
|
||||
$j = json_decode($ret['body'],true);
|
||||
if($j)
|
||||
import_xchan($j);
|
||||
$j = \Zotlabs\Zot\Finger::run($_REQUEST['address'],null);
|
||||
if($j['success']) {
|
||||
import_xchan($j);
|
||||
$r = q("select * from xchan where xchan_addr = '%s' limit 1",
|
||||
dbesc($_REQUEST['address'])
|
||||
);
|
||||
if($r)
|
||||
\App::$poi = $r[0];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module; /** @file */
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
|
||||
require_once('include/chat.php');
|
||||
require_once('include/bookmarks.php');
|
||||
|
||||
use \Zotlabs\Lib as Zlib;
|
||||
|
||||
class Chat extends \Zotlabs\Web\Controller {
|
||||
|
||||
@@ -37,11 +39,11 @@ 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);
|
||||
|
||||
}
|
||||
|
||||
function post() {
|
||||
function post() {
|
||||
|
||||
if($_POST['room_name'])
|
||||
$room = strip_tags(trim($_POST['room_name']));
|
||||
@@ -54,7 +56,7 @@ class Chat extends \Zotlabs\Web\Controller {
|
||||
|
||||
if($_POST['action'] === 'drop') {
|
||||
logger('delete chatroom');
|
||||
chatroom_destroy($channel,array('cr_name' => $room));
|
||||
Zlib\Chatroom::destroy($channel,array('cr_name' => $room));
|
||||
goaway(z_root() . '/chat/' . $channel['channel_address']);
|
||||
}
|
||||
|
||||
@@ -67,7 +69,7 @@ class Chat extends \Zotlabs\Web\Controller {
|
||||
if(intval($arr['expire']) < 0)
|
||||
$arr['expire'] = 0;
|
||||
|
||||
chatroom_create($channel,$arr);
|
||||
Zlib\Chatroom::create($channel,$arr);
|
||||
|
||||
$x = q("select * from chatroom where cr_name = '%s' and cr_uid = %d limit 1",
|
||||
dbesc($room),
|
||||
@@ -87,7 +89,7 @@ class Chat extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
|
||||
function get() {
|
||||
function get() {
|
||||
|
||||
if(local_channel())
|
||||
$channel = \App::get_channel();
|
||||
@@ -105,7 +107,7 @@ class Chat extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
if((argc() > 3) && intval(argv(2)) && (argv(3) === 'leave')) {
|
||||
chatroom_leave($observer,argv(2),$_SERVER['REMOTE_ADDR']);
|
||||
Zlib\Chatroom::leave($observer,argv(2),$_SERVER['REMOTE_ADDR']);
|
||||
goaway(z_root() . '/channel/' . argv(1));
|
||||
}
|
||||
|
||||
@@ -158,7 +160,7 @@ class Chat extends \Zotlabs\Web\Controller {
|
||||
$room_id = intval(argv(2));
|
||||
$bookmark_link = get_bookmark_link($ob);
|
||||
|
||||
$x = chatroom_enter($observer,$room_id,'online',$_SERVER['REMOTE_ADDR']);
|
||||
$x = Zlib\Chatroom::enter($observer,$room_id,'online',$_SERVER['REMOTE_ADDR']);
|
||||
if(! $x)
|
||||
return;
|
||||
$x = q("select * from chatroom where cr_id = %d and cr_uid = %d $sql_extra limit 1",
|
||||
@@ -216,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(
|
||||
@@ -232,16 +233,20 @@ 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 = chatroom_list(\App::$profile['profile_uid']);
|
||||
|
||||
$rooms = Zlib\Chatroom::roomlist(\App::$profile['profile_uid']);
|
||||
|
||||
$o .= replace_macros(get_markup_template('chatrooms.tpl'), array(
|
||||
'$header' => sprintf( t('%1$s\'s Chatrooms'), \App::$profile['name']),
|
||||
'$header' => sprintf( t('%1$s\'s Chatrooms'), \App::$profile['fullname']),
|
||||
'$name' => t('Name'),
|
||||
'$baseurl' => z_root(),
|
||||
'$nickname' => \App::$profile['channel_address'],
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module; /** @file */
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/security.php');
|
||||
|
||||
use \Zotlabs\Lib as Zlib;
|
||||
|
||||
class Chatsvc extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
//logger('chatsvc');
|
||||
//logger('chatsvc');
|
||||
|
||||
$ret = array('success' => false);
|
||||
|
||||
@@ -27,7 +29,7 @@ class Chatsvc extends \Zotlabs\Web\Controller {
|
||||
|
||||
}
|
||||
|
||||
function post() {
|
||||
function post() {
|
||||
|
||||
$ret = array('success' => false);
|
||||
|
||||
@@ -65,7 +67,7 @@ class Chatsvc extends \Zotlabs\Web\Controller {
|
||||
json_return_and_die($ret);
|
||||
}
|
||||
|
||||
function get() {
|
||||
function get() {
|
||||
|
||||
$status = strip_tags($_REQUEST['status']);
|
||||
$room_id = intval(\App::$data['chat']['room_id']);
|
||||
|
||||
@@ -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);
|
||||
@@ -100,9 +91,12 @@ class Cloud extends \Zotlabs\Web\Controller {
|
||||
// require_once('\Zotlabs\Storage/QuotaPlugin.php');
|
||||
// $server->addPlugin(new \Zotlabs\Storage\\QuotaPlugin($auth));
|
||||
|
||||
ob_start();
|
||||
// All we need to do now, is to fire up the server
|
||||
$server->exec();
|
||||
|
||||
|
||||
ob_end_flush();
|
||||
|
||||
killme();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
namespace Zotlabs\Module; /** @file */
|
||||
|
||||
|
||||
require_once('include/Contact.php');
|
||||
|
||||
require_once('include/contact_widgets.php');
|
||||
require_once('include/items.php');
|
||||
|
||||
@@ -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() {
|
||||
@@ -47,7 +47,8 @@ class Connect extends \Zotlabs\Web\Controller {
|
||||
intval(PAGE_PREMIUM),
|
||||
intval(local_channel())
|
||||
);
|
||||
proc_run('php','include/notifier.php','refresh_all',\App::$data['channel']['channel_id']);
|
||||
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier','refresh_all',\App::$data['channel']['channel_id']));
|
||||
}
|
||||
set_pconfig(\App::$data['channel']['channel_id'],'system','selltext',$text);
|
||||
// reload the page completely to get fresh data
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/Contact.php');
|
||||
|
||||
require_once('include/socgraph.php');
|
||||
require_once('include/contact_selectors.php');
|
||||
require_once('include/selectors.php');
|
||||
require_once('include/group.php');
|
||||
require_once('include/contact_widgets.php');
|
||||
require_once('include/zot.php');
|
||||
|
||||
@@ -7,23 +7,23 @@ namespace Zotlabs\Module;
|
||||
*
|
||||
*/
|
||||
|
||||
require_once('include/Contact.php');
|
||||
|
||||
require_once('include/socgraph.php');
|
||||
require_once('include/contact_selectors.php');
|
||||
require_once('include/selectors.php');
|
||||
require_once('include/group.php');
|
||||
require_once('include/contact_widgets.php');
|
||||
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']),
|
||||
@@ -176,7 +199,7 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
$record = $z[0]['xlink_id'];
|
||||
}
|
||||
if($record) {
|
||||
proc_run('php','include/ratenotif.php','rating',$record);
|
||||
\Zotlabs\Daemon\Master::Summon(array('Ratenotif','rating',$record));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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']))) {
|
||||
proc_run('php', 'include/notifier.php', (($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) {
|
||||
@@ -270,7 +302,7 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
array('rel' => 'photo', 'type' => \App::$poi['xchan_photo_mimetype'], 'href' => \App::$poi['xchan_photo_l'])
|
||||
),
|
||||
);
|
||||
$xarr['object'] = json_encode($obj);
|
||||
$xarr['obj'] = json_encode($obj);
|
||||
$xarr['obj_type'] = ACTIVITY_OBJ_PERSON;
|
||||
|
||||
$xarr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t('is now connected to') . ' ' . '[zrl=' . \App::$poi['xchan_url'] . ']' . \App::$poi['xchan_name'] . '[/zrl]';
|
||||
@@ -283,7 +315,7 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
|
||||
|
||||
// pull in a bit of content if there is any to pull in
|
||||
proc_run('php','include/onepoll.php',$contact_id);
|
||||
\Zotlabs\Daemon\Master::Summon(array('Onepoll',$contact_id));
|
||||
|
||||
}
|
||||
|
||||
@@ -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'));
|
||||
@@ -414,11 +443,17 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
|
||||
if($cmd === 'update') {
|
||||
// pull feed and consume it, which should subscribe to the hub.
|
||||
proc_run('php',"include/poller.php","$contact_id");
|
||||
\Zotlabs\Daemon\Master::Summon(array('Poller',$contact_id));
|
||||
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
|
||||
proc_run('php','include/notifier.php','permission_update',$contact_id);
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier','permission_update',$contact_id));
|
||||
}
|
||||
goaway(z_root() . '/connedit/' . $contact_id);
|
||||
}
|
||||
@@ -485,7 +520,6 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
|
||||
if($cmd === 'drop') {
|
||||
|
||||
require_once('include/Contact.php');
|
||||
|
||||
// FIXME
|
||||
// We need to send either a purge or a refresh packet to the other side (the channel being unfriended).
|
||||
@@ -583,8 +617,6 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
if(intval($contact['abook_self']))
|
||||
$self = true;
|
||||
|
||||
require_once('include/contact_selectors.php');
|
||||
|
||||
$tpl = get_markup_template("abook_edit.tpl");
|
||||
|
||||
if(feature_enabled(local_channel(),'affinity')) {
|
||||
@@ -651,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')));
|
||||
@@ -667,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 = '';
|
||||
|
||||
@@ -41,10 +41,10 @@ class Contactgroup extends \Zotlabs\Web\Controller {
|
||||
|
||||
if($change) {
|
||||
if(in_array($change,$preselected)) {
|
||||
group_rmv_member(local_channel(),$group['name'],$change);
|
||||
group_rmv_member(local_channel(),$group['gname'],$change);
|
||||
}
|
||||
else {
|
||||
group_add_member(local_channel(),$group['name'],$change);
|
||||
group_add_member(local_channel(),$group['gname'],$change);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Zotlabs\Module;
|
||||
*/
|
||||
|
||||
require_once('include/photo/photo_driver.php');
|
||||
require_once('include/identity.php');
|
||||
require_once('include/channel.php');
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -80,7 +80,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
$profile = $r[0];
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND scale = 0 LIMIT 1",
|
||||
$r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale = 0 LIMIT 1",
|
||||
dbesc($image_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
@@ -88,9 +88,9 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
if($r) {
|
||||
|
||||
$base_image = $r[0];
|
||||
$base_image['data'] = (($r[0]['os_storage']) ? @file_get_contents($base_image['data']) : dbunescbin($base_image['data']));
|
||||
$base_image['content'] = (($r[0]['os_storage']) ? @file_get_contents($base_image['content']) : dbunescbin($base_image['content']));
|
||||
|
||||
$im = photo_factory($base_image['data'], $base_image['type']);
|
||||
$im = photo_factory($base_image['content'], $base_image['mimetype']);
|
||||
if($im->is_valid()) {
|
||||
|
||||
// We are scaling and cropping the relative pixel locations to the original photo instead of the
|
||||
@@ -99,7 +99,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
// First load the scaled photo to check its size. (Should probably pass this in the post form and save
|
||||
// a query.)
|
||||
|
||||
$g = q("select width, height from photo where resource_id = '%s' and uid = %d and scale = 3",
|
||||
$g = q("select width, height from photo where resource_id = '%s' and uid = %d and imgscale = 3",
|
||||
dbesc($image_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
@@ -133,26 +133,26 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
$p = array('aid' => $aid, 'uid' => local_channel(), 'resource_id' => $base_image['resource_id'],
|
||||
'filename' => $base_image['filename'], 'album' => t('Cover Photos'));
|
||||
|
||||
$p['scale'] = 7;
|
||||
$p['imgscale'] = 7;
|
||||
$p['photo_usage'] = PHOTO_COVER;
|
||||
|
||||
$r1 = $im->save($p);
|
||||
|
||||
$im->doScaleImage(850,310);
|
||||
$p['scale'] = 8;
|
||||
$p['imgscale'] = 8;
|
||||
|
||||
$r2 = $im->save($p);
|
||||
|
||||
|
||||
$im->doScaleImage(425,160);
|
||||
$p['scale'] = 9;
|
||||
$p['imgscale'] = 9;
|
||||
|
||||
$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 scale >= 7 ",
|
||||
$x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale >= 7 ",
|
||||
dbesc($base_image['resource_id']),
|
||||
local_channel()
|
||||
);
|
||||
@@ -183,7 +183,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
logger('attach_store: ' . print_r($res,true));
|
||||
|
||||
if($res && intval($res['data']['is_photo'])) {
|
||||
$i = q("select * from photo where resource_id = '%s' and uid = %d and scale = 0",
|
||||
$i = q("select * from photo where resource_id = '%s' and uid = %d and imgscale = 0",
|
||||
dbesc($hash),
|
||||
intval(local_channel())
|
||||
);
|
||||
@@ -195,10 +195,10 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
$os_storage = false;
|
||||
|
||||
foreach($i as $ii) {
|
||||
$smallest = intval($ii['scale']);
|
||||
$smallest = intval($ii['imgscale']);
|
||||
$os_storage = intval($ii['os_storage']);
|
||||
$imagedata = $ii['data'];
|
||||
$filetype = $ii['type'];
|
||||
$imagedata = $ii['content'];
|
||||
$filetype = $ii['mimetype'];
|
||||
|
||||
}
|
||||
}
|
||||
@@ -224,10 +224,10 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
$arr['obj_type'] = ACTIVITY_OBJ_PHOTO;
|
||||
$arr['verb'] = ACTIVITY_UPDATE;
|
||||
|
||||
$arr['object'] = json_encode(array(
|
||||
$arr['obj'] = json_encode(array(
|
||||
'type' => $arr['obj_type'],
|
||||
'id' => z_root() . '/photo/' . $photo['resource_id'] . '-7',
|
||||
'link' => array('rel' => 'photo', 'type' => $photo['type'], 'href' => z_root() . '/photo/' . $photo['resource_id'] . '-7')
|
||||
'link' => array('rel' => 'photo', 'type' => $photo['mimetype'], 'href' => z_root() . '/photo/' . $photo['resource_id'] . '-7')
|
||||
));
|
||||
|
||||
if($profile && stripos($profile['gender'],t('female')) !== false)
|
||||
@@ -271,7 +271,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
*/
|
||||
|
||||
|
||||
function get() {
|
||||
function get() {
|
||||
|
||||
if(! local_channel()) {
|
||||
notice( t('Permission denied.') . EOL );
|
||||
@@ -295,7 +295,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
|
||||
$resource_id = argv(2);
|
||||
|
||||
$r = q("SELECT id, album, scale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY scale ASC",
|
||||
$r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY imgscale ASC",
|
||||
intval(local_channel()),
|
||||
dbesc($resource_id)
|
||||
);
|
||||
@@ -305,11 +305,11 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
$havescale = false;
|
||||
foreach($r as $rr) {
|
||||
if($rr['scale'] == 7)
|
||||
if($rr['imgscale'] == 7)
|
||||
$havescale = true;
|
||||
}
|
||||
|
||||
$r = q("SELECT `data`, `type`, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1",
|
||||
$r = q("SELECT `content`, `mimetype`, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1",
|
||||
intval($r[0]['id']),
|
||||
intval(local_channel())
|
||||
|
||||
@@ -320,15 +320,15 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
if(intval($r[0]['os_storage']))
|
||||
$data = @file_get_contents($r[0]['data']);
|
||||
$data = @file_get_contents($r[0]['content']);
|
||||
else
|
||||
$data = dbunescbin($r[0]['data']);
|
||||
$data = dbunescbin($r[0]['content']);
|
||||
|
||||
$ph = photo_factory($data, $r[0]['type']);
|
||||
$ph = photo_factory($data, $r[0]['mimetype']);
|
||||
$smallest = 0;
|
||||
if($ph->is_valid()) {
|
||||
// go ahead as if we have just uploaded a new photo to crop
|
||||
$i = q("select resource_id, scale from photo where resource_id = '%s' and uid = %d and scale = 0",
|
||||
$i = q("select resource_id, imgscale from photo where resource_id = '%s' and uid = %d and imgscale = 0",
|
||||
dbesc($r[0]['resource_id']),
|
||||
intval(local_channel())
|
||||
);
|
||||
@@ -336,12 +336,12 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
if($i) {
|
||||
$hash = $i[0]['resource_id'];
|
||||
foreach($i as $ii) {
|
||||
$smallest = intval($ii['scale']);
|
||||
$smallest = intval($ii['imgscale']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cover_photo_crop_ui_head($a, $ph, $hash, $smallest);
|
||||
$this->cover_photo_crop_ui_head($a, $ph, $hash, $smallest);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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,59 +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');
|
||||
|
||||
// $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
|
||||
@@ -113,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();
|
||||
|
||||
@@ -57,9 +57,9 @@ class Directory extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
function get() {
|
||||
function get() {
|
||||
|
||||
if((get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
|
||||
if(observer_prohibited()) {
|
||||
notice( t('Public access denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -7,17 +7,13 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get($update = 0, $load = false) {
|
||||
|
||||
// logger("mod-display: update = $update load = $load");
|
||||
|
||||
|
||||
$checkjs = new \Zotlabs\Web\CheckJS(1);
|
||||
|
||||
|
||||
if($load)
|
||||
$_SESSION['loadtime'] = datetime_convert();
|
||||
|
||||
|
||||
if(intval(get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) {
|
||||
if(observer_prohibited()) {
|
||||
notice( t('Public access denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
@@ -69,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(),
|
||||
@@ -110,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);
|
||||
@@ -185,7 +183,7 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
if($load || ($checkjs->disabled())) {
|
||||
$r = null;
|
||||
|
||||
require_once('include/identity.php');
|
||||
require_once('include/channel.php');
|
||||
$sys = get_sys_channel();
|
||||
$sysid = $sys['channel_id'];
|
||||
|
||||
@@ -233,7 +231,7 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
elseif($update && !$load) {
|
||||
$r = null;
|
||||
|
||||
require_once('include/identity.php');
|
||||
require_once('include/channel.php');
|
||||
$sys = get_sys_channel();
|
||||
$sysid = $sys['channel_id'];
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/identity.php');
|
||||
require_once('include/channel.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/conversation.php');
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/identity.php');
|
||||
require_once('include/channel.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/conversation.php');
|
||||
|
||||
@@ -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 = '';
|
||||
@@ -87,11 +87,11 @@ class Editpost extends \Zotlabs\Web\Controller {
|
||||
'hide_location' => true,
|
||||
'mimetype' => $itm[0]['mimetype'],
|
||||
'ptyp' => $itm[0]['obj_type'],
|
||||
'body' => undo_post_tagging($itm[0]['body']),
|
||||
'body' => htmlspecialchars_decode(undo_post_tagging($itm[0]['body']),ENT_COMPAT),
|
||||
'post_id' => $post_id,
|
||||
'defloc' => $channel['channel_location'],
|
||||
'visitor' => true,
|
||||
'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'),
|
||||
'title' => htmlspecialchars_decode($itm[0]['title'],ENT_COMPAT),
|
||||
'category' => $category,
|
||||
'showacl' => false,
|
||||
'profile_uid' => $owner_uid,
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/identity.php');
|
||||
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 {
|
||||
@@ -171,7 +170,7 @@ class Events extends \Zotlabs\Web\Controller {
|
||||
foreach($cats as $cat) {
|
||||
$post_tags[] = array(
|
||||
'uid' => $profile_uid,
|
||||
'type' => TERM_CATEGORY,
|
||||
'ttype' => TERM_CATEGORY,
|
||||
'otype' => TERM_OBJ_POST,
|
||||
'term' => trim($cat),
|
||||
'url' => $channel['xchan_url'] . '?f=&cat=' . urlencode(trim($cat))
|
||||
@@ -180,12 +179,12 @@ class Events extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
$datarray = array();
|
||||
$datarray['start'] = $start;
|
||||
$datarray['finish'] = $finish;
|
||||
$datarray['dtstart'] = $start;
|
||||
$datarray['dtend'] = $finish;
|
||||
$datarray['summary'] = $summary;
|
||||
$datarray['description'] = $desc;
|
||||
$datarray['location'] = $location;
|
||||
$datarray['type'] = $type;
|
||||
$datarray['etype'] = $type;
|
||||
$datarray['adjust'] = $adjust;
|
||||
$datarray['nofinish'] = $nofinish;
|
||||
$datarray['uid'] = local_channel();
|
||||
@@ -232,7 +231,7 @@ class Events extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
if($share)
|
||||
proc_run('php',"include/notifier.php","event","$item_id");
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier','event',$item_id));
|
||||
|
||||
}
|
||||
|
||||
@@ -269,14 +268,14 @@ class Events extends \Zotlabs\Web\Controller {
|
||||
nav_set_selected('all_events');
|
||||
|
||||
if((argc() > 2) && (argv(1) === 'ignore') && intval(argv(2))) {
|
||||
$r = q("update event set ignore = 1 where id = %d and uid = %d",
|
||||
$r = q("update event set dismissed = 1 where id = %d and uid = %d",
|
||||
intval(argv(2)),
|
||||
intval(local_channel())
|
||||
);
|
||||
}
|
||||
|
||||
if((argc() > 2) && (argv(1) === 'unignore') && intval(argv(2))) {
|
||||
$r = q("update event set ignore = 0 where id = %d and uid = %d",
|
||||
$r = q("update event set dismissed = 0 where id = %d and uid = %d",
|
||||
intval(argv(2)),
|
||||
intval(local_channel())
|
||||
);
|
||||
@@ -301,7 +300,7 @@ class Events extends \Zotlabs\Web\Controller {
|
||||
$mode = 'view';
|
||||
$y = 0;
|
||||
$m = 0;
|
||||
$ignored = ((x($_REQUEST,'ignored')) ? " and ignored = " . intval($_REQUEST['ignored']) . " " : '');
|
||||
$ignored = ((x($_REQUEST,'ignored')) ? " and dismissed = " . intval($_REQUEST['ignored']) . " " : '');
|
||||
|
||||
|
||||
// logger('args: ' . print_r(\App::$argv,true));
|
||||
@@ -358,9 +357,9 @@ class Events extends \Zotlabs\Web\Controller {
|
||||
if(x($_REQUEST,'summary')) $orig_event['summary'] = $_REQUEST['summary'];
|
||||
if(x($_REQUEST,'description')) $orig_event['description'] = $_REQUEST['description'];
|
||||
if(x($_REQUEST,'location')) $orig_event['location'] = $_REQUEST['location'];
|
||||
if(x($_REQUEST,'start')) $orig_event['start'] = $_REQUEST['start'];
|
||||
if(x($_REQUEST,'finish')) $orig_event['finish'] = $_REQUEST['finish'];
|
||||
if(x($_REQUEST,'type')) $orig_event['type'] = $_REQUEST['type'];
|
||||
if(x($_REQUEST,'start')) $orig_event['dtstart'] = $_REQUEST['start'];
|
||||
if(x($_REQUEST,'finish')) $orig_event['dtend'] = $_REQUEST['finish'];
|
||||
if(x($_REQUEST,'type')) $orig_event['etype'] = $_REQUEST['type'];
|
||||
*/
|
||||
|
||||
$n_checked = ((x($orig_event) && $orig_event['nofinish']) ? ' checked="checked" ' : '');
|
||||
@@ -380,9 +379,9 @@ class Events extends \Zotlabs\Web\Controller {
|
||||
if($orig_event['event_xchan'])
|
||||
$sh_checked .= ' disabled="disabled" ';
|
||||
|
||||
$sdt = ((x($orig_event)) ? $orig_event['start'] : 'now');
|
||||
$sdt = ((x($orig_event)) ? $orig_event['dtstart'] : 'now');
|
||||
|
||||
$fdt = ((x($orig_event)) ? $orig_event['finish'] : '+1 hour');
|
||||
$fdt = ((x($orig_event)) ? $orig_event['dtend'] : '+1 hour');
|
||||
|
||||
$tz = date_default_timezone_get();
|
||||
if(x($orig_event))
|
||||
@@ -406,7 +405,7 @@ class Events extends \Zotlabs\Web\Controller {
|
||||
$ftext = datetime_convert('UTC',$tz,$fdt);
|
||||
$ftext = substr($ftext,0,14) . "00:00";
|
||||
|
||||
$type = ((x($orig_event)) ? $orig_event['type'] : 'event');
|
||||
$type = ((x($orig_event)) ? $orig_event['etype'] : 'event');
|
||||
|
||||
$f = get_config('system','event_input_format');
|
||||
if(! $f)
|
||||
@@ -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')
|
||||
|
||||
@@ -536,8 +545,8 @@ class Events extends \Zotlabs\Web\Controller {
|
||||
);
|
||||
} elseif($export) {
|
||||
$r = q("SELECT * from event where uid = %d
|
||||
AND (( `adjust` = 0 AND ( `finish` >= '%s' or nofinish = 1 ) AND `start` <= '%s' )
|
||||
OR ( `adjust` = 1 AND ( `finish` >= '%s' or nofinish = 1 ) AND `start` <= '%s' )) ",
|
||||
AND (( `adjust` = 0 AND ( `dtend` >= '%s' or nofinish = 1 ) AND `dtstart` <= '%s' )
|
||||
OR ( `adjust` = 1 AND ( `dtend` >= '%s' or nofinish = 1 ) AND `dtstart` <= '%s' )) ",
|
||||
intval(local_channel()),
|
||||
dbesc($start),
|
||||
dbesc($finish),
|
||||
@@ -554,8 +563,8 @@ class Events extends \Zotlabs\Web\Controller {
|
||||
$r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan
|
||||
from event left join item on event_hash = resource_id
|
||||
where resource_type = 'event' and event.uid = %d $ignored
|
||||
AND (( adjust = 0 AND ( finish >= '%s' or nofinish = 1 ) AND start <= '%s' )
|
||||
OR ( adjust = 1 AND ( finish >= '%s' or nofinish = 1 ) AND start <= '%s' )) ",
|
||||
AND (( adjust = 0 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )
|
||||
OR ( adjust = 1 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )) ",
|
||||
intval(local_channel()),
|
||||
dbesc($start),
|
||||
dbesc($finish),
|
||||
@@ -576,7 +585,7 @@ class Events extends \Zotlabs\Web\Controller {
|
||||
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'j') : datetime_convert('UTC','UTC',$rr['start'],'j'));
|
||||
$j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'j') : datetime_convert('UTC','UTC',$rr['dtstart'],'j'));
|
||||
if(! x($links,$j))
|
||||
$links[$j] = z_root() . '/' . \App::$cmd . '#link-' . $j;
|
||||
}
|
||||
@@ -591,15 +600,15 @@ class Events extends \Zotlabs\Web\Controller {
|
||||
|
||||
foreach($r as $rr) {
|
||||
|
||||
$j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'j') : datetime_convert('UTC','UTC',$rr['start'],'j'));
|
||||
$d = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], $fmt) : datetime_convert('UTC','UTC',$rr['start'],$fmt));
|
||||
$j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'j') : datetime_convert('UTC','UTC',$rr['dtstart'],'j'));
|
||||
$d = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], $fmt) : datetime_convert('UTC','UTC',$rr['dtstart'],$fmt));
|
||||
$d = day_translate($d);
|
||||
|
||||
$start = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'c') : datetime_convert('UTC','UTC',$rr['start'],'c'));
|
||||
$start = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'c') : datetime_convert('UTC','UTC',$rr['dtstart'],'c'));
|
||||
if ($rr['nofinish']){
|
||||
$end = null;
|
||||
} else {
|
||||
$end = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['finish'], 'c') : datetime_convert('UTC','UTC',$rr['finish'],'c'));
|
||||
$end = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtend'], 'c') : datetime_convert('UTC','UTC',$rr['dtend'],'c'));
|
||||
}
|
||||
|
||||
|
||||
@@ -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,10 +45,10 @@ class Fbrowser extends \Zotlabs\Web\Controller {
|
||||
$album = hex2bin(\App::$argv[2]);
|
||||
$sql_extra = sprintf("AND `album` = '%s' ",dbesc($album));
|
||||
$sql_extra2 = "";
|
||||
$path[]=array(z_root()."/fbrowser/image/".\App::$argv[2]."/", $album);
|
||||
$path[]=array(z_root() . "/fbrowser/image/" . \App::$argv[2] . "/", $album);
|
||||
}
|
||||
|
||||
$r = q("SELECT `resource_id`, `id`, `filename`, type, min(`scale`) AS `hiq`,max(`scale`) AS `loq`, `description`
|
||||
$r = q("SELECT `resource_id`, `id`, `filename`, type, min(`imgscale`) AS `hiq`,max(`imgscale`) AS `loq`, `description`
|
||||
FROM `photo` WHERE `uid` = %d $sql_extra
|
||||
GROUP BY `resource_id` $sql_extra2",
|
||||
intval(local_channel())
|
||||
|
||||
@@ -31,7 +31,7 @@ class Feed extends \Zotlabs\Web\Controller {
|
||||
|
||||
$channel = $r[0];
|
||||
|
||||
if((intval(get_config('system','block_public'))) && (! get_account_id()))
|
||||
if(observer_prohibited(true))
|
||||
killme();
|
||||
|
||||
logger('mod_feed: public feed request from ' . $_SERVER['REMOTE_ADDR'] . ' for ' . $channel['channel_address']);
|
||||
|
||||
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']);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,7 +39,7 @@ class Filer extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
else {
|
||||
$filetags = array();
|
||||
$r = q("select distinct(term) from term where uid = %d and type = %d order by term asc",
|
||||
$r = q("select distinct(term) from term where uid = %d and ttype = %d order by term asc",
|
||||
intval(local_channel()),
|
||||
intval(TERM_FILE)
|
||||
);
|
||||
|
||||
@@ -22,7 +22,7 @@ class Filerm extends \Zotlabs\Web\Controller {
|
||||
logger('filerm: tag ' . $term . ' item ' . $item_id);
|
||||
|
||||
if($item_id && strlen($term)) {
|
||||
$r = q("delete from term where uid = %d and type = %d and oid = %d and term = '%s'",
|
||||
$r = q("delete from term where uid = %d and ttype = %d and oid = %d and term = '%s'",
|
||||
intval(local_channel()),
|
||||
intval(($category) ? TERM_CATEGORY : TERM_FILE),
|
||||
intval($item_id),
|
||||
|
||||
@@ -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,24 +43,24 @@ 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'))
|
||||
proc_run('php','include/onepoll.php',$result['abook']['abook_id']);
|
||||
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');
|
||||
|
||||
}
|
||||
|
||||
function get() {
|
||||
|
||||
function get() {
|
||||
if(! local_channel()) {
|
||||
return login();
|
||||
}
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
|
||||
|
||||
class Fsuggest extends \Zotlabs\Web\Controller {
|
||||
|
||||
function post() {
|
||||
|
||||
if(! local_channel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(\App::$argc != 2)
|
||||
return;
|
||||
|
||||
$contact_id = intval(\App::$argv[1]);
|
||||
|
||||
$r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval($contact_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
if(! count($r)) {
|
||||
notice( t('Contact not found.') . EOL);
|
||||
return;
|
||||
}
|
||||
$contact = $r[0];
|
||||
|
||||
$new_contact = intval($_POST['suggest']);
|
||||
|
||||
$hash = random_string();
|
||||
|
||||
$note = escape_tags(trim($_POST['note']));
|
||||
|
||||
if($new_contact) {
|
||||
$r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval($new_contact),
|
||||
intval(local_channel())
|
||||
);
|
||||
if(count($r)) {
|
||||
|
||||
$x = q("INSERT INTO `fsuggest` ( `uid`,`cid`,`name`,`url`,`request`,`photo`,`note`,`created`)
|
||||
VALUES ( %d, %d, '%s','%s','%s','%s','%s','%s')",
|
||||
intval(local_channel()),
|
||||
intval($contact_id),
|
||||
dbesc($r[0]['name']),
|
||||
dbesc($r[0]['url']),
|
||||
dbesc($r[0]['request']),
|
||||
dbesc($r[0]['photo']),
|
||||
dbesc($hash),
|
||||
dbesc(datetime_convert())
|
||||
);
|
||||
$r = q("SELECT `id` FROM `fsuggest` WHERE `note` = '%s' AND `uid` = %d LIMIT 1",
|
||||
dbesc($hash),
|
||||
intval(local_channel())
|
||||
);
|
||||
if(count($r)) {
|
||||
$fsuggest_id = $r[0]['id'];
|
||||
q("UPDATE `fsuggest` SET `note` = '%s' WHERE `id` = %d AND `uid` = %d",
|
||||
dbesc($note),
|
||||
intval($fsuggest_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
proc_run('php', 'include/notifier.php', 'suggest' , $fsuggest_id);
|
||||
}
|
||||
|
||||
info( t('Friend suggestion sent.') . EOL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
require_once('include/acl_selectors.php');
|
||||
|
||||
if(! local_channel()) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if(\App::$argc != 2)
|
||||
return;
|
||||
|
||||
$contact_id = intval(\App::$argv[1]);
|
||||
|
||||
$r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval($contact_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
if(! count($r)) {
|
||||
notice( t('Contact not found.') . EOL);
|
||||
return;
|
||||
}
|
||||
$contact = $r[0];
|
||||
|
||||
$o = '<h3>' . t('Suggest Friends') . '</h3>';
|
||||
|
||||
$o .= '<div id="fsuggest-desc" >' . sprintf( t('Suggest a friend for %s'), $contact['name']) . '</div>';
|
||||
|
||||
$o .= '<form id="fsuggest-form" action="fsuggest/' . $contact_id . '" method="post" >';
|
||||
|
||||
// FIXME contact_selector deprecated, removed
|
||||
// $o .= contact_selector('suggest','suggest-select', false,
|
||||
// array('size' => 4, 'exclude' => $contact_id, 'networks' => 'DFRN_ONLY', 'single' => true));
|
||||
|
||||
|
||||
$o .= '<div id="fsuggest-submit-wrapper"><input id="fsuggest-submit" type="submit" name="submit" value="' . t('Submit') . '" /></div>';
|
||||
$o .= '</form>';
|
||||
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,6 @@ namespace Zotlabs\Module;
|
||||
|
||||
|
||||
|
||||
require_once('include/Contact.php');
|
||||
require_once('include/attach.php');
|
||||
|
||||
|
||||
|
||||
@@ -47,8 +47,8 @@ class Group extends \Zotlabs\Web\Controller {
|
||||
$groupname = notags(trim($_POST['groupname']));
|
||||
$public = intval($_POST['public']);
|
||||
|
||||
if((strlen($groupname)) && (($groupname != $group['name']) || ($public != $group['visible']))) {
|
||||
$r = q("UPDATE `groups` SET `name` = '%s', visible = %d WHERE `uid` = %d AND `id` = %d",
|
||||
if((strlen($groupname)) && (($groupname != $group['gname']) || ($public != $group['visible']))) {
|
||||
$r = q("UPDATE `groups` SET `gname` = '%s', visible = %d WHERE `uid` = %d AND `id` = %d",
|
||||
dbesc($groupname),
|
||||
intval($public),
|
||||
intval(local_channel()),
|
||||
@@ -101,12 +101,12 @@ 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())
|
||||
);
|
||||
if($r)
|
||||
$result = group_rmv(local_channel(),$r[0]['name']);
|
||||
$result = group_rmv(local_channel(),$r[0]['gname']);
|
||||
if($result)
|
||||
info( t('Privacy group removed.') . EOL);
|
||||
else
|
||||
@@ -156,10 +156,10 @@ class Group extends \Zotlabs\Web\Controller {
|
||||
if($change) {
|
||||
|
||||
if(in_array($change,$preselected)) {
|
||||
group_rmv_member(local_channel(),$group['name'],$change);
|
||||
group_rmv_member(local_channel(),$group['gname'],$change);
|
||||
}
|
||||
else {
|
||||
group_add_member(local_channel(),$group['name'],$change);
|
||||
group_add_member(local_channel(),$group['gname'],$change);
|
||||
}
|
||||
|
||||
$members = group_get_members($group['id']);
|
||||
@@ -181,7 +181,7 @@ class Group extends \Zotlabs\Web\Controller {
|
||||
|
||||
$context = $context + array(
|
||||
'$title' => t('Privacy group editor'),
|
||||
'$gname' => array('groupname',t('Privacy group name: '),$group['name'], ''),
|
||||
'$gname' => array('groupname',t('Privacy group name: '),$group['gname'], ''),
|
||||
'$gid' => $group['id'],
|
||||
'$drop' => $drop_txt,
|
||||
'$public' => array('public',t('Members are visible to other channels'), $group['visible'], ''),
|
||||
@@ -209,7 +209,7 @@ class Group extends \Zotlabs\Web\Controller {
|
||||
$groupeditor['members'][] = micropro($member,true,'mpgroup', $textmode);
|
||||
}
|
||||
else
|
||||
group_rmv_member(local_channel(),$group['name'],$member['xchan_hash']);
|
||||
group_rmv_member(local_channel(),$group['gname'],$member['xchan_hash']);
|
||||
}
|
||||
|
||||
$r = q("SELECT abook.*, xchan.* FROM `abook` left join xchan on abook_xchan = xchan_hash WHERE `abook_channel` = %d AND abook_self = 0 and abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 order by xchan_name asc",
|
||||
|
||||
@@ -40,7 +40,7 @@ class Hcard extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
profile_load($a,$which,$profile);
|
||||
profile_load($which,$profile);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class Help extends \Zotlabs\Web\Controller {
|
||||
$path = trim(substr($dirname,4),'/');
|
||||
|
||||
$o .= '<li><a href="help/' . (($path) ? $path . '/' : '') . $fname . '" >' . ucwords(str_replace('_',' ',notags($fname))) . '</a><br />' .
|
||||
str_replace('$Projectname',\Zotlabs\Project\System::get_platform_name(),substr($rr['text'],0,200)) . '...<br /><br /></li>';
|
||||
str_replace('$Projectname',\Zotlabs\Lib\System::get_platform_name(),substr($rr['text'],0,200)) . '...<br /><br /></li>';
|
||||
|
||||
}
|
||||
$o .= '</ul>';
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -4,10 +4,11 @@ namespace Zotlabs\Module;
|
||||
// Import a channel, either by direct file upload or via
|
||||
// connection to original server.
|
||||
|
||||
require_once('include/Contact.php');
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/identity.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']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -408,8 +418,12 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
$saved = array();
|
||||
foreach($groups as $group) {
|
||||
$saved[$group['hash']] = array('old' => $group['id']);
|
||||
if(array_key_exists('name',$group)) {
|
||||
$group['gname'] = $group['name'];
|
||||
unset($group['name']);
|
||||
}
|
||||
unset($group['id']);
|
||||
$group['uid'] = $channel['channel_id'];
|
||||
$group['uid'] = $channel['channel_id'];
|
||||
dbesc_array($group);
|
||||
$r = dbq("INSERT INTO groups (`"
|
||||
. implode("`, `", array_keys($group))
|
||||
@@ -471,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']);
|
||||
@@ -482,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);
|
||||
|
||||
@@ -496,11 +510,11 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
// send out refresh requests
|
||||
// notify old server that it may no longer be primary.
|
||||
|
||||
proc_run('php','include/notifier.php','location',$channel['channel_id']);
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier','location',$channel['channel_id']));
|
||||
|
||||
// This will indirectly perform a refresh_all *and* update the directory
|
||||
|
||||
proc_run('php', 'include/directory.php', $channel['channel_id']);
|
||||
\Zotlabs\Daemon\Master::Summon(array('Directory', $channel['channel_id']));
|
||||
|
||||
|
||||
notice( t('Import completed.') . EOL);
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
@@ -17,10 +18,10 @@ namespace Zotlabs\Module;
|
||||
*/
|
||||
|
||||
require_once('include/crypto.php');
|
||||
require_once('include/enotify.php');
|
||||
require_once('include/items.php');
|
||||
require_once('include/attach.php');
|
||||
|
||||
use \Zotlabs\Lib as Zlib;
|
||||
|
||||
class Item extends \Zotlabs\Web\Controller {
|
||||
|
||||
@@ -56,7 +57,7 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
$remote_xchan = $remote_observer = false;
|
||||
|
||||
$profile_uid = ((x($_REQUEST,'profile_uid')) ? intval($_REQUEST['profile_uid']) : 0);
|
||||
require_once('include/identity.php');
|
||||
require_once('include/channel.php');
|
||||
$sys = get_sys_channel();
|
||||
if($sys && $profile_uid && ($sys['channel_id'] == $profile_uid) && is_site_admin()) {
|
||||
$uid = intval($sys['channel_id']);
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -581,7 +586,7 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
if($success['replaced']) {
|
||||
$post_tags[] = array(
|
||||
'uid' => $profile_uid,
|
||||
'type' => $success['termtype'],
|
||||
'ttype' => $success['termtype'],
|
||||
'otype' => TERM_OBJ_POST,
|
||||
'term' => $success['term'],
|
||||
'url' => $success['url']
|
||||
@@ -666,7 +671,7 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
foreach($cats as $cat) {
|
||||
$post_tags[] = array(
|
||||
'uid' => $profile_uid,
|
||||
'type' => TERM_CATEGORY,
|
||||
'ttype' => TERM_CATEGORY,
|
||||
'otype' => TERM_OBJ_POST,
|
||||
'term' => trim($cat),
|
||||
'url' => $owner_xchan['xchan_url'] . '?f=&cat=' . urlencode(trim($cat))
|
||||
@@ -676,7 +681,7 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
|
||||
if($orig_post) {
|
||||
// preserve original tags
|
||||
$t = q("select * from term where oid = %d and otype = %d and uid = %d and type in ( %d, %d, %d )",
|
||||
$t = q("select * from term where oid = %d and otype = %d and uid = %d and ttype in ( %d, %d, %d )",
|
||||
intval($orig_post['id']),
|
||||
intval(TERM_OBJ_POST),
|
||||
intval($profile_uid),
|
||||
@@ -688,7 +693,7 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
foreach($t as $t1) {
|
||||
$post_tags[] = array(
|
||||
'uid' => $profile_uid,
|
||||
'type' => $t1['type'],
|
||||
'ttype' => $t1['type'],
|
||||
'otype' => TERM_OBJ_POST,
|
||||
'term' => $t1['term'],
|
||||
'url' => $t1['url'],
|
||||
@@ -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,14 +909,11 @@ 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)
|
||||
proc_run('php', "include/notifier.php", 'edit_post', $post_id);
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier', 'edit_post', $post_id));
|
||||
|
||||
if((x($_REQUEST,'return')) && strlen($return_path)) {
|
||||
logger('return: ' . $return_path);
|
||||
@@ -925,7 +937,7 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
// otherwise it will happen during delivery
|
||||
|
||||
if(($datarray['owner_xchan'] != $datarray['author_xchan']) && (intval($parent_item['item_wall']))) {
|
||||
notification(array(
|
||||
Zlib\Enotify::submit(array(
|
||||
'type' => NOTIFY_COMMENT,
|
||||
'from_xchan' => $datarray['author_xchan'],
|
||||
'to_xchan' => $datarray['owner_xchan'],
|
||||
@@ -943,7 +955,7 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
$parent = $post_id;
|
||||
|
||||
if(($datarray['owner_xchan'] != $datarray['author_xchan']) && ($datarray['item_type'] == ITEM_TYPE_POST)) {
|
||||
notification(array(
|
||||
Zlib\Enotify::submit(array(
|
||||
'type' => NOTIFY_WALL,
|
||||
'from_xchan' => $datarray['author_xchan'],
|
||||
'to_xchan' => $datarray['owner_xchan'],
|
||||
@@ -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))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1008,15 +1014,10 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
call_hooks('post_local_end', $datarray);
|
||||
|
||||
if(! $nopush)
|
||||
proc_run('php', 'include/notifier.php', $notify_type, $post_id);
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier', $notify_type, $post_id));
|
||||
|
||||
logger('post_complete');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// figure out how to return, depending on from whence we came
|
||||
|
||||
if($api_source)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/identity.php');
|
||||
require_once('include/channel.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -346,7 +345,7 @@ class Like extends \Zotlabs\Web\Controller {
|
||||
// drop_item was not done interactively, so we need to invoke the notifier
|
||||
// in order to push the changes to connections
|
||||
|
||||
proc_run('php','include/notifier.php','drop',$rr['id']);
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier','drop',$rr['id']));
|
||||
|
||||
}
|
||||
|
||||
@@ -483,7 +482,7 @@ class Like extends \Zotlabs\Web\Controller {
|
||||
|
||||
$arr['verb'] = $activity;
|
||||
$arr['obj_type'] = $objtype;
|
||||
$arr['object'] = $object;
|
||||
$arr['obj'] = $object;
|
||||
|
||||
if($target) {
|
||||
$arr['tgt_type'] = $tgttype;
|
||||
@@ -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'];
|
||||
@@ -531,7 +532,7 @@ class Like extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
|
||||
proc_run('php',"include/notifier.php","like","$post_id");
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier','like',$post_id));
|
||||
|
||||
if($interactive) {
|
||||
notice( t('Action completed.') . EOL);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user