mirror of
https://framagit.org/hubzilla/core.git
synced 2026-06-22 01:17:41 -04:00
Compare commits
1200 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
249bdeb642 | ||
|
|
b4ee80d1ea | ||
|
|
96bf9d0769 | ||
|
|
7fc9c83986 | ||
|
|
5502f1cc63 | ||
|
|
b55801323c | ||
|
|
818374c8cc | ||
|
|
e80191d4cd | ||
|
|
c2a796b6ea | ||
|
|
00694f0dfd | ||
|
|
134f4c5b52 | ||
|
|
0840fc42f9 | ||
|
|
2650a647e9 | ||
|
|
3311269162 | ||
|
|
b2172d39f6 | ||
|
|
f4d39bd3c8 | ||
|
|
1cf659033b | ||
|
|
3dc5527690 | ||
|
|
81b02d04b5 | ||
|
|
95f6f9e10a | ||
|
|
9554f53519 | ||
|
|
5d7081a224 | ||
|
|
9cbdf3f31f | ||
|
|
c8bc1b560b | ||
|
|
40ae6b396f | ||
|
|
9c117ffa05 | ||
|
|
9e95f189ed | ||
|
|
221b31bcc6 | ||
|
|
8879776d64 | ||
|
|
5edd13c6bb | ||
|
|
7ca289edd0 | ||
|
|
bf434818d7 | ||
|
|
03aeb88832 | ||
|
|
bb5b33a0d3 | ||
|
|
53931017b9 | ||
|
|
e9ca17cec1 | ||
|
|
f70956964b | ||
|
|
4547a9d9d3 | ||
|
|
71accb6b0a | ||
|
|
2a95500b65 | ||
|
|
2ddad66ce7 | ||
|
|
108be24aed | ||
|
|
71efb05658 | ||
|
|
a9a36894cb | ||
|
|
bc9778e02f | ||
|
|
a83d2efe84 | ||
|
|
d3856caf81 | ||
|
|
e1f9b1c47d | ||
|
|
497c953d0e | ||
|
|
bec76bd057 | ||
|
|
54f4762e1a | ||
|
|
8bf5c18425 | ||
|
|
c36bb17475 | ||
|
|
2291fcdf11 | ||
|
|
4070c46d15 | ||
|
|
a749db8d0f | ||
|
|
10ba98c4f5 | ||
|
|
108a3efe0b | ||
|
|
ccd826f63a | ||
|
|
5e5f0aa955 | ||
|
|
f9a4c53e3f | ||
|
|
60b576568e | ||
|
|
d0e1b73205 | ||
|
|
ef2448e17e | ||
|
|
99a5cf1ad4 | ||
|
|
bc3113ae16 | ||
|
|
fb475da008 | ||
|
|
d5fc3ad646 | ||
|
|
8b7da6e318 | ||
|
|
ed208c4bcc | ||
|
|
6ab65519a0 | ||
|
|
4549bc89ec | ||
|
|
a0430f91bd | ||
|
|
624bb1db8d | ||
|
|
9f522bbe6c | ||
|
|
931da3b4f7 | ||
|
|
5a25fd54a4 | ||
|
|
9f0f4c50a4 | ||
|
|
0bf3d31578 | ||
|
|
8ca293c3e4 | ||
|
|
ba0c877ffc | ||
|
|
b8e00c2dc9 | ||
|
|
2dd48898a8 | ||
|
|
66fc807655 | ||
|
|
653eb2909b | ||
|
|
72520a2dd9 | ||
|
|
a7d4666a70 | ||
|
|
13476d5003 | ||
|
|
879cdedec3 | ||
|
|
05bd2a1f9e | ||
|
|
c49d1547c4 | ||
|
|
ad35363c2e | ||
|
|
b3f70140e5 | ||
|
|
2f21dc50b4 | ||
|
|
cbd8c2483b | ||
|
|
03475bfb15 | ||
|
|
bb9411e7dc | ||
|
|
bce4e2d022 | ||
|
|
7cfc14fef7 | ||
|
|
f220cf3173 | ||
|
|
725359b1aa | ||
|
|
937d6cb1ef | ||
|
|
118a5edebc | ||
|
|
1b4333e8d9 | ||
|
|
d66a0b50e9 | ||
|
|
1d56b9a1bb | ||
|
|
96535ee4df | ||
|
|
b55f314d7e | ||
|
|
480862d714 | ||
|
|
990a3af2a7 | ||
|
|
1f5a23143a | ||
|
|
fcfb9e9758 | ||
|
|
9beee689ce | ||
|
|
2c388c3833 | ||
|
|
1a75066616 | ||
|
|
3dfb0bcae9 | ||
|
|
9ac0b77e92 | ||
|
|
6421a32520 | ||
|
|
fdcae52740 | ||
|
|
a8752844ef | ||
|
|
e04ce5028e | ||
|
|
f2c4d80ac0 | ||
|
|
d8a6226805 | ||
|
|
fedf60a32c | ||
|
|
b3548fefc1 | ||
|
|
febd64c527 | ||
|
|
d67a5c5070 | ||
|
|
aefe7ddd8f | ||
|
|
254dea7558 | ||
|
|
b1550f7922 | ||
|
|
2d07c3e45d | ||
|
|
e5f3406cb5 | ||
|
|
185ddf1eaf | ||
|
|
2734335869 | ||
|
|
0132c4e36e | ||
|
|
7dee47183d | ||
|
|
9c4988c297 | ||
|
|
3bfbc70587 | ||
|
|
34858fce1c | ||
|
|
b47dab0ee9 | ||
|
|
6eeb033b96 | ||
|
|
0679cb8e00 | ||
|
|
3abc9ee387 | ||
|
|
2e9211cf41 | ||
|
|
40377796ed | ||
|
|
fedad7f31a | ||
|
|
d2a34e0107 | ||
|
|
769c822568 | ||
|
|
c452a621fe | ||
|
|
231ab95ef6 | ||
|
|
7c01b59ffb | ||
|
|
e79668ddf4 | ||
|
|
dc6b6fc353 | ||
|
|
34ea58cf38 | ||
|
|
199168c318 | ||
|
|
063d4bbd7d | ||
|
|
29fd9b9d64 | ||
|
|
c301baafb5 | ||
|
|
4282672201 | ||
|
|
ae705dd865 | ||
|
|
f0fa2ce171 | ||
|
|
d6a9a9927c | ||
|
|
40b4636858 | ||
|
|
97fe499b63 | ||
|
|
e0915cffda | ||
|
|
7602de85c3 | ||
|
|
0787817eb8 | ||
|
|
e030648957 | ||
|
|
b815935fd7 | ||
|
|
a5000ba311 | ||
|
|
5e2bb874c8 | ||
|
|
fcb5a7f645 | ||
|
|
b8c6520abb | ||
|
|
1d99c3d3f7 | ||
|
|
5e112b395d | ||
|
|
d1a8e7813a | ||
|
|
a0582fec12 | ||
|
|
2cd3a7b3f0 | ||
|
|
47448b11cd | ||
|
|
e63f043841 | ||
|
|
33dd0c83e3 | ||
|
|
32dad136f8 | ||
|
|
073ed52538 | ||
|
|
eef828cf3e | ||
|
|
d0b5930a3a | ||
|
|
c66ad9ccc8 | ||
|
|
9959a15c8e | ||
|
|
f0e4b4dc84 | ||
|
|
f62f808368 | ||
|
|
530a521679 | ||
|
|
50782dfb83 | ||
|
|
27a142d5c5 | ||
|
|
6d00b2e63d | ||
|
|
7be1415a3a | ||
|
|
0a30b12f7d | ||
|
|
3058cbfbb2 | ||
|
|
ae780c977b | ||
|
|
e146a67f4b | ||
|
|
162d86983a | ||
|
|
8534366a31 | ||
|
|
d1c6617dc9 | ||
|
|
6f994709b9 | ||
|
|
55d833a9c8 | ||
|
|
8ba4745097 | ||
|
|
940a0c8b10 | ||
|
|
8928b24e23 | ||
|
|
ae9a9191f3 | ||
|
|
cb553bd016 | ||
|
|
a75c61d71e | ||
|
|
c1dc16a89d | ||
|
|
66436ce4a2 | ||
|
|
62b1ff4ba1 | ||
|
|
304d136437 | ||
|
|
1b4268b9b0 | ||
|
|
a7968e6525 | ||
|
|
e59cc3d404 | ||
|
|
3a2d126877 | ||
|
|
ee3d6fcfee | ||
|
|
09d929bd56 | ||
|
|
bd55ae15f2 | ||
|
|
2ca80118bf | ||
|
|
04eb20ac35 | ||
|
|
f299391aa1 | ||
|
|
c334fc9d22 | ||
|
|
8520088376 | ||
|
|
9ada8518dc | ||
|
|
f0c09b374c | ||
|
|
c5f33baf27 | ||
|
|
2efcdd92e0 | ||
|
|
38fda98b6d | ||
|
|
f9fd195c24 | ||
|
|
01e82090b2 | ||
|
|
39602ede37 | ||
|
|
98a311ae40 | ||
|
|
5c398b3e8f | ||
|
|
83e585ee9b | ||
|
|
e386499bfa | ||
|
|
4552630bf8 | ||
|
|
2d8065a780 | ||
|
|
b94da93c74 | ||
|
|
695045f197 | ||
|
|
376733bd08 | ||
|
|
4c7c5137c5 | ||
|
|
930b9820f2 | ||
|
|
b2fa63f2c8 | ||
|
|
1390e1db39 | ||
|
|
e7768ae954 | ||
|
|
38d977e546 | ||
|
|
3e38a24f0a | ||
|
|
0784cd593a | ||
|
|
9c5d2ee563 | ||
|
|
be5f7c2e67 | ||
|
|
0d0f73fb67 | ||
|
|
680be6cfec | ||
|
|
2ab3d072b0 | ||
|
|
943ecff623 | ||
|
|
03973f5d1d | ||
|
|
c42a0fa9b6 | ||
|
|
61522ed31d | ||
|
|
29a527426a | ||
|
|
62ac0ff21e | ||
|
|
a41c7caa18 | ||
|
|
b3ca31bce7 | ||
|
|
b02f6a1dae | ||
|
|
d35609f33a | ||
|
|
8c19ab8f9f | ||
|
|
30ae198b89 | ||
|
|
bddeab3ac1 | ||
|
|
591349ee74 | ||
|
|
9081a25e64 | ||
|
|
1beadfc6e7 | ||
|
|
f4af532c5a | ||
|
|
76eb1a9d78 | ||
|
|
14a2790dcb | ||
|
|
46f54db197 | ||
|
|
4ffd7587a9 | ||
|
|
c48c62c7a8 | ||
|
|
9e7fd20ade | ||
|
|
efa1d381ba | ||
|
|
740fa058aa | ||
|
|
37f56e1efd | ||
|
|
6294be371a | ||
|
|
bee7549a1e | ||
|
|
db14dbacc9 | ||
|
|
27058e6297 | ||
|
|
b41175e0e2 | ||
|
|
eeea3251ad | ||
|
|
34ffff3947 | ||
|
|
65ed3818ec | ||
|
|
c8417df6f1 | ||
|
|
dc3be7ecf7 | ||
|
|
cf3c0b593b | ||
|
|
34f64148e8 | ||
|
|
fc5dad1983 | ||
|
|
c3c40548b9 | ||
|
|
0e2e932102 | ||
|
|
6930c4e23b | ||
|
|
01b9f2dfcf | ||
|
|
0cc6f66a26 | ||
|
|
d384f55dd1 | ||
|
|
1893368aa5 | ||
|
|
a520063265 | ||
|
|
1e171a72a0 | ||
|
|
5b1a0d93b9 | ||
|
|
7e04662a9c | ||
|
|
a804549781 | ||
|
|
2a60f1cc6e | ||
|
|
2ddff785e5 | ||
|
|
38882efb5c | ||
|
|
6f7786b068 | ||
|
|
0819141f03 | ||
|
|
329ef5049f | ||
|
|
34bb8c65d6 | ||
|
|
575ccae6f9 | ||
|
|
486be87e33 | ||
|
|
c0350861ef | ||
|
|
a7ec1805e3 | ||
|
|
4b06bc552f | ||
|
|
76ee7b7eea | ||
|
|
04b1e7e34f | ||
|
|
17dbb156e1 | ||
|
|
135117c637 | ||
|
|
d3348f7855 | ||
|
|
39bbcb66c8 | ||
|
|
d45e8e4d20 | ||
|
|
d65052c1ac | ||
|
|
2fbc42753f | ||
|
|
4195865965 | ||
|
|
de3f6fbeba | ||
|
|
6a377120bd | ||
|
|
502226b0a6 | ||
|
|
78206b48f4 | ||
|
|
dc3cec06ca | ||
|
|
5a7688e099 | ||
|
|
c721f01c76 | ||
|
|
463806822c | ||
|
|
b74c2f001d | ||
|
|
9fc7a8b626 | ||
|
|
3ffd92a6c3 | ||
|
|
29b02e5329 | ||
|
|
97584e046f | ||
|
|
09d2fce85d | ||
|
|
fc3060cb29 | ||
|
|
9804a67165 | ||
|
|
21eddefa41 | ||
|
|
9b62e7eedb | ||
|
|
bf30cfd8a4 | ||
|
|
139ffae367 | ||
|
|
51a48cc264 | ||
|
|
abbca12565 | ||
|
|
9e9d96a2ec | ||
|
|
615c9f1cbe | ||
|
|
7d75d0cfbd | ||
|
|
5468de2c6a | ||
|
|
6d8aabab23 | ||
|
|
e74359fcfe | ||
|
|
53c842c614 | ||
|
|
23ececeb34 | ||
|
|
521c9eb566 | ||
|
|
35877b1382 | ||
|
|
c531287170 | ||
|
|
8e79a81b88 | ||
|
|
b95ceb301f | ||
|
|
76a94495c4 | ||
|
|
b6b2299b4e | ||
|
|
34ddea87d3 | ||
|
|
3d318542cb | ||
|
|
4a8c3cdc61 | ||
|
|
c0b6f2d95f | ||
|
|
9ca7fccab8 | ||
|
|
d91fcfc866 | ||
|
|
29b53f3b9d | ||
|
|
30987095c7 | ||
|
|
43b93de570 | ||
|
|
5b310cf315 | ||
|
|
a1c2a57ea6 | ||
|
|
34bf8f1133 | ||
|
|
c708ec577e | ||
|
|
c185685f2d | ||
|
|
daee5b3477 | ||
|
|
5d0346ee30 | ||
|
|
85ad5355cf | ||
|
|
4c8b84633a | ||
|
|
c0dd4d748d | ||
|
|
c94f25570b | ||
|
|
ffa5e08832 | ||
|
|
63243c8e04 | ||
|
|
21c4ec2de0 | ||
|
|
a8d87af418 | ||
|
|
7b084a065e | ||
|
|
47f6b202e5 | ||
|
|
f588d8379b | ||
|
|
58827e130b | ||
|
|
d702334604 | ||
|
|
b04aa799e3 | ||
|
|
e113f6cb9d | ||
|
|
bc13b7eb72 | ||
|
|
f50b395da6 | ||
|
|
a0e8e40f1c | ||
|
|
cb6055c1b8 | ||
|
|
25424c16e4 | ||
|
|
99dcdee67a | ||
|
|
99928f1aea | ||
|
|
1740ae2104 | ||
|
|
d8372f8433 | ||
|
|
2a15d2c421 | ||
|
|
bacf19688f | ||
|
|
31fbdcf6c5 | ||
|
|
c8818cb7b3 | ||
|
|
eb20789821 | ||
|
|
c90862217e | ||
|
|
df87d6feeb | ||
|
|
6c808abcfc | ||
|
|
f1822bdfab | ||
|
|
c3428acd80 | ||
|
|
d619192b22 | ||
|
|
5bdc713afe | ||
|
|
46eff1c937 | ||
|
|
76e1ea1c02 | ||
|
|
755076a8e5 | ||
|
|
b49f7b8b34 | ||
|
|
c4dd8885e4 | ||
|
|
4c82952b58 | ||
|
|
0da69cb9c7 | ||
|
|
36e244060c | ||
|
|
b13a9f57af | ||
|
|
0aa67ad7f9 | ||
|
|
195a3a6827 | ||
|
|
38ecff1220 | ||
|
|
67e64287af | ||
|
|
b022703b0b | ||
|
|
e8069c0d93 | ||
|
|
7a1c6b64c2 | ||
|
|
8250cb1e8d | ||
|
|
ffe2c4d42b | ||
|
|
f06c970628 | ||
|
|
99bce46b32 | ||
|
|
f711913778 | ||
|
|
a8ac231667 | ||
|
|
f7c8791a6d | ||
|
|
7acc775c91 | ||
|
|
c2e21e837f | ||
|
|
755d0f54f7 | ||
|
|
f62d66ff25 | ||
|
|
406d19f930 | ||
|
|
42b13614eb | ||
|
|
c942bd67fe | ||
|
|
b8dc3d74b6 | ||
|
|
38fb263737 | ||
|
|
b55beed2f9 | ||
|
|
e9278c03c1 | ||
|
|
ae1fe83784 | ||
|
|
717a547c40 | ||
|
|
ec491e87ab | ||
|
|
42e30d0835 | ||
|
|
5b19418e48 | ||
|
|
1bc9a7373f | ||
|
|
23e59b5dcc | ||
|
|
c6b459cf96 | ||
|
|
33254b4cac | ||
|
|
44da40d18d | ||
|
|
c742f25801 | ||
|
|
b153687bf1 | ||
|
|
3318f093da | ||
|
|
d98d56c3b5 | ||
|
|
c3f5f6c7ad | ||
|
|
5f21edcc53 | ||
|
|
cd0731cbb0 | ||
|
|
f392ddec2f | ||
|
|
df71168ab7 | ||
|
|
e93b26bf54 | ||
|
|
a73d4a8cbd | ||
|
|
20ee57801c | ||
|
|
6a270d7f02 | ||
|
|
68639637c9 | ||
|
|
0d1eabbc33 | ||
|
|
dce249f7a9 | ||
|
|
1723d4fbd8 | ||
|
|
c4b09f1a4f | ||
|
|
788c973c13 | ||
|
|
465c5c8cfb | ||
|
|
ee28ba5be1 | ||
|
|
9a22e9cf39 | ||
|
|
2513f605b6 | ||
|
|
3b1ffb2028 | ||
|
|
47c6624e12 | ||
|
|
b6f1b064d3 | ||
|
|
17d89467df | ||
|
|
1282214d48 | ||
|
|
f4bc6ee615 | ||
|
|
f8b8d8c540 | ||
|
|
57ff667438 | ||
|
|
abe3039926 | ||
|
|
82a1117e91 | ||
|
|
b6ff3a4d99 | ||
|
|
f4046efcb2 | ||
|
|
fc1d3831cf | ||
|
|
867deda247 | ||
|
|
f8149face5 | ||
|
|
7e2aecd8bb | ||
|
|
105d121199 | ||
|
|
37d662f2f5 | ||
|
|
5b50454b4d | ||
|
|
b5e4c08fc5 | ||
|
|
db39cd8b7c | ||
|
|
a35f741a35 | ||
|
|
fc02e018cb | ||
|
|
b14a530efb | ||
|
|
f70bc571bd | ||
|
|
8cc64176b4 | ||
|
|
7450ac1a31 | ||
|
|
c72e5e3b66 | ||
|
|
5e811819e2 | ||
|
|
f1c0034a18 | ||
|
|
7342cb81a3 | ||
|
|
b40e858556 | ||
|
|
95a4ed7d6a | ||
|
|
2c2d4b6b95 | ||
|
|
4490eae4fe | ||
|
|
9d59cb0135 | ||
|
|
7d348fe69f | ||
|
|
fa8fb9e73f | ||
|
|
f6093872ec | ||
|
|
e8030e29d9 | ||
|
|
df8bb0596a | ||
|
|
0003e0b8a5 | ||
|
|
e42703d557 | ||
|
|
4636e56395 | ||
|
|
27ebeffad4 | ||
|
|
07110cee17 | ||
|
|
afa1f1416b | ||
|
|
f8dfcab0ca | ||
|
|
e14fd920d6 | ||
|
|
8c10fdae5b | ||
|
|
eee027d9ff | ||
|
|
1b1fb5d26a | ||
|
|
c36e0805d8 | ||
|
|
5c56041185 | ||
|
|
5aefe0b74f | ||
|
|
20e0359efd | ||
|
|
9c790e5a90 | ||
|
|
9c79b5be77 | ||
|
|
2d9a4f4e42 | ||
|
|
565602538c | ||
|
|
78972725ae | ||
|
|
5ab90f7791 | ||
|
|
b90d98fc2b | ||
|
|
eca3ae393b | ||
|
|
2bd69495d2 | ||
|
|
bfd3da43ac | ||
|
|
32a9eaf3b6 | ||
|
|
91cea1f28a | ||
|
|
220ed35f58 | ||
|
|
b1cf5d4e44 | ||
|
|
fe330ec1bb | ||
|
|
2968bf8241 | ||
|
|
a40babbf0d | ||
|
|
7822257e1c | ||
|
|
b37165c62b | ||
|
|
5e9d267959 | ||
|
|
1a1e6b6810 | ||
|
|
88140002e7 | ||
|
|
efc203d958 | ||
|
|
42d4cdcc39 | ||
|
|
fd433b3eb6 | ||
|
|
7483adb8ad | ||
|
|
45fd462f80 | ||
|
|
807003adf7 | ||
|
|
1b0a17c7db | ||
|
|
60b145833c | ||
|
|
39458b2ba8 | ||
|
|
5de38b3632 | ||
|
|
6ced3426cf | ||
|
|
43460c9d19 | ||
|
|
ca17fb01bc | ||
|
|
a6f65aa9c5 | ||
|
|
ae9a7727d6 | ||
|
|
3ac5d5257b | ||
|
|
668d7c73ed | ||
|
|
c95f708c91 | ||
|
|
06e214e567 | ||
|
|
18f8cafee0 | ||
|
|
6bd6afac05 | ||
|
|
fe7ecede70 | ||
|
|
089708ab9f | ||
|
|
daa844c038 | ||
|
|
4049992228 | ||
|
|
7c576c91b7 | ||
|
|
17bd364614 | ||
|
|
25ffd39519 | ||
|
|
acfa527e3e | ||
|
|
b512416cb3 | ||
|
|
bd116c53a1 | ||
|
|
1251fca256 | ||
|
|
b2fe21709c | ||
|
|
c082d12b59 | ||
|
|
9a4ca44255 | ||
|
|
6fce9a41b0 | ||
|
|
65acdd7b15 | ||
|
|
a209374cbd | ||
|
|
c1bb87db98 | ||
|
|
8bae40449f | ||
|
|
bc3bb4694a | ||
|
|
22588e58f3 | ||
|
|
69ba4eb055 | ||
|
|
687b9fb6a2 | ||
|
|
9b9ca9695c | ||
|
|
6357c69868 | ||
|
|
15cb7ab7a1 | ||
|
|
2c741bd24d | ||
|
|
3f72a3beb6 | ||
|
|
42de18d96d | ||
|
|
4bdbdab399 | ||
|
|
c7515b8687 | ||
|
|
c79e39a488 | ||
|
|
d639104b71 | ||
|
|
c66a5ba732 | ||
|
|
79f9b49dd7 | ||
|
|
8b542c250a | ||
|
|
55237683d2 | ||
|
|
27401794e1 | ||
|
|
862a7c2dba | ||
|
|
bb31a4620e | ||
|
|
7aaade8b23 | ||
|
|
a622f533ad | ||
|
|
0dd27dabd6 | ||
|
|
8ab464acf2 | ||
|
|
db18438db2 | ||
|
|
f885f98611 | ||
|
|
9b8b85545f | ||
|
|
532b479f96 | ||
|
|
422dfca6d7 | ||
|
|
c3d1474f59 | ||
|
|
99873504e4 | ||
|
|
138a67298d | ||
|
|
aca1551e86 | ||
|
|
ca32850a32 | ||
|
|
ba6f069997 | ||
|
|
c6c6b52ccd | ||
|
|
96c334e730 | ||
|
|
3e503ec3a3 | ||
|
|
e455fae334 | ||
|
|
29f3dc2fa3 | ||
|
|
aa41b16757 | ||
|
|
f4d59abe41 | ||
|
|
18de58fd8b | ||
|
|
4c2b188f8b | ||
|
|
08f65420f4 | ||
|
|
b90228b319 | ||
|
|
ad2c165f26 | ||
|
|
af5218593a | ||
|
|
f19acd9f50 | ||
|
|
59940e7f05 | ||
|
|
094536e633 | ||
|
|
4f2a439873 | ||
|
|
63bdab2b5f | ||
|
|
14733f8482 | ||
|
|
b830bbd084 | ||
|
|
c1894c5a39 | ||
|
|
e91e488e1f | ||
|
|
e6dac085cb | ||
|
|
5023a5b56b | ||
|
|
32d37d1178 | ||
|
|
848221649e | ||
|
|
f5f357060b | ||
|
|
98eea41865 | ||
|
|
8ac529f5ae | ||
|
|
b5fed08dd4 | ||
|
|
9bfcaf2669 | ||
|
|
af05ee7e1c | ||
|
|
3918439020 | ||
|
|
3b71e115a4 | ||
|
|
c33660a015 | ||
|
|
7963d4cb8f | ||
|
|
16281e0e7f | ||
|
|
72c58e60d7 | ||
|
|
4b48ff2868 | ||
|
|
8e212d30d0 | ||
|
|
b9ae396e74 | ||
|
|
3a38946f8a | ||
|
|
d0d3a5454e | ||
|
|
04c6d77d2c | ||
|
|
c2c5730d00 | ||
|
|
21a6dffd5f | ||
|
|
7430989212 | ||
|
|
2e26a13f81 | ||
|
|
404ebd4d5e | ||
|
|
11ea7bf0fc | ||
|
|
6da7fe7d27 | ||
|
|
538e540531 | ||
|
|
53138f4b09 | ||
|
|
3d71367f30 | ||
|
|
bb52ff9b4b | ||
|
|
ab5b82221c | ||
|
|
5c3b89a68b | ||
|
|
da923d7749 | ||
|
|
55d905fdd9 | ||
|
|
4ba70a3fae | ||
|
|
a5835b0e85 | ||
|
|
ed4e5c9bcf | ||
|
|
d8793de629 | ||
|
|
f45cb38cd3 | ||
|
|
0722188ea6 | ||
|
|
d6f81e139a | ||
|
|
58ee147653 | ||
|
|
28ad6a6883 | ||
|
|
9de8aefa98 | ||
|
|
66c273ae8d | ||
|
|
b27fbf209e | ||
|
|
4afd1ac705 | ||
|
|
d556ef59e6 | ||
|
|
81e972b85c | ||
|
|
3bb04cc323 | ||
|
|
9ff43f081f | ||
|
|
8c014e3b6b | ||
|
|
d8378a17c9 | ||
|
|
574a01727e | ||
|
|
b5cea3301d | ||
|
|
9346a06f35 | ||
|
|
250e917c6e | ||
|
|
7b1cd37cd6 | ||
|
|
47e83a15c1 | ||
|
|
597e847a3b | ||
|
|
47f3b41d5e | ||
|
|
e7f4c1ffd1 | ||
|
|
9a87b8bf1b | ||
|
|
dac27aab68 | ||
|
|
069a5429c9 | ||
|
|
b1eaa810ce | ||
|
|
e5e3c268a2 | ||
|
|
22dff49673 | ||
|
|
591905c282 | ||
|
|
6ed160e4fa | ||
|
|
d462230b82 | ||
|
|
e48ed9d06d | ||
|
|
6236869ebe | ||
|
|
2c7c9ae2d7 | ||
|
|
b9b4e71f7d | ||
|
|
b0bf646d71 | ||
|
|
5cb5ecdb54 | ||
|
|
44fa5ac9a1 | ||
|
|
9a19f7eac9 | ||
|
|
af0896bb8b | ||
|
|
817237ef77 | ||
|
|
fbefff6eed | ||
|
|
4ba47698d7 | ||
|
|
2688abf25a | ||
|
|
5eb79bd51e | ||
|
|
d3f5f778a4 | ||
|
|
3eeb2b0ee4 | ||
|
|
230a1919dd | ||
|
|
14004fbf7f | ||
|
|
73e8af98f2 | ||
|
|
0117a0019b | ||
|
|
35ff8781f0 | ||
|
|
2d17442f28 | ||
|
|
5c179522bb | ||
|
|
b35d95da52 | ||
|
|
feca5afaa5 | ||
|
|
9cb5274d30 | ||
|
|
2870fd46da | ||
|
|
dff8ef91a6 | ||
|
|
0588975e37 | ||
|
|
e0600b241a | ||
|
|
d19aa8fb3b | ||
|
|
989a4f3d49 | ||
|
|
2a2c4d3e9c | ||
|
|
a451449766 | ||
|
|
3347fab105 | ||
|
|
33a6c92629 | ||
|
|
0707d33493 | ||
|
|
89e4006b2d | ||
|
|
4eb8921635 | ||
|
|
26ac452c96 | ||
|
|
7122e1522a | ||
|
|
5497adfde6 | ||
|
|
d4c2e50285 | ||
|
|
7ba58208f2 | ||
|
|
cc83677711 | ||
|
|
c28cce1b54 | ||
|
|
9052695a13 | ||
|
|
46b8db53ab | ||
|
|
0b716b3cc7 | ||
|
|
d115e09abc | ||
|
|
0f803aa3ae | ||
|
|
e5dc3c05df | ||
|
|
1cfe5c3e16 | ||
|
|
e2d0269b5c | ||
|
|
b95c61d2c2 | ||
|
|
7b0f8f2896 | ||
|
|
25a81ea500 | ||
|
|
4c5f0a05c7 | ||
|
|
977a55eb84 | ||
|
|
8ec001c87b | ||
|
|
ddbc55d166 | ||
|
|
9a3a0d94ea | ||
|
|
1d3a59e0cd | ||
|
|
ad7c84eda7 | ||
|
|
fe62b245ca | ||
|
|
6084360588 | ||
|
|
52995bde12 | ||
|
|
0f54b26e9d | ||
|
|
2523ebc76a | ||
|
|
c1ce211b56 | ||
|
|
1aa7826331 | ||
|
|
29a1556541 | ||
|
|
93f48aa805 | ||
|
|
95367a8267 | ||
|
|
97ef781a0f | ||
|
|
81351d2952 | ||
|
|
8d28649e1b | ||
|
|
9495fef79b | ||
|
|
de02d4c04b | ||
|
|
18cd3926d7 | ||
|
|
0e1e1cda7a | ||
|
|
b3f2374b57 | ||
|
|
793881b9f9 | ||
|
|
529824d010 | ||
|
|
c47e21f3a7 | ||
|
|
d83c013bec | ||
|
|
17220b2465 | ||
|
|
5dcf053b4c | ||
|
|
a11fe8c6c6 | ||
|
|
70370407ad | ||
|
|
7973f11cd7 | ||
|
|
44371c9adf | ||
|
|
3d40ea7f44 | ||
|
|
8a3446c021 | ||
|
|
6a8cc313da | ||
|
|
7a1c72d5a4 | ||
|
|
4e7525c355 | ||
|
|
e20a2752d6 | ||
|
|
e25558e24d | ||
|
|
ada7d4eef5 | ||
|
|
3fb4077672 | ||
|
|
5b73cee0d8 | ||
|
|
8343f63964 | ||
|
|
5532560d07 | ||
|
|
ed277dbda9 | ||
|
|
2866c0b173 | ||
|
|
5eaabbdb18 | ||
|
|
d24fbb51fc | ||
|
|
6e4c9d684d | ||
|
|
3ff184f8bb | ||
|
|
a68b5f9de4 | ||
|
|
d5bf42faf0 | ||
|
|
88b13658a7 | ||
|
|
05152ac8c8 | ||
|
|
aa2106f949 | ||
|
|
6261d0826c | ||
|
|
2e7a915ee8 | ||
|
|
0081bafab2 | ||
|
|
64b59b4358 | ||
|
|
19f9bbcad4 | ||
|
|
f399528055 | ||
|
|
fea3980c01 | ||
|
|
8804499cb7 | ||
|
|
fa1878fda1 | ||
|
|
b129d74a38 | ||
|
|
189da4fdc1 | ||
|
|
824894baf0 | ||
|
|
2bd4f7384e | ||
|
|
1c44b37cb0 | ||
|
|
ab0da7db13 | ||
|
|
052633d570 | ||
|
|
3bb71a6ba8 | ||
|
|
7093b66b76 | ||
|
|
168010a32c | ||
|
|
6eb84a3d9a | ||
|
|
69d909596a | ||
|
|
dd296e1aaa | ||
|
|
c3bbc35e84 | ||
|
|
952407363e | ||
|
|
2deb75de8d | ||
|
|
a2403042c2 | ||
|
|
87cf2039ad | ||
|
|
db4109c2a0 | ||
|
|
36564b5aa7 | ||
|
|
101fc33c63 | ||
|
|
bd2270deb6 | ||
|
|
5b72f6f09d | ||
|
|
ee1cec8de2 | ||
|
|
b0a499d8b1 | ||
|
|
08f70c49f8 | ||
|
|
cddc021772 | ||
|
|
571bae9d1c | ||
|
|
e01666526e | ||
|
|
562a160a52 | ||
|
|
cb57c4ea18 | ||
|
|
b7ffec6fbe | ||
|
|
94be9f115b | ||
|
|
693736df7c | ||
|
|
943e7dd242 | ||
|
|
c1526b473b | ||
|
|
d459dfac74 | ||
|
|
cec2f0d894 | ||
|
|
9722d157bf | ||
|
|
6bcd24ab90 | ||
|
|
c6133d2558 | ||
|
|
ea8d38dec0 | ||
|
|
0fa41f082d | ||
|
|
83b1f62e13 | ||
|
|
b19213b60b | ||
|
|
3c5b18913f | ||
|
|
676a65cd61 | ||
|
|
95fb66b433 | ||
|
|
a57529bc54 | ||
|
|
4f15c08805 | ||
|
|
7b2f4b0814 | ||
|
|
3051e2c268 | ||
|
|
d7489e3913 | ||
|
|
62606bf006 | ||
|
|
c68f2bc2d1 | ||
|
|
f5669c9935 | ||
|
|
9e2bdb012e | ||
|
|
d8ac25c35a | ||
|
|
2dd47a9f59 | ||
|
|
a92ad512bb | ||
|
|
e39b29cc4b | ||
|
|
76ed9f3915 | ||
|
|
73b53675b1 | ||
|
|
fd6ec17d4b | ||
|
|
8de364c83e | ||
|
|
9b9ac5054f | ||
|
|
9efea4e188 | ||
|
|
d45df824ed | ||
|
|
50ead82bc4 | ||
|
|
c43f501716 | ||
|
|
86d471834e | ||
|
|
a1f7f7a966 | ||
|
|
081d82218b | ||
|
|
cca3eb8c56 | ||
|
|
933c097a52 | ||
|
|
f5912e05ef | ||
|
|
e94eb1af0c | ||
|
|
0ab7996a2a | ||
|
|
faeec0b77b | ||
|
|
ebc84eab3f | ||
|
|
b560b6fbd3 | ||
|
|
c6b3bc5b20 | ||
|
|
e31cb28b08 | ||
|
|
458fa7bfeb | ||
|
|
fab3f0f2de | ||
|
|
c8d9238c58 | ||
|
|
5aa79caf84 | ||
|
|
12cabbde9e | ||
|
|
ca3ab2014f | ||
|
|
3e6283a262 | ||
|
|
bc0d0a6b39 | ||
|
|
6a4727e3eb | ||
|
|
ff6d1c808d | ||
|
|
197d15b7de | ||
|
|
bb5f6a1d79 | ||
|
|
e8c6121b4e | ||
|
|
bed81d785c | ||
|
|
0503914527 | ||
|
|
cb65ae6848 | ||
|
|
652d083766 | ||
|
|
091d9c10fb | ||
|
|
835fe10bfe | ||
|
|
5a474f94e0 | ||
|
|
d322feeb54 | ||
|
|
842c7b31fb | ||
|
|
1034f02d4d | ||
|
|
3f6b6dfaf3 | ||
|
|
d3d4dee36a | ||
|
|
7002248325 | ||
|
|
d8d0f01f80 | ||
|
|
b3b842c071 | ||
|
|
aca8d1b8f9 | ||
|
|
4f328740dc | ||
|
|
2f1c2f42b1 | ||
|
|
d42a998e49 | ||
|
|
167db22e15 | ||
|
|
108777251e | ||
|
|
088713a555 | ||
|
|
7582ebc9c8 | ||
|
|
97d9764f01 | ||
|
|
dfcd8395d5 | ||
|
|
6e91bee0ba | ||
|
|
cf791a1909 | ||
|
|
c6d872d177 | ||
|
|
cc4f3a827c | ||
|
|
0489fbb685 | ||
|
|
7da23603ec | ||
|
|
afb4ae2109 | ||
|
|
e024375b15 | ||
|
|
3632fb359f | ||
|
|
2a3ba5d5f0 | ||
|
|
5b9dc764c5 | ||
|
|
24a0d4f308 | ||
|
|
88f5b10b22 | ||
|
|
cf69859885 | ||
|
|
af71f7f8cd | ||
|
|
ec22ca7553 | ||
|
|
c42d8a81c7 | ||
|
|
0e7473c3ba | ||
|
|
f4f9ccc3b2 | ||
|
|
efda8aac1d | ||
|
|
a84cec4acd | ||
|
|
cf6b7a4236 | ||
|
|
998f46b45c | ||
|
|
5ca352a6c3 | ||
|
|
a34bd3b013 | ||
|
|
c268bc327a | ||
|
|
e79a27c654 | ||
|
|
2f0bac8ddf | ||
|
|
12d7d1c3f0 | ||
|
|
34ca2cddd4 | ||
|
|
fa076efd3b | ||
|
|
b55676d089 | ||
|
|
9b71c090c5 | ||
|
|
0f8e4e4eed | ||
|
|
de1e3d7b17 | ||
|
|
3d077a0bc6 | ||
|
|
c74d1f4bf7 | ||
|
|
776e1211bc | ||
|
|
b5a8ca6ef7 | ||
|
|
2c198ed89a | ||
|
|
17fdeb9e1f | ||
|
|
e41858f57c | ||
|
|
219d47f04c | ||
|
|
750721c1a0 | ||
|
|
b66b43256b | ||
|
|
58cacaff06 | ||
|
|
9aebb01d62 | ||
|
|
f3b4308cb5 | ||
|
|
12089e127a | ||
|
|
c75b8711b1 | ||
|
|
67322c1264 | ||
|
|
607f0346f4 | ||
|
|
d5bb34f65d | ||
|
|
3e18efd89f | ||
|
|
bec3cb48e5 | ||
|
|
e8d2819c42 | ||
|
|
cc85c2f4d7 | ||
|
|
bee4fa9937 | ||
|
|
14ab5801d2 | ||
|
|
fd8a5ff4c4 | ||
|
|
ef9ae0db94 | ||
|
|
4db384da34 | ||
|
|
0784d2ea4e | ||
|
|
b90db6931d | ||
|
|
25497336bb | ||
|
|
a0ee9557f0 | ||
|
|
7b3eb09067 | ||
|
|
1fc3be0c9f | ||
|
|
6de327402b | ||
|
|
131ce826c3 | ||
|
|
a3f4ad9ea0 | ||
|
|
ec3b1131d9 | ||
|
|
74c0345009 | ||
|
|
628b03da29 | ||
|
|
bd59fb0b4e | ||
|
|
443b436be8 | ||
|
|
993d648011 | ||
|
|
343f3059e6 | ||
|
|
10f8fe8973 | ||
|
|
e44bf42c64 | ||
|
|
3d1684fa94 | ||
|
|
d882bad706 | ||
|
|
686530c187 | ||
|
|
e5c8273f72 | ||
|
|
440f7bacd6 | ||
|
|
ba22d3e9b6 | ||
|
|
33463152e8 | ||
|
|
657af3024e | ||
|
|
7d82a34538 | ||
|
|
a0b788e96a | ||
|
|
50c14d353b | ||
|
|
b63aa3079b | ||
|
|
25be24e6b8 | ||
|
|
2ec2da5dff | ||
|
|
b3df15a3c6 | ||
|
|
481ecee9e8 | ||
|
|
462980c70a | ||
|
|
2171686284 | ||
|
|
b382edc61d | ||
|
|
5ae21d04b0 | ||
|
|
b0825ead84 | ||
|
|
2980f852aa | ||
|
|
5e07ebe7fa | ||
|
|
baabb3a873 | ||
|
|
5ee1c3f2c8 | ||
|
|
3fe2a2b181 | ||
|
|
3d2b923102 | ||
|
|
43c941d370 | ||
|
|
e1721b8496 | ||
|
|
ccf3ed185f | ||
|
|
99af27770e | ||
|
|
e9088bd52e | ||
|
|
f72b8ce30f | ||
|
|
19bb96121b | ||
|
|
69ef7cf168 | ||
|
|
f1aace5a22 | ||
|
|
0718ac514d | ||
|
|
d289994da4 | ||
|
|
30f258b3f9 | ||
|
|
d06d22c7c9 | ||
|
|
57c301d59c | ||
|
|
4bde2f64bd | ||
|
|
8ca487115f | ||
|
|
7ad0a1e557 | ||
|
|
1aa626f0e8 | ||
|
|
7e36d17135 | ||
|
|
2f7e875eb4 | ||
|
|
3ab8632d3b | ||
|
|
190fc4e3c4 | ||
|
|
3eb1b9d168 | ||
|
|
2fb3d6ddf5 | ||
|
|
bf74a75303 | ||
|
|
7d1b240954 | ||
|
|
2db3e4ca48 | ||
|
|
cee2e63278 | ||
|
|
9d5732400f | ||
|
|
3cb0613d04 | ||
|
|
d9920fce3a | ||
|
|
2765a0a9fd | ||
|
|
92ea7fcfb1 | ||
|
|
9d96793e1a | ||
|
|
7776283a47 | ||
|
|
c9d4802bf1 | ||
|
|
37558e24f8 | ||
|
|
67cf9f6caf | ||
|
|
16146af039 | ||
|
|
6a7e06f11c | ||
|
|
adba56a5e5 | ||
|
|
90c9fc5338 | ||
|
|
0a09f507fc | ||
|
|
9ea60ba79f | ||
|
|
43ef82aaaa | ||
|
|
7171d790f4 | ||
|
|
4099549609 | ||
|
|
4e4bffe5c5 | ||
|
|
1c8000d026 | ||
|
|
ff34a787c3 | ||
|
|
84c5f57d22 | ||
|
|
64181c7cf1 | ||
|
|
3c5f840cf0 | ||
|
|
1fa4bc9ac0 | ||
|
|
b742910107 | ||
|
|
b7f124072f | ||
|
|
ec02eda113 | ||
|
|
8d8523684c | ||
|
|
8a0c7b3fe1 | ||
|
|
a29dbaba21 | ||
|
|
51ad4fac01 | ||
|
|
d863ba1b2a | ||
|
|
175001eccd | ||
|
|
846d99cfce | ||
|
|
2486a9c914 | ||
|
|
a47a81db6f | ||
|
|
587e790892 | ||
|
|
f73a83aa55 | ||
|
|
513cf2b8e2 | ||
|
|
ea215697ed | ||
|
|
d40686e5d0 | ||
|
|
0b7d343c7c | ||
|
|
d692ed634a | ||
|
|
7d4e07df79 | ||
|
|
8211bc09d4 | ||
|
|
5705005ca3 | ||
|
|
79b4642b32 | ||
|
|
c9981ff0e1 | ||
|
|
0948b061fe | ||
|
|
a537e78f14 | ||
|
|
25edeebf2b | ||
|
|
a7a4727591 | ||
|
|
bc2afb21e1 | ||
|
|
64fe93b9eb | ||
|
|
33d2a852c9 | ||
|
|
300679c053 | ||
|
|
f9c85c52f3 | ||
|
|
98985b2761 | ||
|
|
8fe00d428d | ||
|
|
02229482b8 | ||
|
|
9a5c1aa02f | ||
|
|
a46e340a13 | ||
|
|
70c3cd99ac | ||
|
|
e89bbde575 | ||
|
|
2ee1e2af72 | ||
|
|
c3ad21c548 | ||
|
|
635a24dff4 | ||
|
|
a03423794a | ||
|
|
d4e723a8eb | ||
|
|
ded9f18b8a | ||
|
|
a96345401f | ||
|
|
9359fc065c | ||
|
|
878be8fff0 | ||
|
|
beb418b093 | ||
|
|
0f89d2b8e0 | ||
|
|
fc88c306ab | ||
|
|
5664f5e0a2 | ||
|
|
136bc13ff6 | ||
|
|
62b738da95 | ||
|
|
e7c7f91a3f | ||
|
|
8a65fc8a43 | ||
|
|
0b95e061a3 | ||
|
|
383917eb0f | ||
|
|
7e3046b85c |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -33,8 +33,10 @@ apps/
|
||||
home.html
|
||||
# page header plugin
|
||||
pageheader.html
|
||||
# Ignore site TOS
|
||||
# Ignore site TOS & gddpr
|
||||
doc/SiteTOS.md
|
||||
doc/*/SiteTOS.md
|
||||
doc/*/gdpr.md
|
||||
# themes except for redbasic
|
||||
view/theme/*
|
||||
!view/theme/redbasic
|
||||
@@ -55,6 +57,7 @@ tests/results/
|
||||
.buildpath
|
||||
.externalToolBuilders
|
||||
.settings/
|
||||
.pydevproject
|
||||
# NetBeans project folder
|
||||
nbproject/
|
||||
# Kdevelop project files
|
||||
@@ -75,3 +78,5 @@ composer.phar
|
||||
vendor/**/tests/
|
||||
vendor/**/Test/
|
||||
vendor/sabre/*/examples/
|
||||
# /info is a directory containing site-specific HTML documents
|
||||
/info/
|
||||
|
||||
115
.gitlab-ci.yml
115
.gitlab-ci.yml
@@ -1,7 +1,9 @@
|
||||
# Select image from https://hub.docker.com/_/php/
|
||||
#image: php:7.3
|
||||
# Use a prepared Hubzilla image to optimise pipeline duration
|
||||
image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.3
|
||||
# image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.3
|
||||
|
||||
image: php:8.0
|
||||
|
||||
stages:
|
||||
- test
|
||||
@@ -35,7 +37,12 @@ before_script:
|
||||
- if [ -f /usr/local/etc/php/conf.d/z_prod.ini ]; then mv /usr/local/etc/php/conf.d/z_prod.ini /usr/local/etc/php/conf.d/z_prod.ini.off; fi
|
||||
# Install & enable Xdebug for code coverage reports
|
||||
- pecl install xdebug
|
||||
- apt-get update
|
||||
- apt-get install zip unzip libjpeg-dev libpng-dev -yqq
|
||||
- docker-php-ext-enable xdebug
|
||||
- docker-php-ext-install gd
|
||||
|
||||
|
||||
# Install composer
|
||||
- curl -sS https://getcomposer.org/installer | php
|
||||
# Install dev libraries from composer
|
||||
@@ -43,31 +50,38 @@ before_script:
|
||||
# php.ini settings
|
||||
- echo 'xdebug.mode=coverage' >> /usr/local/etc/php/php.ini
|
||||
|
||||
# hidden job definition with template for MySQL/MariaDB
|
||||
.job_template_mysql: &job_definition_mysql
|
||||
# hidden job definition with template for PHP
|
||||
.job_template_php: &job_definition_php
|
||||
stage: test
|
||||
script:
|
||||
- echo "USE $MYSQL_DATABASE; $(cat ./install/schema_mysql.sql)" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
|
||||
- echo "SHOW DATABASES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
|
||||
- echo "USE $MYSQL_DATABASE; SHOW TABLES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
|
||||
- vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-text
|
||||
|
||||
|
||||
# hidden job definition with template for MySQL/MariaDB
|
||||
#.job_template_mysql: &job_definition_mysql
|
||||
# stage: test
|
||||
# script:
|
||||
# - echo "USE $MYSQL_DATABASE; $(cat ./install/schema_mysql.sql)" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
|
||||
# - echo "SHOW DATABASES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
|
||||
# - echo "USE $MYSQL_DATABASE; SHOW TABLES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
|
||||
# - vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-text
|
||||
|
||||
# hidden job definition with template for PostgreSQL
|
||||
.job_template_postgres: &job_definition_postgres
|
||||
stage: test
|
||||
services:
|
||||
- postgres:latest
|
||||
script:
|
||||
- export PGPASSWORD=$POSTGRES_PASSWORD
|
||||
- psql --version
|
||||
- psql -h "postgres" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "SELECT VERSION();"
|
||||
#.job_template_postgres: &job_definition_postgres
|
||||
# stage: test
|
||||
# services:
|
||||
# - postgres:latest
|
||||
# script:
|
||||
# - export PGPASSWORD=$POSTGRES_PASSWORD
|
||||
# - psql --version
|
||||
# - psql -h "postgres" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "SELECT VERSION();"
|
||||
# Import hubzilla's DB schema
|
||||
- psql -h "postgres" -U "$POSTGRES_USER" -v ON_ERROR_STOP=1 --quiet "$POSTGRES_DB" < ./install/schema_postgres.sql
|
||||
# - psql -h "postgres" -U "$POSTGRES_USER" -v ON_ERROR_STOP=1 --quiet "$POSTGRES_DB" < ./install/schema_postgres.sql
|
||||
# Show databases and relations/tables of hubzilla's database
|
||||
#- psql -h "postgres" -U "$POSTGRES_USER" -l
|
||||
#- psql -h "postgres" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "\dt;"
|
||||
# Run the actual tests
|
||||
- vendor/bin/phpunit --configuration tests/phpunit-pgsql.xml --testdox
|
||||
# - vendor/bin/phpunit --configuration tests/phpunit-pgsql.xml --testdox
|
||||
|
||||
# hidden job definition with artifacts config template
|
||||
.artifacts_template:
|
||||
@@ -82,56 +96,61 @@ before_script:
|
||||
- tests/results/
|
||||
|
||||
|
||||
# PHP7.3 with MySQL 5.7
|
||||
php7.3_mysql5.7:
|
||||
<<: *job_definition_mysql
|
||||
services:
|
||||
- mysql:5.7
|
||||
# PHP8.0
|
||||
php8.0:
|
||||
<<: *job_definition_php
|
||||
|
||||
# PHP8.0 with MySQL 5.7
|
||||
#php8.0_mysql5.7:
|
||||
# <<: *job_definition_mysql
|
||||
# services:
|
||||
# - mysql:5.7
|
||||
|
||||
|
||||
# PHP7.3 with MySQL 8 (latest)
|
||||
php7.3_mysql8:
|
||||
<<: *job_definition_mysql
|
||||
services:
|
||||
- name: mysql:8
|
||||
command: ["--default-authentication-plugin=mysql_native_password"]
|
||||
# PHP8.0 with MySQL 8 (latest)
|
||||
#php8.0_mysql8:
|
||||
# <<: *job_definition_mysql
|
||||
# services:
|
||||
# - name: mysql:8
|
||||
# command: ["--default-authentication-plugin=mysql_native_password"]
|
||||
|
||||
|
||||
# PHP7.3 with MariaDB 10.2
|
||||
php7.3_mariadb10.2:
|
||||
<<: *job_definition_mysql
|
||||
services:
|
||||
- name: mariadb:10.2
|
||||
alias: mysql
|
||||
# PHP8.0 with MariaDB 10.2
|
||||
#php8.0_mariadb10.2:
|
||||
# <<: *job_definition_mysql
|
||||
# services:
|
||||
# - name: mariadb:10.2
|
||||
# alias: mysql
|
||||
|
||||
|
||||
# PHP7.3 with MariaDB 10.3 (latest)
|
||||
php7.3_mariadb10.3:
|
||||
<<: *job_definition_mysql
|
||||
image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.3
|
||||
services:
|
||||
- name: mariadb:10.3
|
||||
alias: mysql
|
||||
# PHP8.0 with MariaDB 10.3 (latest)
|
||||
#php8.0_mariadb10.3:
|
||||
# <<: *job_definition_mysql
|
||||
# image: php:8.0
|
||||
#image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.3
|
||||
# services:
|
||||
# - name: mariadb:10.3
|
||||
# alias: mysql
|
||||
|
||||
|
||||
# PHP7.3 with PostgreSQL latest (11)
|
||||
php7.3_postgres11:
|
||||
<<: *job_definition_postgres
|
||||
artifacts: *artifacts_template
|
||||
#php7.3_postgres11:
|
||||
# <<: *job_definition_postgres
|
||||
# artifacts: *artifacts_template
|
||||
|
||||
|
||||
# PHP7.3 with PostgreSQL latest (11)
|
||||
php7.3_postgres11:
|
||||
<<: *job_definition_postgres
|
||||
image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.3
|
||||
artifacts: *artifacts_template
|
||||
#php7.3_postgres11:
|
||||
# <<: *job_definition_postgres
|
||||
# image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.3
|
||||
# artifacts: *artifacts_template
|
||||
|
||||
|
||||
# Generate Doxygen API Documentation and deploy it as GitLab pages
|
||||
pages:
|
||||
stage: deploy
|
||||
cache: {}
|
||||
image: php:7-cli-alpine
|
||||
image: php:8-cli-alpine
|
||||
before_script:
|
||||
- apk update
|
||||
- apk add doxygen ttf-freefont graphviz
|
||||
|
||||
497
CHANGELOG
497
CHANGELOG
@@ -1,3 +1,500 @@
|
||||
Hubzilla 7.8.2 (2022-11-05)
|
||||
- Pubcrawl: fix regression in inbox
|
||||
- Fix display issue of shares coming from streams
|
||||
- Throw a 404 if we could not determine which channel to load
|
||||
- If we have a cached xchan/hubloc entry, make sure we fetch the latest
|
||||
- Gallery: paint the background grid with css
|
||||
|
||||
|
||||
Hubzilla 7.8.1 (2022-10-26)
|
||||
- Silence tons of PHP warnings in core
|
||||
- Catch decryption failure edgecase in receiver
|
||||
- Deal with conversation privacy mismatches in Activity::store()
|
||||
- Composer libs updates
|
||||
- Fix timeago strings not always translated
|
||||
- Fix edit link regression in cards addon
|
||||
- Fix edit link regression in article addon
|
||||
|
||||
|
||||
Hubzilla 7.8 (2022-10-10)
|
||||
- Updated spanish translations
|
||||
- Always update hubloc_updated timestamp if a hubloc is updated
|
||||
- Do better with re-installs in various situations
|
||||
- Update htconfig templates
|
||||
- Emit an info if an item is deleted manually (issue #1691)
|
||||
- Updated german translations
|
||||
- Make Activity::actor_store() fetch the actor object if none is provided
|
||||
- Check for various forms of as:Public for compatibility
|
||||
- Cleanup dark schema
|
||||
- Make use of CSS variables in redbasic
|
||||
- Implement link hover color in redbasic
|
||||
- Update to bootstrap version 5.2 which implements CSS variables
|
||||
|
||||
Bugfixes
|
||||
- Fix stream filter for polls and events does not work anymore (issue #1694)
|
||||
- Fix item menu display issue
|
||||
- Fix HQ widget displaying superblocked items
|
||||
- Fix mod poke
|
||||
- Fix link to article or card not processed correctly if umlauts are involved (issue #1687)
|
||||
- Fix mod siteinfo containing a dead link (issue #1690)
|
||||
- Fix permission issue when displaying things (issue #1686).
|
||||
- Fix check for existing profiles (issue #1688)
|
||||
- Fix modal missing for conversation settings
|
||||
- Fix missing closing div tag if there are no recent channel activities
|
||||
- Fix issue where an unkown diaspora author was not imported if the comment arrived via a relayed activity
|
||||
- Fix mangled xchan_url due to escape_tags()
|
||||
- Fix the AP url not decode bin mod search
|
||||
- Fix some php warnings
|
||||
|
||||
Addons
|
||||
- Wiki: move create_missing_page() from widget to module
|
||||
- Superblock: implement blocking for messages widget_item
|
||||
- Diaspora: fix verification of relayed comments and likes
|
||||
- Pubcrawl: make sure to store the attributedTo actor in announce activities
|
||||
- Diaspora: fix issue where an unkown author was not imported if the comment arrived via a relayed activity
|
||||
|
||||
|
||||
Hubzilla 7.6.1 (2022-08-07)
|
||||
Bugfixes
|
||||
- Fix attachments displayed in visible response activities
|
||||
- Fix wrong attribution in unseen like notifications
|
||||
|
||||
Addons
|
||||
- Cards: fix widget not implemented via pdl file (requires re-install)
|
||||
- Articles: fix widget not implemented via pdl file (requires re-install)
|
||||
- Wiki: fix widget not implemented via pdl file (requires re-install)
|
||||
|
||||
|
||||
Hubzilla 7.6 (2022-07-26)
|
||||
- Add filter rule to check for false condition
|
||||
- Implement HQ dashboard to display recently created content for various modules
|
||||
- Updated spanish translations
|
||||
- Implement a max oembed size which defaults to 1MB
|
||||
- Update composer libs
|
||||
|
||||
Addons
|
||||
- Cart: do not attempt oembed
|
||||
- Cards: implement channel_activities_widget for HQ dashboard
|
||||
- Articles: implement channel_activities_widget for HQ dashboard
|
||||
- Wiki: implement channel_activities_widget for HQ dashboard
|
||||
|
||||
Bugfixes
|
||||
- Fix language filter filtering ambigous results
|
||||
- Fix vcard-card background for dark schema
|
||||
- Fix contact edit dialog not displayed in chrome browser
|
||||
- Fix readability of category pills in dark schema
|
||||
- Fix opengraph images inside zmg opening tag
|
||||
- Fix oembed attempted for text previews
|
||||
|
||||
|
||||
Hubzilla 7.4 (2022-06-01)
|
||||
- Updated russian translations
|
||||
- Raise min PHP version to 8.0
|
||||
- Rewrite inbound attachment handling
|
||||
- Move photo flag feature from addon to core
|
||||
- Adjust default production php logging
|
||||
- Update composer libs
|
||||
- Add a hidden config to enable the hs2019 http signature algorithm
|
||||
- Allow starring of pubstream items
|
||||
- Update spanish translations
|
||||
- Add the title in forum post reshares if applicable
|
||||
- Implement inbound pleroma reactions
|
||||
- Add real name info to the navbar template data
|
||||
- Add the updated date to the icon url so that other platforms will pick it up on change
|
||||
- Move wiki from core to addon
|
||||
- Move articles from core to addon
|
||||
- Move cards from core to addon
|
||||
|
||||
Addons
|
||||
- Rendezvous: add missing default value to sql schema
|
||||
- Wiki: moved from core to addons
|
||||
- Articles: moved from core to addons
|
||||
- Cards: moved from core to addons
|
||||
- Photoflag: moved to core
|
||||
- Sse: fix issue where notifications were emited for created tasks
|
||||
|
||||
Bugfixes
|
||||
- Fix issue where inbound activitypub items lost image descriptions (issue 1679)
|
||||
- Fix issue where observer tags were not rendered correctly in event items (issue 1674)
|
||||
- Fix forum posts leaked into network stream
|
||||
- Fix tags not found in search if not logged in (issue 1677)
|
||||
- Fix dislikes causing stuck notifications (issue 1676)
|
||||
|
||||
|
||||
Hubzilla 7.2.2 (2022-04-26)
|
||||
- Fix item_verified not set due to data structure changes
|
||||
|
||||
|
||||
Hubzilla 7.2.1 (2022-04-25)
|
||||
- Fix changing profile image from new member widget - issue #1671
|
||||
- Fix regression with incoming poll answers from activitypub introduced in 7.2
|
||||
- Fix addons not removed from the DB when removed from the filesystem
|
||||
- Fix regression in attaching images for activitypub introduced in 7.2
|
||||
- Move activitypub addressing from core to the pubcrawl addon
|
||||
- Fix hub re-install issues
|
||||
- Fediwordle: slightly improved algorithm
|
||||
|
||||
|
||||
Hubzilla 7.2 (2022-03-29)
|
||||
- Streamline comment policy with downstream project
|
||||
- Add new function is_local_url()
|
||||
- Add helper function to escape URLs
|
||||
- Add signing algorithm to zotinfo()
|
||||
- Store signing algorithm in import_xchan()
|
||||
- Use bootstrap-nightfall for redbasic:dark schema
|
||||
- Add support for hs2019
|
||||
- Remove unused function script_path()
|
||||
- Move login and register button into the hamburger menu for small screens
|
||||
- Collect accept headers in an array instead of a concatenated string
|
||||
- Update composer libs
|
||||
- Enhanced content filters
|
||||
- Improve mod gprobe to also deal with URLs
|
||||
- Adapt unseen forum posts query in mod network to new forum post style
|
||||
- Remove deprecated widgets
|
||||
- Add inbound support for quoteUrl to Lib/Activity
|
||||
- Add widget descriptions
|
||||
- Add a GUI for the PDL editor
|
||||
|
||||
Addons
|
||||
- Pubcrawl: deprecate as.php in favor of core libs
|
||||
- Pubcrawl: rewrite/modernize mod inbox
|
||||
- Pubcrawl: reflect core enhanced content filter changes
|
||||
- Diaspora: reflect core enhanced content filter changes
|
||||
- Fediwordle: new addon - a distributed word game inspired by wordle
|
||||
- Pubcrawl: streamline post_local hook with diaspora
|
||||
|
||||
Bugfixes
|
||||
- Fix comments_closed date on posts where comments are disabled
|
||||
- Fix open redirect via rpath query param (CVE-2022-27256)
|
||||
- Fix cross-site scripting via rpath query param (CVE-2022-27258)
|
||||
- Fix local file inclusion in redbasic theme (CVE-2022-27257)
|
||||
- Fix baseurl for css and js
|
||||
- Fix duplicate IDs in login form
|
||||
- Fix unknown author not fetched if w2w comment arrives
|
||||
- Fix thr_parent lost across edits
|
||||
|
||||
|
||||
Hubzilla 7.0.3 (2022-02-10)
|
||||
- Allow to override the charset for the PDO connection string via $db_charset in .htconfig.php
|
||||
|
||||
|
||||
Hubzilla 7.0.2 (2022-02-09)
|
||||
- Update french templates
|
||||
- Add charset to the PDO connection strings
|
||||
- Introduce delete keytype for get_activitystreams_key()
|
||||
- Fix PHP error in Daemon/Externals
|
||||
- Improved actor cache handling
|
||||
- Implement manual fetch of packed local links
|
||||
- Add JSalmon data to the meta field instead of data in Lib/ActivityStreams
|
||||
- Fix some PHP8.1 deprecation warnings
|
||||
- Fix delivery report for likes not found in some cases
|
||||
- Allow zotfinger to recurse through all known hublocs if the one we got does not exist (404) or got removed (410)
|
||||
- Diaspora: improve relaying of comments
|
||||
- Fix regression in mod hcard
|
||||
- Add the LD signature in Daemon/Notifier in case where there is no signed data available
|
||||
- Prevent zot6 packet being saved as AP raw message
|
||||
- Attach iconfig to the activity instead of the activity object
|
||||
|
||||
Addons
|
||||
- Pubcrawl: make sure the sys channel falls through the app installed check
|
||||
- Pubcrawl: improve local delivery of shared inbox items
|
||||
|
||||
|
||||
Hubzilla 7.0.1 (2022-01-28)
|
||||
- Fix removing contacts from privacy groups in the contact edit modal
|
||||
- Fix escape_tags() messing with URLs in actor_store()
|
||||
- Fix pagination in the cards module if a category is selected
|
||||
- Remove unused entries in webfinger
|
||||
- Remove deprecated mail app from apps
|
||||
- Set item_hidden for forum comment announces
|
||||
- Fix relaying of signed messages for activitypub
|
||||
- Fix contact role permissions not re-assigned if the role permission has changed
|
||||
- Fix default channel role not set in rare cases
|
||||
|
||||
Addons
|
||||
- Pubcrawl: fix webfinger not returning the fetched URL
|
||||
- Pubcrawl: improved queue handling for rejected deliveries
|
||||
|
||||
|
||||
Hubzilla 7.0 (2022-01-21)
|
||||
- Provide theme_color and background_color in App::$theme_info for usage in page meta and manifest
|
||||
- PWA improvements according to lighthouse
|
||||
- Refactor mod profile_photo
|
||||
- Remove core legacy mail code
|
||||
- Set session samesite cookie flag
|
||||
- Improve toc bbcode for more flexible usecases
|
||||
- Deprecate include/group in favor of Lib/AccessList
|
||||
- Deprecate AccessList::widget()
|
||||
- Mark forum channel profile images with a small icon in the timelines
|
||||
- Improve privacy groups UI/UX
|
||||
- Do not show connections widget if there are no connections
|
||||
- Remove suggestions widget from various modules
|
||||
- Provide guest access links for private resources in lockview
|
||||
- Improve pconfig syncing
|
||||
- deprecate include/group in favor of Lib/AccessList
|
||||
- Implement background deleting of items in contact_remove()
|
||||
- Refactor guest access tokens for better usability and provide quick access
|
||||
- Refactor permissions handling
|
||||
- Improved poll rendering
|
||||
|
||||
Bugfixes
|
||||
- Fix items not deleted on remote channel purge
|
||||
- Fix plink in post_activity_item()
|
||||
- Fix multiple update_poll() calls dismissed in queueworker
|
||||
- Fix blocked or ignored contacts displayed in connections
|
||||
- Fix polls for forum channels
|
||||
|
||||
Addons:
|
||||
- Legacy mail: remove
|
||||
- Deprecate include/group in favor of Lib/AccessList
|
||||
- Pubcrawl: support pleroma end time for polls
|
||||
- Pubcrawl: slightly adjust the way we check mastodon direct messages
|
||||
- Socialauth: scope support and improvements
|
||||
|
||||
|
||||
Hubzilla 6.4.2 (2021-12-14)
|
||||
- Fix issue in mod sse_bs where returning message id's were assumed to be base64 encoded
|
||||
- Fix announce activity type not registered as response activity
|
||||
|
||||
|
||||
Hubzilla 6.4.1 (2021-12-03)
|
||||
- Fix hubloc_site_id in fix_system_urls() on detected site rename events
|
||||
- Fix duplicate deliveries if duplicate hublocs available
|
||||
- Redesign profile vcard for improved responsive handling
|
||||
- Fix profile photos not stored in profile photo folder
|
||||
- Maximum width of content region is now calculated in rem for improved responsive handling
|
||||
- Fix likes notices emited allthough they are disabled
|
||||
- Fix page not reloaded after comment/like in mod photos - issue #1651
|
||||
- Port improved Lib/HttpMeta from zap
|
||||
- Improved responsive aside
|
||||
|
||||
|
||||
Hubzilla 6.4 (2021-11-09)
|
||||
- Automatically connect the invitee with the inviting channel
|
||||
- Use the composer version of urlify
|
||||
- Implement zip file import of exported items from mod uexport
|
||||
- Start sending supported protocols with the actor object
|
||||
- Split up manual item export to separate sections
|
||||
- Serve w3.org jsonld documents locally - issue #1637
|
||||
- Support IDNA URL embedding
|
||||
- Improve handling of re-installed hubs in lib HTTPSig
|
||||
- BBcode support for notes widget/app
|
||||
- Implement a force flag for HTTPSig::get_key()
|
||||
- Update composer libs
|
||||
- Use Libzot::fetch_conversation for manual content import
|
||||
- Implement optional force argument in Libzot::process_delivery
|
||||
- Improve german doco
|
||||
- Move sync logic for apps to mod appman
|
||||
- Provide sync for system apps
|
||||
- Update certificates
|
||||
- Return status code 410 if a channel is deleted
|
||||
- Add optional argument to channelx_by_* functions to allow inclusion of removed channels
|
||||
- Improve file upload performance
|
||||
- Introduce progress tracking for channel cloning via network (not compatible with cloning from older versions)
|
||||
- Improve channel delete performance by moving some actions to background tasks
|
||||
- Introduce all in one channel cloning via network (not compatible with cloning from older versions)
|
||||
- Rename zotfeed to outbox but keep an alias for compatibility
|
||||
- Implement apps un-starring from the app bin via drag and drop
|
||||
- Re-implement the externals daemon
|
||||
- Add zot6 specific handling to onepoll
|
||||
- Implement the top option in items_fetch() which will only return top level items
|
||||
- Add notices tab to HQ widget
|
||||
- Improve mod manage performance
|
||||
- Add option to mark all notices of a thread read if a notice of the thread is clicked (default true)
|
||||
- Provide a get_cached_actor_provider hook and improve the author/owner handling in Libzot::import()
|
||||
|
||||
Bugfixes
|
||||
- Fix issue where remote channels could not create wiki pages due to wron permission check - issue #1640
|
||||
- Fix dutch registration email template
|
||||
- Fix selection of invite template
|
||||
- Fix too restrictive email check in mod invite
|
||||
- Fix photos and albums ActivityStreams 2 representation
|
||||
- Fix keys always fetched from network in lib HTTPSig for some AP implementations
|
||||
- Fix album display of root directory
|
||||
- Fix onepoll importing to deleted channels
|
||||
- Fix rendering of image tags in codeblocks
|
||||
- Fix webfinger and xrd providing results for removed channels
|
||||
- Fix alt_pager() providing too many arguments
|
||||
- Fix drop_query_params() if no query params are provided
|
||||
- Fix duplicate entries for dead hubs in delivery report
|
||||
- Fix site lookup
|
||||
- Fix mod locs displaying drop icons for local channels
|
||||
- Fix multiple issues with propagating deletes of cloned channels
|
||||
- Fix apps can be draged outsite of drop areas
|
||||
- Fix removed channels counted in max id check
|
||||
- Fix api_auth not fetching the id if it was not cached
|
||||
- Fix public stream unseen notifications displayed allthough the app is not installed
|
||||
- Fix possible storage conversion stuck on file save error
|
||||
- Fix notification panel collapsed state not saved if closed manually
|
||||
- Fix find_best_identity() dismissing AP hublocs
|
||||
- Fix likes and commments on direct messages mixed up in notices
|
||||
- Fix rewrite of links to resources in body fails if nicknames of clones differ - issue #1507
|
||||
- Fix syncing outdated data due to profile sync done before the fields were updated
|
||||
- Fix $desturl set to wrong value (null)
|
||||
|
||||
Addons
|
||||
- Cart: add settings URL to the apd file
|
||||
- Diaspora: remove deprecated included
|
||||
- Cart: remove deprecated include
|
||||
- Openid: remove library/urlify in favor of composer installed versions
|
||||
- Pubcrawl: provide tags indicating the supported protocols
|
||||
- Pubcrawl: if we do not get an uuid, create a v5 uuid from the mid
|
||||
- Cart: fix rendering regressions from bootstrap5 upgrade
|
||||
- Upgrade_info: fix dismiss button
|
||||
- Pubcrawl: move fetch_provider from core to addon
|
||||
- Diaspora: fix regression in fetch_provider
|
||||
- Content_import: fix syntax error
|
||||
- Queueworker: update priorities
|
||||
- Pubcrawl: only lookup announce author if we actually deal with an announce
|
||||
- Pubcrawl: make sure we have the best identity before we make the abook lookup
|
||||
- Pubcrawl: outbox moved to core
|
||||
- Diaspora: implement the get_cached_actor_provider hook
|
||||
|
||||
|
||||
Hubzilla 6.2.2 (2021-10-03)
|
||||
- Fix an issue which could lead to loss of photos under certain conditions
|
||||
|
||||
|
||||
Hubzilla 6.2.1 (2021-09-16)
|
||||
- Fix regression introduced in 6.2 where Diaspora comments on Hubzilla posts were not relayed
|
||||
- Fix wrong variable used for refresh under certain conditions
|
||||
- Fix issue where summary tag was processed in cleanup_bbcode() while it shoud not
|
||||
- Fix issue where profile name change was not applied if done from non primary location
|
||||
- Fix spacing issue for collapsed pinned apps with an image
|
||||
- Fix language selector reloading the page if not clicking exactly the icon
|
||||
- Fix regression displaying bootstrap modals introduced in 6.2
|
||||
|
||||
|
||||
Hubzilla 6.2 (2021-09-08)
|
||||
- Deprecate the custom highlight [hl] bbcode in favor of [mark] which is a html5 standard
|
||||
- Check post_mail permission when receiving a direct message
|
||||
- Refactor actor store and cache mechanism
|
||||
- Add optional strict flag (false) to base64url_decode() which is passed on to base64_decode()
|
||||
- Update russian translations
|
||||
- Add optional force flag (false) to Activity::actor_store()
|
||||
- Improved icon lookup for actor objects
|
||||
- Improved desktop notifications
|
||||
- Make Hubzilla installable as PWA in supported browsers
|
||||
- Capitalized widget titles (redbasic)
|
||||
- Make images loaded counter showing % loaded instead of actual image count
|
||||
- Deprecate optional channel menu in favor of extended app bin
|
||||
- Implement infrastructure to provide an app install widget for modules
|
||||
- Implement app descriptions
|
||||
- Implement app drag and drop sorting
|
||||
- Implement app drag and drop pinning/starring
|
||||
- Update polish translations
|
||||
- Update to bootstrap 5 and adjust templates
|
||||
|
||||
Bugfixes
|
||||
- Fix anonymous comments for cards and articles
|
||||
- Resolve regex interference between contact and channel autocomplete
|
||||
- Fix files stored in wrong directory when uploaded in the photo module
|
||||
- Fix records with empty public key selected for OWA
|
||||
- Fix import_author_zot failing if primary is both dead and unknown - issue #1599
|
||||
- Fix regression with bookmarks
|
||||
- Fix pubstream notifications link redirecting to mod hq when not local
|
||||
- Cleanup legacy mail leftovers - issue #1595
|
||||
- Fix getimagesize() called with empty path
|
||||
- Fix display issue caused by redundant closing div tag
|
||||
|
||||
Addons
|
||||
- Pubcrawl: fix post to forum - issue #159
|
||||
- Diaspora: implement post_mail permissions for direct messages
|
||||
- Pubcrawl: implement post_mail permissions for direct messages
|
||||
- Pubcrawl: deprecate asencode_person() in favor of Activity::encode_person()
|
||||
- Pubcrawl: implement Activity::get_actor_collections() to reflect core actor store changes
|
||||
- Diaspora: fix use of deprecated function
|
||||
- Twitter: prevent re-retweeting of a post from a clone if it has already been sent
|
||||
- Totp: use platform name instead of banner text
|
||||
- Pubcrawl: use force flag when updating an actor
|
||||
- Sse: do not process possible empty hashes
|
||||
- Implement app descriptions for addons that already support the apps infrastructure
|
||||
|
||||
|
||||
Hubzilla 6.0.1 (2021-07-27)
|
||||
- Fix regression in notification handling introduced in 6.0
|
||||
- Fix regression in regard to unified session page load times introduced in 6.0
|
||||
- Fix photo description textarea only available if create status post enabled
|
||||
- Fix item not found by message id at clone locations
|
||||
- Dismiss deleted xchans in mod chanview
|
||||
|
||||
|
||||
Hubzilla 6.0 (2021-07-09)
|
||||
- Implement swipe to right for bringing in left aside
|
||||
- DB update 1247 to clean up bogus entries in updates
|
||||
- DB update 1246 to mark legacy zot xchans and hublocs deleted
|
||||
- Implement desktop notifications
|
||||
- Emit a warning if the calendar for the created event is disabled
|
||||
- Add an option to drop media for bbcode processing
|
||||
- Make mod HQ the default landing page after login
|
||||
- Implement direct messages view for mod HQ
|
||||
- Implement public/restricted messages view for mod HQ
|
||||
- Implement starred messages view for mod HQ (only available if the Star Posts feature is enabled)
|
||||
- Update composer libs
|
||||
- Remove deprecated mod ping
|
||||
- Remove legacy zot libs and functions - major cleanup
|
||||
|
||||
Bugfixes
|
||||
- Fix deleting and starring in unthreaded view
|
||||
- Fix issue where incomplete datasets were stored into updates
|
||||
- Fix photo item tags not stored and propagated
|
||||
- Fix notifications not loading if a filter was applied
|
||||
- Fix in browser email validation for registrations
|
||||
- Fix directory sync issues
|
||||
- Fix issue where the original rawmsg iconfig got overwritten
|
||||
- Fix unmaintained id3 pareser for PHP8
|
||||
- Fix item_private state for imported items
|
||||
- Random PHP8 fixes (ongoing)
|
||||
|
||||
Addons
|
||||
- Pubcrawl: fix ld-signature for profile updates
|
||||
- Pubcrawl: deprecate as_actor_store() in favor of Activity::actor_store()
|
||||
- Twitter: prevent duplicated tweets
|
||||
- Remove legacy zot dpendencies and deprecated functions
|
||||
- Pubcrawl: fix remote reply for peertube
|
||||
- Pubcrawl: fix issue where we could end up with an xchan but without hubloc
|
||||
- Diaspora: implement the direct_message_recipients hook
|
||||
- Queueworker: add a simple priority mechanism to prevent not so important janitor tasks (e.g. onedirsync) stuffing up the queue and delaying delivery of items
|
||||
- Pubcrawl: implement direct message recognision for activities coming from Mastodon
|
||||
- Pubcrawl: always show complete threads (complete as in all the messages we have received) in public stream
|
||||
- Twitter_api: remove the mail endpoint
|
||||
- Mail: make interface read only with the possibility to download and delete mails (this addon will be removed in a future version)
|
||||
- Pubsubhubbub: move to addons-unmaintained
|
||||
- GNU-Social: move to addons-unmaintained
|
||||
- Fixes to reflect core notifier changes
|
||||
- Diaspora: refactor conversations a.k.a mail to implement direct messages infrastructure
|
||||
- Pubcrawl: allow hublocs to be upgraded from ostatus
|
||||
- Diaspora: fix issue where we could end up with an xchan but without hubloc
|
||||
|
||||
|
||||
Hubzilla 5.6.1 (2021-06-04)
|
||||
- Update spanish translations
|
||||
- Fix login name label if register email verification is disabled
|
||||
- Fix zotinfo issue with deleted channels
|
||||
- Make pubstream ordering configurable
|
||||
- Fix article summary duplicated when editing
|
||||
- Update polish translations
|
||||
- Fix admin setting for invitations not displayed correctly
|
||||
- Fix registration in invite only mode
|
||||
- Fix notifications not returning offset -1 when returning early
|
||||
- Fix direct messages for items imported via sync
|
||||
- Bring back the channel protocols hooks
|
||||
- Fix security headers switching
|
||||
- Fix magic auth for delegated channels
|
||||
- Introduce drop_query_params() for secure query parameter removal
|
||||
- PHP8 fixes (ongoing)
|
||||
- Fix menu wrapping regression
|
||||
|
||||
Addons
|
||||
- LDAPauth: fix regression creating an account
|
||||
- Twitter: allow feeds crossposting
|
||||
- Twitter: fix posting when post by default is disabled
|
||||
- Pubcrawl: add litepub directMessage attribute
|
||||
- Pubcrawl: allow xchan/hubloc upgrades from e.g. ostatus
|
||||
- Diaspora: fix possible issue with missing hublocs
|
||||
- Diaspora: refine dispatching of public of public items
|
||||
|
||||
|
||||
Hubzilla 5.6 (2021-05-11)
|
||||
- Improve postgres hubloc queries
|
||||
- Implement automatic duplicate singleton hubloc removal
|
||||
|
||||
27
SBOM.md
27
SBOM.md
@@ -2,20 +2,21 @@
|
||||
|
||||
|Name|Version|License|Source|
|
||||
|----|-------|-------|------|
|
||||
|blueimp/jquery-file-upload|10.31.0.0|MIT|https://github.com/vkhramtsov/jQuery-File-Upload.git|
|
||||
|brick/math|0.9.2.0|MIT|https://github.com/brick/math.git|
|
||||
|blueimp/jquery-file-upload|10.32.0.0|MIT|https://github.com/vkhramtsov/jQuery-File-Upload.git|
|
||||
|brick/math|0.9.3.0|MIT|https://github.com/brick/math.git|
|
||||
|bshaffer/oauth2-server-php|1.11.1.0|MIT|https://github.com/bshaffer/oauth2-server-php.git|
|
||||
|commerceguys/intl|1.0.7.0|MIT|https://github.com/commerceguys/intl.git|
|
||||
|commerceguys/intl|1.1.0.0|MIT|https://github.com/commerceguys/intl.git|
|
||||
|desandro/imagesloaded|4.1.4.0|MIT|https://github.com/desandro/imagesloaded.git|
|
||||
|ezyang/htmlpurifier|4.13.0.0|LGPL-2.1-or-later|https://github.com/ezyang/htmlpurifier.git|
|
||||
|league/html-to-markdown|4.10.0.0|MIT|https://github.com/thephpleague/html-to-markdown.git|
|
||||
|jbroadway/urlify|1.2.2.0|BSD-3-Clause-Clear|https://github.com/jbroadway/urlify.git|
|
||||
|league/html-to-markdown|5.0.1.0|MIT|https://github.com/thephpleague/html-to-markdown.git|
|
||||
|lukasreschke/id3parser|0.0.3.0|GPL|https://github.com/LukasReschke/ID3Parser.git|
|
||||
|michelf/php-markdown|1.9.0.0|BSD-3-Clause|https://github.com/michelf/php-markdown.git|
|
||||
|pear/text_languagedetect|1.0.1.0|BSD-2-Clause|https://github.com/pear/Text_LanguageDetect.git|
|
||||
|phpseclib/phpseclib|2.0.30.0|MIT|https://github.com/phpseclib/phpseclib.git|
|
||||
|psr/log|1.1.3.0|MIT|https://github.com/php-fig/log.git|
|
||||
|ramsey/collection|1.1.3.0|MIT|https://github.com/ramsey/collection.git|
|
||||
|ramsey/uuid|4.1.1.0|MIT|https://github.com/ramsey/uuid.git|
|
||||
|phpseclib/phpseclib|2.0.33.0|MIT|https://github.com/phpseclib/phpseclib.git|
|
||||
|psr/log|1.1.4.0|MIT|https://github.com/php-fig/log.git|
|
||||
|ramsey/collection|1.2.2.0|MIT|https://github.com/ramsey/collection.git|
|
||||
|ramsey/uuid|4.2.3.0|MIT|https://github.com/ramsey/uuid.git|
|
||||
|sabre/dav|4.1.5.0|BSD-3-Clause|https://github.com/sabre-io/dav.git|
|
||||
|sabre/event|5.1.2.0|BSD-3-Clause|https://github.com/sabre-io/event.git|
|
||||
|sabre/http|5.1.1.0|BSD-3-Clause|https://github.com/sabre-io/http.git|
|
||||
@@ -23,9 +24,13 @@
|
||||
|sabre/vobject|4.3.5.0|BSD-3-Clause|https://github.com/sabre-io/vobject.git|
|
||||
|sabre/xml|2.2.3.0|BSD-3-Clause|https://github.com/sabre-io/xml.git|
|
||||
|simplepie/simplepie|1.5.6.0|BSD-3-Clause|https://github.com/simplepie/simplepie.git|
|
||||
|smarty/smarty|3.1.38.0|LGPL-3.0|https://github.com/smarty-php/smarty.git|
|
||||
|symfony/polyfill-ctype|1.22.0.0|MIT|https://github.com/symfony/polyfill-ctype.git|
|
||||
|twbs/bootstrap|4.6.0.0|MIT|https://github.com/twbs/bootstrap.git|
|
||||
|smarty/smarty|3.1.39.0|LGPL-3.0|https://github.com/smarty-php/smarty.git|
|
||||
|symfony/polyfill-ctype|1.23.0.0|MIT|https://github.com/symfony/polyfill-ctype.git|
|
||||
|symfony/polyfill-php80|1.23.1.0|MIT|https://github.com/symfony/polyfill-php80.git|
|
||||
|symfony/polyfill-php81|1.23.0.0|MIT|https://github.com/symfony/polyfill-php81.git|
|
||||
|twbs/bootstrap|5.1.3.0|MIT|https://github.com/twbs/bootstrap.git|
|
||||
|voku/portable-ascii|1.5.6.0|MIT|https://github.com/voku/portable-ascii.git|
|
||||
|voku/stop-words|2.0.1.0|MIT|https://github.com/voku/stop-words.git|
|
||||
|fullcalendar/fullcalendar|4.4.2.0|MIT|https://github.com/fullcalendar/fullcalendar.git|
|
||||
|miromannino/Justified-Gallery|3.8.1.0|MIT|https://github.com/miromannino/Justified-Gallery.git|
|
||||
|fengyuanchen/cropperjs|1.5.7.0|MIT|https://github.com/fengyuanchen/cropperjs.git|
|
||||
|
||||
10
ServiceWorker.js
Normal file
10
ServiceWorker.js
Normal file
@@ -0,0 +1,10 @@
|
||||
// This file should be served from the web root to avoid scope and cookie related issues with some browsers
|
||||
self.addEventListener('install', function(e) {
|
||||
console.log('install event');
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', function(e) {
|
||||
// nothing here yet
|
||||
return;
|
||||
});
|
||||
|
||||
@@ -139,6 +139,11 @@ class AccessList {
|
||||
* @param boolean $explicit (optional) default true
|
||||
*/
|
||||
function set_from_array($arr, $explicit = true) {
|
||||
$arr['contact_allow'] = $arr['contact_allow'] ?? [];
|
||||
$arr['group_allow'] = $arr['group_allow'] ?? [];
|
||||
$arr['contact_deny'] = $arr['contact_deny'] ?? [];
|
||||
$arr['group_deny'] = $arr['group_deny'] ?? [];
|
||||
|
||||
$this->allow_cid = perms2str((is_array($arr['contact_allow']))
|
||||
? $arr['contact_allow'] : explode(',', $arr['contact_allow']));
|
||||
$this->allow_gid = perms2str((is_array($arr['group_allow']))
|
||||
|
||||
@@ -89,4 +89,4 @@ class PermissionLimits {
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class PermissionRoles {
|
||||
* @return number
|
||||
*/
|
||||
static public function version() {
|
||||
return 2;
|
||||
return 3;
|
||||
}
|
||||
|
||||
static function role_perms($role) {
|
||||
@@ -27,6 +27,54 @@ class PermissionRoles {
|
||||
$ret['role'] = $role;
|
||||
|
||||
switch($role) {
|
||||
|
||||
case 'public':
|
||||
$ret['default_collection'] = false;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage', 'view_pages', 'view_wiki',
|
||||
'send_stream', 'post_comments', 'post_mail', 'post_wall', 'chat', 'post_like', 'republish'
|
||||
];
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
$ret['limits']['post_comments'] = PERMS_AUTHED;
|
||||
$ret['limits']['post_mail'] = PERMS_AUTHED;
|
||||
$ret['limits']['post_like'] = PERMS_AUTHED;
|
||||
$ret['limits']['chat'] = PERMS_AUTHED;
|
||||
break;
|
||||
|
||||
// Hubzilla default role
|
||||
case 'personal':
|
||||
$ret['default_collection'] = true;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage', 'view_pages', 'view_wiki',
|
||||
'send_stream', 'post_comments', 'post_mail', 'chat', 'post_like'
|
||||
];
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
|
||||
break;
|
||||
|
||||
case 'group':
|
||||
$ret['default_collection'] = false;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'view_wiki', 'post_wall', 'post_comments',
|
||||
'post_mail', 'post_like', 'chat'
|
||||
];
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
$ret['channel_type'] = 'group';
|
||||
break;
|
||||
|
||||
// Provide some defaults for the custom role so that we do not start
|
||||
// with no permissions at all if we create a new channel with this role
|
||||
case 'custom':
|
||||
$ret['default_collection'] = true;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage', 'view_pages', 'view_wiki',
|
||||
'send_stream', 'post_comments', 'post_mail', 'chat', 'post_like'
|
||||
];
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
break;
|
||||
|
||||
/*
|
||||
case 'social':
|
||||
$ret['perms_auto'] = false;
|
||||
$ret['default_collection'] = false;
|
||||
@@ -193,13 +241,14 @@ class PermissionRoles {
|
||||
$ret['channel_type'] = 'group';
|
||||
|
||||
break;
|
||||
*/
|
||||
|
||||
case 'custom':
|
||||
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]);
|
||||
@@ -284,6 +333,7 @@ class PermissionRoles {
|
||||
*/
|
||||
static public function roles() {
|
||||
$roles = [
|
||||
|
||||
t('Social Networking') => [
|
||||
'social_federation' => t('Social - Federation'),
|
||||
'social' => t('Social - Mostly Public'),
|
||||
@@ -317,4 +367,29 @@ class PermissionRoles {
|
||||
return $roles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Array with translated role names and grouping.
|
||||
*
|
||||
* Return an associative array with role names that can be used
|
||||
* to create select groups like in \e field_select_grouped.tpl.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function channel_roles() {
|
||||
$channel_roles = [
|
||||
//'public' => [t('Public'), t('A very permissive role suited for participation in the fediverse')],
|
||||
//'personal' => [t('Personal'), t('The $Projectname default role suited for a personal channel')],
|
||||
//'forum' => [t('Community forum'), t('This role configures your channel to act as an community forum')],
|
||||
//'custom' => [t('Custom'), t('This role comes with the presets of the personal role but allows you to configure it to your needs')]
|
||||
'public' => t('Public'),
|
||||
'personal' => t('Personal'),
|
||||
'group' => t('Community forum'),
|
||||
'custom' => t('Custom')
|
||||
];
|
||||
|
||||
call_hooks('list_channel_roles', $channel_roles);
|
||||
|
||||
return $channel_roles;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ class Permissions {
|
||||
* @return number
|
||||
*/
|
||||
static public function version() {
|
||||
return 2;
|
||||
return 3;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,11 +65,11 @@ class Permissions {
|
||||
'write_wiki' => t('Can write to my wiki pages'),
|
||||
'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_mail' => t('Can send me direct 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'),
|
||||
'republish' => t('Can source/mirror my public posts in derived channels'),
|
||||
//'tag_deliver' => t('Can forward to my contacts via direct messages (forum)'),
|
||||
'delegate' => t('Can administer my channel')
|
||||
];
|
||||
|
||||
@@ -217,25 +217,23 @@ class Permissions {
|
||||
|
||||
$my_perms = [];
|
||||
$permcat = null;
|
||||
$automatic = 0;
|
||||
$automatic = get_pconfig($channel_id, 'system', 'autoperms');
|
||||
|
||||
// If a default permcat exists, use that
|
||||
|
||||
$pc = ((feature_enabled($channel_id, 'permcats')) ? get_pconfig($channel_id, 'system', 'default_permcat') : 'default');
|
||||
if (!in_array($pc, ['', 'default'])) {
|
||||
$pcp = new Zlib\Permcat($channel_id);
|
||||
$permcat = $pcp->fetch($pc);
|
||||
if ($permcat && $permcat['perms']) {
|
||||
foreach ($permcat['perms'] as $p) {
|
||||
$my_perms[$p['name']] = $p['value'];
|
||||
}
|
||||
$pc = get_pconfig($channel_id, 'system', 'default_permcat', 'default');
|
||||
$pcp = new Zlib\Permcat($channel_id);
|
||||
$permcat = $pcp->fetch($pc);
|
||||
if ($permcat && $permcat['perms']) {
|
||||
foreach ($permcat['perms'] as $p) {
|
||||
$my_perms[$p['name']] = $p['value'];
|
||||
}
|
||||
}
|
||||
|
||||
// look up the permission role to see if it specified auto-connect
|
||||
// and if there was no permcat or a default permcat, set the perms
|
||||
// from the role
|
||||
|
||||
/*
|
||||
$role = get_pconfig($channel_id, 'system', 'permissions_role');
|
||||
if ($role) {
|
||||
$xx = PermissionRoles::role_perms($role);
|
||||
@@ -247,11 +245,12 @@ class Permissions {
|
||||
$my_perms = Permissions::FilledPerms($default_perms);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// If we reached this point without having any permission information,
|
||||
// it is likely a custom permissions role. First see if there are any
|
||||
// automatic permissions.
|
||||
|
||||
/*
|
||||
if (!$my_perms) {
|
||||
$m = Permissions::FilledAutoperms($channel_id);
|
||||
if ($m) {
|
||||
@@ -259,11 +258,12 @@ class Permissions {
|
||||
$my_perms = $m;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
// If we reached this point with no permissions, the channel is using
|
||||
// custom perms but they are not automatic. They will be stored in abconfig with
|
||||
// the channel's channel_hash (the 'self' connection).
|
||||
|
||||
/*
|
||||
if (!$my_perms) {
|
||||
$r = q("select channel_hash from channel where channel_id = %d",
|
||||
intval($channel_id)
|
||||
@@ -280,10 +280,10 @@ class Permissions {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (['perms' => $my_perms, 'automatic' => $automatic]);
|
||||
*/
|
||||
return (['perms' => $my_perms, 'automatic' => $automatic, 'role' => $pc]);
|
||||
}
|
||||
|
||||
/*
|
||||
static public function serialise($p) {
|
||||
$n = [];
|
||||
if ($p) {
|
||||
@@ -295,4 +295,5 @@ class Permissions {
|
||||
}
|
||||
return implode(',', $n);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
34
Zotlabs/Daemon/Channel_purge.php
Normal file
34
Zotlabs/Daemon/Channel_purge.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
class Channel_purge {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
cli_startup();
|
||||
|
||||
$channel_id = intval($argv[1]);
|
||||
|
||||
$channel = q("select * from channel where channel_id = %d and channel_removed = 1",
|
||||
intval($channel_id)
|
||||
);
|
||||
|
||||
if (! $channel) {
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
$r = q("select id from item where uid = %d and item_deleted = 0 limit 1000",
|
||||
intval($channel_id)
|
||||
);
|
||||
if ($r) {
|
||||
foreach ($r as $rv) {
|
||||
drop_item($rv['id'], false);
|
||||
}
|
||||
}
|
||||
} while ($r);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,9 @@ class Checksites {
|
||||
|
||||
logger('checksites: start');
|
||||
|
||||
$site_id = '';
|
||||
$sql_options = '';
|
||||
|
||||
if (($argc > 1) && ($argv[1]))
|
||||
$site_id = $argv[1];
|
||||
|
||||
|
||||
77
Zotlabs/Daemon/Content_importer.php
Normal file
77
Zotlabs/Daemon/Content_importer.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
use Zotlabs\Web\HTTPSig;
|
||||
use Zotlabs\Lib\PConfig;
|
||||
|
||||
|
||||
require_once('include/cli_startup.php');
|
||||
require_once('include/attach.php');
|
||||
require_once('include/import.php');
|
||||
|
||||
class Content_importer {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
cli_startup();
|
||||
|
||||
$page = $argv[1];
|
||||
$since = $argv[2];
|
||||
$until = $argv[3];
|
||||
$channel_address = $argv[4];
|
||||
$hz_server = urldecode($argv[5]);
|
||||
|
||||
$m = parse_url($hz_server);
|
||||
|
||||
$channel = channelx_by_nick($channel_address);
|
||||
if(! $channel) {
|
||||
logger('channel not found');
|
||||
return;
|
||||
}
|
||||
|
||||
$headers = [
|
||||
'X-API-Token' => random_string(),
|
||||
'X-API-Request' => $hz_server . '/api/z/1.0/item/export_page?f=&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page ,
|
||||
'Host' => $m['host'],
|
||||
'(request-target)' => 'get /api/z/1.0/item/export_page?f=&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page ,
|
||||
];
|
||||
|
||||
$headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'], channel_url($channel),true,'sha512');
|
||||
|
||||
$x = z_fetch_url($hz_server . '/api/z/1.0/item/export_page?f=&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page,false,$redirects,[ 'headers' => $headers ]);
|
||||
|
||||
// logger('item fetch: ' . print_r($x,true));
|
||||
|
||||
if(! $x['success']) {
|
||||
logger('no API response',LOGGER_DEBUG);
|
||||
killme();
|
||||
}
|
||||
|
||||
$j = json_decode($x['body'],true);
|
||||
|
||||
if(! is_array($j['item']) || ! count($j['item'])) {
|
||||
PConfig::Set($channel['channel_id'], 'import', 'content_completed', 1);
|
||||
return;
|
||||
}
|
||||
|
||||
$saved_notification_flags = notifications_off($channel['channel_id']);
|
||||
|
||||
import_items($channel,$j['item'],false,((array_key_exists('relocate',$j)) ? $j['relocate'] : null));
|
||||
|
||||
notifications_on($channel['channel_id'], $saved_notification_flags);
|
||||
|
||||
PConfig::Set($channel['channel_id'], 'import', 'content_progress', [
|
||||
'items_total' => $j['items_total'],
|
||||
'items_page' => $j['items_page'],
|
||||
'items_current_page' => count($j['item']),
|
||||
'last_page' => $page,
|
||||
'next_cmd' => ['Content_importer', sprintf('%d',$page + 1), $since, $until, $channel['channel_address'], urlencode($hz_server)]
|
||||
]);
|
||||
|
||||
$page++;
|
||||
|
||||
Master::Summon([ 'Content_importer', sprintf('%d',$page), $since, $until, $channel['channel_address'], urlencode($hz_server) ]);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,6 @@ class Cron {
|
||||
// run queue delivery process in the background
|
||||
|
||||
Master::Summon(array('Queue'));
|
||||
|
||||
Master::Summon(array('Poller'));
|
||||
|
||||
/**
|
||||
@@ -48,13 +47,7 @@ class Cron {
|
||||
db_quoteinterval('3 MINUTE')
|
||||
);
|
||||
|
||||
// expire any expired mail
|
||||
|
||||
q("delete from mail where expires > '%s' and expires < %s ",
|
||||
dbesc(NULL_DATE),
|
||||
db_utcnow()
|
||||
);
|
||||
|
||||
require_once('include/account.php');
|
||||
remove_expired_registrations();
|
||||
|
||||
$interval = get_config('system', 'delivery_interval', 3);
|
||||
@@ -164,11 +157,6 @@ class Cron {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// check if any connections transitioned to zot6 and upgrade the connections to zot6 at this hub if so.
|
||||
require_once('include/connections.php');
|
||||
z6trans_connections();
|
||||
|
||||
require_once('include/attach.php');
|
||||
attach_upgrade();
|
||||
|
||||
@@ -217,10 +205,9 @@ class Cron {
|
||||
|
||||
// pull in some public posts
|
||||
|
||||
/* $disable_discover_tab = get_config('system', 'disable_discover_tab') || get_config('system', 'disable_discover_tab') === false;
|
||||
$disable_discover_tab = get_config('system', 'disable_discover_tab') || get_config('system', 'disable_discover_tab') === false;
|
||||
if (!$disable_discover_tab)
|
||||
Master::Summon(array('Externals'));
|
||||
*/
|
||||
Master::Summon(['Externals']);
|
||||
|
||||
$restart = false;
|
||||
|
||||
|
||||
@@ -95,8 +95,6 @@ class Cron_daily {
|
||||
remove_obsolete_hublocs();
|
||||
remove_duplicate_singleton_hublocs();
|
||||
|
||||
z6_discover();
|
||||
|
||||
$date = datetime_convert();
|
||||
call_hooks('cron_daily', $date);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/queue_fn.php');
|
||||
use Zotlabs\Lib\Queue;
|
||||
|
||||
class Deliver {
|
||||
|
||||
@@ -23,7 +23,7 @@ class Deliver {
|
||||
);
|
||||
|
||||
if ($r) {
|
||||
queue_deliver($r[0], true);
|
||||
Queue::deliver($r[0], true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
25
Zotlabs/Daemon/Delxitems.php
Normal file
25
Zotlabs/Daemon/Delxitems.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/connections.php');
|
||||
|
||||
/*
|
||||
* Daemon to remove 'item' resources in the background from a removed connection
|
||||
*/
|
||||
|
||||
class Delxitems {
|
||||
|
||||
static public function run($argc, $argv) {
|
||||
|
||||
cli_startup();
|
||||
|
||||
if($argc != 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
remove_abook_items($argv[1], $argv[2]);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -49,8 +49,9 @@ class Directory {
|
||||
);
|
||||
|
||||
// Now update all the connections
|
||||
if ($pushall)
|
||||
if ($pushall) {
|
||||
Master::Summon(array('Notifier', 'refresh_all', $channel['channel_id']));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -74,7 +75,7 @@ class Directory {
|
||||
* the directory packet. That means we'll try again on the next poll run.
|
||||
*/
|
||||
|
||||
$hash = random_string();
|
||||
$hash = new_uuid();
|
||||
|
||||
Queue::insert(array(
|
||||
'hash' => $hash,
|
||||
@@ -93,8 +94,8 @@ class Directory {
|
||||
}
|
||||
|
||||
// Now update all the connections
|
||||
if ($pushall)
|
||||
if ($pushall) {
|
||||
Master::Summon(array('Notifier', 'refresh_all', $channel['channel_id']));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/items.php');
|
||||
|
||||
class Expire {
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
use Zotlabs\Lib\Activity;
|
||||
use Zotlabs\Lib\Libzot;
|
||||
use Zotlabs\Lib\ActivityStreams;
|
||||
use Zotlabs\Lib\ASCollection;
|
||||
|
||||
@@ -31,25 +32,55 @@ class Externals {
|
||||
$url = $arr['url'];
|
||||
}
|
||||
else {
|
||||
$networks = ['zot6'];
|
||||
|
||||
if (plugin_is_installed('pubcrawl')) {
|
||||
$networks[] = 'activitypub';
|
||||
}
|
||||
|
||||
stringify_array_elms($networks);
|
||||
$networks_str = implode(',', $networks);
|
||||
|
||||
$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 and site_project like '%s' and site_version > '5.3.1' order by $randfunc limit 1",
|
||||
//dbesc(z_root()),
|
||||
//intval(DIRECTORY_MODE_STANDALONE),
|
||||
//intval(SITE_TYPE_ZOT),
|
||||
//dbesc('hubzilla%')
|
||||
//);
|
||||
|
||||
$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 and site_project like '%s' and site_version > '5.3.1' order by $randfunc limit 1",
|
||||
$r = q("SELECT * FROM hubloc
|
||||
LEFT JOIN abook ON abook_xchan = hubloc_hash
|
||||
LEFT JOIN site ON site_url = hubloc_url WHERE
|
||||
hubloc_network IN ( $networks_str ) AND
|
||||
abook_xchan IS NULL AND
|
||||
hubloc_url != '%s' AND
|
||||
hubloc_updated > '%s' AND
|
||||
hubloc_primary = 1 AND hubloc_deleted = 0 AND
|
||||
site_dead = 0
|
||||
ORDER BY $randfunc LIMIT 1",
|
||||
dbesc(z_root()),
|
||||
intval(DIRECTORY_MODE_STANDALONE),
|
||||
intval(SITE_TYPE_ZOT),
|
||||
dbesc('hubzilla%')
|
||||
datetime_convert('UTC', 'UTC', 'now - 30 days')
|
||||
);
|
||||
if ($r)
|
||||
$url = $r[0]['site_url'];
|
||||
|
||||
$contact = $r[0];
|
||||
|
||||
if ($contact) {
|
||||
$url = $contact['hubloc_id_url'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!$url) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$blacklisted = false;
|
||||
|
||||
if (!check_siteallowed($url)) {
|
||||
if (!check_siteallowed($contact['hubloc_url'])) {
|
||||
logger('blacklisted site: ' . $url);
|
||||
$blacklisted = true;
|
||||
}
|
||||
@@ -59,123 +90,67 @@ class Externals {
|
||||
// make sure we can eventually break out if somebody blacklists all known sites
|
||||
|
||||
if ($blacklisted) {
|
||||
if ($attempts > 20)
|
||||
if ($attempts > 5)
|
||||
break;
|
||||
$attempts--;
|
||||
continue;
|
||||
}
|
||||
|
||||
$cl = Activity::get_actor_collections($contact['hubloc_hash']);
|
||||
if(empty($cl)) {
|
||||
$cl = get_xconfig($contact['hubloc_hash'], 'activitypub', 'collections');
|
||||
}
|
||||
|
||||
if (is_array($cl) && array_key_exists('outbox', $cl)) {
|
||||
$url = $cl['outbox'];
|
||||
}
|
||||
else {
|
||||
$url = str_replace('/channel/', '/outbox/', $contact['hubloc_id_url']);
|
||||
if ($url) {
|
||||
$url .= '?top=1';
|
||||
}
|
||||
}
|
||||
|
||||
if ($url) {
|
||||
logger('fetching outbox: ' . $url);
|
||||
|
||||
$max = intval(get_config('system', 'max_imported_posts', 30));
|
||||
if (intval($max)) {
|
||||
logger('externals: fetching outbox');
|
||||
$obj = new ASCollection($url, $importer, 0, 10);
|
||||
$messages = $obj->get();
|
||||
|
||||
$feed_url = $url . '/zotfeed';
|
||||
$obj = new ASCollection($feed_url, $importer, 0, $max);
|
||||
$messages = $obj->get();
|
||||
if ($messages) {
|
||||
foreach ($messages as $message) {
|
||||
if (is_string($message)) {
|
||||
$message = Activity::fetch($message, $importer);
|
||||
}
|
||||
|
||||
if ($messages) {
|
||||
foreach ($messages as $message) {
|
||||
if (is_string($message)) {
|
||||
$message = Activity::fetch($message, $importer);
|
||||
}
|
||||
$AS = new ActivityStreams($message);
|
||||
if ($AS->is_valid() && is_array($AS->obj)) {
|
||||
$item = Activity::decode_note($AS);
|
||||
Activity::store($importer, $importer['xchan_hash'], $AS, $item, true);
|
||||
$total++;
|
||||
if ($message['type'] !== 'Create') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($contact['hubloc_network'] === 'zot6') {
|
||||
// make sure we only fetch top level items
|
||||
if (isset($message['object']['inReplyTo'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$obj_id = $message['object']['id'] ?? $message['object'];
|
||||
|
||||
Libzot::fetch_conversation($importer, $obj_id);
|
||||
$total++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$AS = new ActivityStreams($message);
|
||||
if ($AS->is_valid() && is_array($AS->obj)) {
|
||||
$item = Activity::decode_note($AS);
|
||||
Activity::store($importer, $contact['abook_xchan'], $AS, $item);
|
||||
$total++;
|
||||
}
|
||||
}
|
||||
logger('externals: import_public_posts: ' . $total . ' messages imported', LOGGER_DEBUG);
|
||||
}
|
||||
logger('fetched messages count: ' . $total);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
/* $total = 0;
|
||||
$attempts = 0;
|
||||
|
||||
logger('externals: startup', LOGGER_DEBUG);
|
||||
|
||||
// pull in some public posts
|
||||
|
||||
while ($total == 0 && $attempts < 3) {
|
||||
$arr = ['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'] = '';
|
||||
process_delivery(['hash' => 'undefined'], get_item_elements($message),
|
||||
[['hash' => $sys['xchan_hash']]], false, true);
|
||||
$total++;
|
||||
}
|
||||
logger('externals: import_public_posts: ' . $total . ' messages imported', LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
71
Zotlabs/Daemon/File_importer.php
Normal file
71
Zotlabs/Daemon/File_importer.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
use Zotlabs\Web\HTTPSig;
|
||||
use Zotlabs\Lib\PConfig;
|
||||
|
||||
|
||||
require_once('include/cli_startup.php');
|
||||
require_once('include/attach.php');
|
||||
require_once('include/import.php');
|
||||
|
||||
class File_importer {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
cli_startup();
|
||||
|
||||
$page = $argv[1];
|
||||
$channel_address = $argv[2];
|
||||
$hz_server = urldecode($argv[3]);
|
||||
|
||||
$m = parse_url($hz_server);
|
||||
|
||||
$channel = channelx_by_nick($channel_address);
|
||||
if(! $channel) {
|
||||
logger('channel not found');
|
||||
return;
|
||||
}
|
||||
|
||||
$headers = [
|
||||
'X-API-Token' => random_string(),
|
||||
'X-API-Request' => $hz_server . '/api/z/1.0/file/export_page?f=records=1&page=' . $page,
|
||||
'Host' => $m['host'],
|
||||
'(request-target)' => 'get /api/z/1.0/file/export_page?f=records=1&page=' . $page,
|
||||
];
|
||||
|
||||
$headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),true,'sha512');
|
||||
|
||||
// TODO: implement total count
|
||||
$x = z_fetch_url($hz_server . '/api/z/1.0/file/export_page?f=records=1&page=' . $page, false, $redirects, [ 'headers' => $headers ]);
|
||||
// logger('file fetch: ' . print_r($x,true));
|
||||
|
||||
if(! $x['success']) {
|
||||
logger('no API response',LOGGER_DEBUG);
|
||||
killme();
|
||||
}
|
||||
|
||||
$j = json_decode($x['body'],true);
|
||||
|
||||
if(! is_array($j['results'][0]['attach']) || ! count($j['results'][0]['attach'])) {
|
||||
PConfig::Set($channel['channel_id'], 'import', 'files_completed', 1);
|
||||
return;
|
||||
}
|
||||
|
||||
$r = sync_files($channel, $j['results']);
|
||||
|
||||
PConfig::Set($channel['channel_id'], 'import', 'files_progress', [
|
||||
'files_total' => $j['total'],
|
||||
'files_page' => 1, // export page atm returns just one file
|
||||
'last_page' => $page,
|
||||
'next_cmd' => ['File_importer',sprintf('%d',$page + 1), $channel['channel_address'], urlencode($hz_server)]
|
||||
]);
|
||||
|
||||
$page++;
|
||||
|
||||
Master::Summon([ 'File_importer',sprintf('%d',$page), $channel['channel_address'], urlencode($hz_server) ]);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -15,21 +15,32 @@ class Gprobe {
|
||||
return;
|
||||
|
||||
$url = hex2bin($argv[1]);
|
||||
$is_webbie = false;
|
||||
$r = null;
|
||||
|
||||
if (!strpos($url, '@'))
|
||||
return;
|
||||
if (filter_var($url, FILTER_VALIDATE_EMAIL)) {
|
||||
$is_webbie = true;
|
||||
|
||||
$r = q("select * from hubloc where hubloc_addr = '%s' and hubloc_network = 'zot6' limit 1",
|
||||
dbesc($url)
|
||||
);
|
||||
$r = q("select * from hubloc where hubloc_addr = '%s' and hubloc_network = 'zot6' limit 1",
|
||||
dbesc($url)
|
||||
);
|
||||
}
|
||||
elseif (filter_var($url, FILTER_VALIDATE_URL)) {
|
||||
$r = q("select * from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
|
||||
dbesc($url)
|
||||
);
|
||||
}
|
||||
|
||||
if (!$r) {
|
||||
$href = Webfinger::zot_url(punify($url));
|
||||
if ($href) {
|
||||
$zf = Zotfinger::exec($href, null);
|
||||
if ($is_webbie) {
|
||||
$url = Webfinger::zot_url(punify($url));
|
||||
}
|
||||
if (is_array($zf) && array_path_exists('signature/signer', $zf) && $zf['signature']['signer'] === $href && intval($zf['signature']['header_valid'])) {
|
||||
Libzot::import_xchan($zf['data']);
|
||||
|
||||
if ($url) {
|
||||
$zf = Zotfinger::exec($url, null);
|
||||
if (is_array($zf) && array_path_exists('signature/signer', $zf) && $zf['signature']['signer'] === $url && intval($zf['signature']['header_valid'])) {
|
||||
Libzot::import_xchan($zf['data']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,10 +5,6 @@ namespace Zotlabs\Daemon;
|
||||
use Zotlabs\Lib\Libzot;
|
||||
use Zotlabs\Lib\Libzotdir;
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/dir_fns.php');
|
||||
|
||||
|
||||
class Onedirsync {
|
||||
|
||||
static public function run($argc, $argv) {
|
||||
@@ -29,6 +25,7 @@ class Onedirsync {
|
||||
|
||||
if (!$r)
|
||||
return;
|
||||
|
||||
if (($r[0]['ud_flags'] & UPDATE_FLAGS_UPDATED) || (!$r[0]['ud_addr']))
|
||||
return;
|
||||
|
||||
@@ -54,25 +51,24 @@ class Onedirsync {
|
||||
// ignore doing an update if this ud_addr refers to a known dead hubloc
|
||||
|
||||
$h = q("select * from hubloc where hubloc_addr = '%s'",
|
||||
dbesc($r[0]['ud_addr'])
|
||||
dbesc($r[0]['ud_addr']),
|
||||
);
|
||||
|
||||
$h = Libzot::zot_record_preferred($h);
|
||||
|
||||
if (($h) && ($h['hubloc_status'] & HUBLOC_OFFLINE)) {
|
||||
if (($h) && (($h['hubloc_status'] & HUBLOC_OFFLINE) || $h['hubloc_deleted'] || $h['hubloc_error'])) {
|
||||
q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 ",
|
||||
intval(UPDATE_FLAGS_UPDATED),
|
||||
intval(UPDATE_FLAGS_DELETED),
|
||||
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 && !in_array($h['hubloc_network'], ['zot6', 'zot']))
|
||||
if ($h && $h['hubloc_network'] !== 'zot6')
|
||||
return;
|
||||
|
||||
Libzotdir::update_directory_entry($r[0]);
|
||||
|
||||
@@ -8,6 +8,7 @@ use Zotlabs\Lib\ASCollection;
|
||||
use Zotlabs\Lib\Libzot;
|
||||
|
||||
require_once('include/socgraph.php');
|
||||
require_once('include/feedutils.php');
|
||||
|
||||
class Onepoll {
|
||||
|
||||
@@ -44,19 +45,16 @@ class Onepoll {
|
||||
return;
|
||||
}
|
||||
|
||||
$contact = array_shift($contacts);
|
||||
$contact = $contacts[0];
|
||||
|
||||
$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)
|
||||
);
|
||||
$importer = channelx_by_n($importer_uid);
|
||||
|
||||
if (!$r)
|
||||
if (!$importer)
|
||||
return;
|
||||
|
||||
$importer = $r[0];
|
||||
|
||||
logger("onepoll: poll: ({$contact['id']}) IMPORTER: {$importer['xchan_name']}, CONTACT: {$contact['xchan_name']}");
|
||||
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')
|
||||
@@ -75,16 +73,12 @@ class Onepoll {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!in_array($contact['xchan_network'], ['zot', 'zot6']))
|
||||
if ($contact['xchan_network'] !== 'zot6')
|
||||
return;
|
||||
|
||||
// update permissions
|
||||
|
||||
if ($contact['xchan_network'] === 'zot6')
|
||||
$x = Libzot::refresh($contact, $importer);
|
||||
|
||||
if ($contact['xchan_network'] === 'zot')
|
||||
$x = zot_refresh($contact, $importer);
|
||||
$x = Libzot::refresh($contact, $importer);
|
||||
|
||||
$responded = false;
|
||||
$updated = datetime_convert();
|
||||
@@ -109,46 +103,63 @@ class Onepoll {
|
||||
return;
|
||||
|
||||
$fetch_feed = true;
|
||||
$x = null;
|
||||
|
||||
// They haven't given us permission to see their stream
|
||||
|
||||
$can_view_stream = intval(get_abconfig($importer_uid, $contact['abook_xchan'], 'their_perms', 'view_stream'));
|
||||
|
||||
if (!$can_view_stream)
|
||||
if (!$can_view_stream) {
|
||||
$fetch_feed = false;
|
||||
}
|
||||
|
||||
// we haven't given them permission to send us their stream
|
||||
|
||||
$can_send_stream = intval(get_abconfig($importer_uid, $contact['abook_xchan'], 'my_perms', 'send_stream'));
|
||||
|
||||
if (!$can_send_stream)
|
||||
if (!$can_send_stream) {
|
||||
$fetch_feed = false;
|
||||
}
|
||||
|
||||
if ($fetch_feed && $contact['xchan_network'] !== 'zot') {
|
||||
if ($fetch_feed) {
|
||||
|
||||
$max = intval(get_config('system', 'max_imported_posts', 30));
|
||||
|
||||
if (intval($max)) {
|
||||
$cl = get_xconfig($contact['abook_xchan'], 'activitypub', 'collections');
|
||||
$cl = Activity::get_actor_collections($contact['abook_xchan']);
|
||||
if(empty($cl)) {
|
||||
$cl = get_xconfig($contact['abook_xchan'], 'activitypub', 'collections');
|
||||
}
|
||||
|
||||
if (is_array($cl) && $cl) {
|
||||
$url = ((array_key_exists('outbox', $cl)) ? $cl['outbox'] : '');
|
||||
if (is_array($cl) && array_key_exists('outbox', $cl)) {
|
||||
$url = $cl['outbox'];
|
||||
}
|
||||
else {
|
||||
$url = str_replace('/poco/', '/zotfeed/', $contact['xchan_connurl']);
|
||||
$url = str_replace('/poco/', '/outbox/', $contact['xchan_connurl']);
|
||||
}
|
||||
|
||||
if ($url) {
|
||||
logger('fetching outbox');
|
||||
$url = $url . '?date_begin=' . urlencode($last_update);
|
||||
$url = $url . '?date_begin=' . urlencode($last_update);
|
||||
|
||||
if($contact['xchan_network'] === 'zot6') {
|
||||
$url = $url . '&top=1';
|
||||
}
|
||||
|
||||
$obj = new ASCollection($url, $importer, 0, $max);
|
||||
$messages = $obj->get();
|
||||
|
||||
if ($messages) {
|
||||
foreach ($messages as $message) {
|
||||
if (is_string($message)) {
|
||||
$message = Activity::fetch($message, $importer);
|
||||
}
|
||||
|
||||
if ($contact['xchan_network'] === 'zot6') {
|
||||
// make sure we only fetch top level items
|
||||
if ($message['type'] === 'Create' && !isset($message['object']['inReplyTo'])) {
|
||||
Libzot::fetch_conversation($importer, $message['object']['id']);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$AS = new ActivityStreams($message);
|
||||
if ($AS->is_valid() && is_array($AS->obj)) {
|
||||
$item = Activity::decode_note($AS);
|
||||
@@ -163,8 +174,10 @@ class Onepoll {
|
||||
// update the poco details for this connection
|
||||
$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')
|
||||
db_utcnow(),
|
||||
db_quoteinterval('1 DAY')
|
||||
);
|
||||
|
||||
if (!$r) {
|
||||
poco_load($contact['xchan_hash'], $contact['xchan_connurl']);
|
||||
}
|
||||
|
||||
@@ -69,11 +69,11 @@ class Poller {
|
||||
abook.abook_channel, abook.abook_id, abook.abook_archived, abook.abook_pending,
|
||||
abook.abook_ignored, abook.abook_blocked,
|
||||
xchan.xchan_network,
|
||||
account.account_lastlog, account.account_flags
|
||||
FROM abook LEFT JOIN xchan on abook_xchan = xchan_hash
|
||||
account.account_lastlog, account.account_flags
|
||||
FROM abook LEFT JOIN xchan on abook_xchan = xchan_hash
|
||||
LEFT JOIN account on abook_account = account_id
|
||||
where abook_self = 0
|
||||
$sql_extra
|
||||
$sql_extra
|
||||
AND (( account_flags = %d ) OR ( account_flags = %d )) $abandon_sql ORDER BY $randfunc",
|
||||
intval(ACCOUNT_OK),
|
||||
intval(ACCOUNT_UNVERIFIED) // FIXME
|
||||
@@ -102,8 +102,7 @@ class Poller {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (!in_array($contact['xchan_network'], ['zot', 'zot6']))
|
||||
if ($contact['xchan_network'] !== 'zot6')
|
||||
continue;
|
||||
|
||||
if ($c == $t) {
|
||||
@@ -191,7 +190,7 @@ class Poller {
|
||||
|
||||
set_config('system', 'lastpoll', datetime_convert());
|
||||
|
||||
//All done - clear the lockfile
|
||||
//All done - clear the lockfile
|
||||
|
||||
@unlink($lockfile);
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/queue_fn.php');
|
||||
require_once('include/zot.php');
|
||||
use Zotlabs\Lib\Queue as LibQueue;
|
||||
|
||||
class Queue {
|
||||
|
||||
@@ -48,17 +47,17 @@ class Queue {
|
||||
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
|
||||
// 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
|
||||
// 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.
|
||||
// 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.
|
||||
|
||||
$sqlrandfunc = db_getfunc('rand');
|
||||
|
||||
@@ -67,7 +66,7 @@ class Queue {
|
||||
);
|
||||
while ($r) {
|
||||
foreach ($r as $rv) {
|
||||
queue_deliver($rv);
|
||||
LibQueue::deliver($rv);
|
||||
}
|
||||
$r = q("SELECT *,$sqlrandfunc as rn FROM outq WHERE outq_delivered = 0 and outq_scheduled < %s order by rn limit 1",
|
||||
db_utcnow()
|
||||
@@ -78,7 +77,7 @@ class Queue {
|
||||
return;
|
||||
|
||||
foreach ($r as $rv) {
|
||||
queue_deliver($rv);
|
||||
LibQueue::deliver($rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/queue_fn.php');
|
||||
|
||||
|
||||
class Ratenotif {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
|
||||
// Deprecated
|
||||
return;
|
||||
|
||||
|
||||
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)
|
||||
));
|
||||
|
||||
|
||||
$x = q("select count(outq_hash) as total from outq where outq_delivered = 0");
|
||||
if(intval($x[0]['total']) > intval(get_config('system','force_queue_threshold',300))) {
|
||||
logger('immediate delivery deferred.', LOGGER_DEBUG, LOG_INFO);
|
||||
update_queue_item($hash);
|
||||
continue;
|
||||
}
|
||||
|
||||
$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;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,6 @@ class Thumbnail {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$default_controller = null;
|
||||
|
||||
$files = glob('Zotlabs/Thumbs/*.php');
|
||||
|
||||
@@ -24,6 +24,8 @@ class ASCollection {
|
||||
$this->direction = $direction;
|
||||
$this->limit = $limit;
|
||||
|
||||
$data = null;
|
||||
|
||||
if (is_array($obj)) {
|
||||
$data = $obj;
|
||||
}
|
||||
@@ -147,4 +149,4 @@ class ASCollection {
|
||||
}
|
||||
logger('nextpage: ' . $this->nextpage, LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,17 @@ namespace Zotlabs\Lib;
|
||||
class AbConfig {
|
||||
|
||||
static public function Load($chan,$xhash,$family = '') {
|
||||
if($family)
|
||||
$where = '';
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -21,7 +26,7 @@ class AbConfig {
|
||||
intval($chan),
|
||||
dbesc($xhash),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
dbesc($key)
|
||||
);
|
||||
if($r) {
|
||||
return ((preg_match('|^a:[0-9]+:{.*}$|s', $r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']);
|
||||
@@ -41,19 +46,19 @@ class AbConfig {
|
||||
dbesc($xhash),
|
||||
dbesc($family),
|
||||
dbesc($key),
|
||||
dbesc($dbvalue)
|
||||
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($dbvalue),
|
||||
dbesc($chan),
|
||||
dbesc($xhash),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if($r)
|
||||
return $value;
|
||||
return false;
|
||||
|
||||
@@ -1,38 +1,37 @@
|
||||
<?php
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use Zotlabs\Lib\Libsync;
|
||||
|
||||
|
||||
class AccessList {
|
||||
|
||||
static function add($uid,$name,$public = 0) {
|
||||
|
||||
$ret = false;
|
||||
static function add($uid, $name, $public = 0) {
|
||||
|
||||
$ret = false;
|
||||
$hash = '';
|
||||
if ($uid && $name) {
|
||||
$r = self::byname($uid,$name); // check for dups
|
||||
$r = self::by_name($uid, $name); // check for dups
|
||||
if ($r !== false) {
|
||||
|
||||
// This could be a problem.
|
||||
// This could be a problem.
|
||||
// Let's assume we've just created a list which we once deleted
|
||||
// all the old members are gone, but the list remains so we don't break any security
|
||||
// access lists. What we're doing here is reviving the dead list, but old content which
|
||||
// was restricted to this list may now be seen by the new list members.
|
||||
// was restricted to this list may now be seen by the new list members.
|
||||
|
||||
$z = q("SELECT * FROM pgrp WHERE id = %d LIMIT 1",
|
||||
intval($r)
|
||||
);
|
||||
if(($z) && $z[0]['deleted']) {
|
||||
if (($z) && $z[0]['deleted']) {
|
||||
q('UPDATE pgrp SET deleted = 0 WHERE id = %d', intval($z[0]['id']));
|
||||
notice( t('A deleted list with this name was revived. Existing item permissions <strong>may</strong> apply to this list and any future members. If this is not what you intended, please create another list with a different name.') . EOL);
|
||||
notice(t('A deleted privacy group with this name was revived. Existing item permissions <strong>may</strong> apply to this privacy group and any future members. If this is not what you intended, please create another privacy group with a different name.') . EOL);
|
||||
}
|
||||
return true;
|
||||
$hash = self::by_id($uid, $r);
|
||||
return $hash;
|
||||
}
|
||||
|
||||
$hash = new_uuid();
|
||||
|
||||
$r = q("INSERT INTO pgrp ( hash, uid, visible, gname )
|
||||
$r = q("INSERT INTO pgrp ( hash, uid, visible, gname )
|
||||
VALUES( '%s', %d, %d, '%s' ) ",
|
||||
dbesc($hash),
|
||||
intval($uid),
|
||||
@@ -42,12 +41,12 @@ class AccessList {
|
||||
$ret = $r;
|
||||
}
|
||||
|
||||
Libsync::build_sync_packet($uid,null,true);
|
||||
return $ret;
|
||||
Libsync::build_sync_packet($uid, null, true);
|
||||
|
||||
return (($ret) ? $hash : $ret);
|
||||
}
|
||||
|
||||
|
||||
static function remove($uid,$name) {
|
||||
static function remove($uid, $name) {
|
||||
$ret = false;
|
||||
if ($uid && $name) {
|
||||
$r = q("SELECT id, hash FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1",
|
||||
@@ -55,36 +54,36 @@ class AccessList {
|
||||
dbesc($name)
|
||||
);
|
||||
if ($r) {
|
||||
$group_id = $r[0]['id'];
|
||||
$group_id = $r[0]['id'];
|
||||
$group_hash = $r[0]['hash'];
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// remove group from default posting lists
|
||||
$r = q("SELECT channel_default_group, channel_allow_gid, channel_deny_gid FROM channel WHERE channel_id = %d LIMIT 1",
|
||||
intval($uid)
|
||||
intval($uid)
|
||||
);
|
||||
if ($r) {
|
||||
$user_info = array_shift($r);
|
||||
$change = false;
|
||||
$change = false;
|
||||
|
||||
if ($user_info['channel_default_group'] == $group_hash) {
|
||||
$user_info['channel_default_group'] = '';
|
||||
$change = true;
|
||||
$change = true;
|
||||
}
|
||||
if (strpos($user_info['channel_allow_gid'], '<' . $group_hash . '>') !== false) {
|
||||
$user_info['channel_allow_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_allow_gid']);
|
||||
$change = true;
|
||||
$change = true;
|
||||
}
|
||||
if (strpos($user_info['channel_deny_gid'], '<' . $group_hash . '>') !== false) {
|
||||
$user_info['channel_deny_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_deny_gid']);
|
||||
$change = true;
|
||||
$change = true;
|
||||
}
|
||||
|
||||
if ($change) {
|
||||
q("UPDATE channel SET channel_default_group = '%s', channel_allow_gid = '%s', channel_deny_gid = '%s'
|
||||
q("UPDATE channel SET channel_default_group = '%s', channel_allow_gid = '%s', channel_deny_gid = '%s'
|
||||
WHERE channel_id = %d",
|
||||
intval($user_info['channel_default_group']),
|
||||
dbesc($user_info['channel_allow_gid']),
|
||||
@@ -110,16 +109,16 @@ class AccessList {
|
||||
|
||||
}
|
||||
|
||||
Libsync::build_sync_packet($uid,null,true);
|
||||
Libsync::build_sync_packet($uid, null, true);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// returns the integer id of an access group owned by $uid and named $name
|
||||
// or false.
|
||||
|
||||
static function byname($uid,$name) {
|
||||
if (! ($uid && $name)) {
|
||||
|
||||
static function by_name($uid, $name) {
|
||||
if (!($uid && $name)) {
|
||||
return false;
|
||||
}
|
||||
$r = q("SELECT id FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1",
|
||||
@@ -132,11 +131,11 @@ class AccessList {
|
||||
return false;
|
||||
}
|
||||
|
||||
static function by_id($uid,$id) {
|
||||
if (! ($uid && $id)) {
|
||||
static function by_id($uid, $id) {
|
||||
if (!($uid && $id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$r = q("SELECT * FROM pgrp WHERE uid = %d AND id = %d and deleted = 0",
|
||||
intval($uid),
|
||||
intval($id)
|
||||
@@ -147,10 +146,8 @@ class AccessList {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static function rec_byhash($uid,$hash) {
|
||||
if (! ( $uid && $hash)) {
|
||||
static function by_hash($uid, $hash) {
|
||||
if (!($uid && $hash)) {
|
||||
return false;
|
||||
}
|
||||
$r = q("SELECT * FROM pgrp WHERE uid = %d AND hash = '%s' LIMIT 1",
|
||||
@@ -163,46 +160,46 @@ class AccessList {
|
||||
return false;
|
||||
}
|
||||
|
||||
static function member_remove($uid, $name, $member, $gid = 0) {
|
||||
if (!$gid) {
|
||||
$gid = self::by_name($uid, $name);
|
||||
}
|
||||
|
||||
static function member_remove($uid,$name,$member) {
|
||||
$gid = self::byname($uid,$name);
|
||||
if (! $gid) {
|
||||
return false;
|
||||
}
|
||||
if (! ($uid && $gid && $member)) {
|
||||
if (!($uid && $gid && $member)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$r = q("DELETE FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' ",
|
||||
intval($uid),
|
||||
intval($gid),
|
||||
dbesc($member)
|
||||
);
|
||||
|
||||
Libsync::build_sync_packet($uid,null,true);
|
||||
Libsync::build_sync_packet($uid, null, true);
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
static function member_add($uid,$name,$member,$gid = 0) {
|
||||
if (! $gid) {
|
||||
$gid = self::byname($uid,$name);
|
||||
static function member_add($uid, $name, $member, $gid = 0) {
|
||||
if (!$gid) {
|
||||
$gid = self::by_name($uid, $name);
|
||||
}
|
||||
if (! ($gid && $uid && $member)) {
|
||||
if (!($gid && $uid && $member)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' LIMIT 1",
|
||||
$r = q("SELECT * FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' LIMIT 1",
|
||||
intval($uid),
|
||||
intval($gid),
|
||||
dbesc($member)
|
||||
);
|
||||
if ($r) {
|
||||
return true; // You might question this, but
|
||||
// we indicate success because the group member was in fact created
|
||||
// -- It was just created at another time
|
||||
return true;
|
||||
// You might question this, but
|
||||
// we indicate success because the group member was in fact created
|
||||
// -- It was just created at another time
|
||||
}
|
||||
else {
|
||||
else {
|
||||
$r = q("INSERT INTO pgrp_member (uid, gid, xchan)
|
||||
VALUES( %d, %d, '%s' ) ",
|
||||
intval($uid),
|
||||
@@ -210,15 +207,14 @@ class AccessList {
|
||||
dbesc($member)
|
||||
);
|
||||
}
|
||||
Libsync::build_sync_packet($uid,null,true);
|
||||
Libsync::build_sync_packet($uid, null, true);
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
static function members($uid, $gid) {
|
||||
$ret = [];
|
||||
if (intval($gid)) {
|
||||
$r = q("SELECT * FROM pgrp_member
|
||||
$r = q("SELECT * FROM pgrp_member
|
||||
LEFT JOIN abook ON abook_xchan = pgrp_member.xchan left join xchan on xchan_hash = abook_xchan
|
||||
WHERE gid = %d AND abook_channel = %d and pgrp_member.uid = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 ORDER BY xchan_name ASC ",
|
||||
intval($gid),
|
||||
@@ -232,7 +228,7 @@ class AccessList {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
static function members_xchan($uid,$gid) {
|
||||
static function members_xchan($uid, $gid) {
|
||||
$ret = [];
|
||||
if (intval($gid)) {
|
||||
$r = q("SELECT xchan FROM pgrp_member WHERE gid = %d AND uid = %d",
|
||||
@@ -248,99 +244,75 @@ class AccessList {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
static function members_profile_xchan($uid,$gid) {
|
||||
static function profile_members_xchan($uid,$gid) {
|
||||
$ret = [];
|
||||
if (intval($gid)) {
|
||||
|
||||
if(intval($gid)) {
|
||||
$r = q("SELECT abook_xchan as xchan from abook left join profile on abook_profile = profile_guid where profile.id = %d and profile.uid = %d",
|
||||
intval($gid),
|
||||
intval($uid)
|
||||
);
|
||||
if ($r) {
|
||||
foreach($r as $rv) {
|
||||
$ret[] = $rv['xchan'];
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$ret[] = $rr['xchan'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
static function select($uid, $options) {
|
||||
|
||||
$selected = $options['selected'] ?? '';
|
||||
$form_id = $options['form_id'] ?? 'accesslist_select';
|
||||
$label = $options['label'] ?? t('Select a privacy group');
|
||||
$before = $options['before'] ?? [];
|
||||
$after = $options['after'] ?? [];
|
||||
|
||||
|
||||
static function select($uid,$group = '') {
|
||||
|
||||
$grps = [];
|
||||
$o = '';
|
||||
|
||||
$grps[] = [
|
||||
'name' => '',
|
||||
'id' => '0',
|
||||
'selected' => false
|
||||
];
|
||||
|
||||
if ($before) {
|
||||
$grps[] = $before;
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
|
||||
intval($uid)
|
||||
);
|
||||
$grps[] = [ 'name' => '', 'hash' => '0', 'selected' => '' ];
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
$grps[] = [ 'name' => $rr['gname'], 'id' => $rr['hash'], 'selected' => (($group == $rr['hash']) ? 'true' : '') ];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return replace_macros(get_markup_template('group_selection.tpl'), [
|
||||
'$label' => t('Add new connections to this access list'),
|
||||
'$groups' => $grps
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
static function widget($every="connections",$each="lists",$edit = false, $group_id = 0, $cid = '',$mode = 1) {
|
||||
|
||||
$o = '';
|
||||
|
||||
$groups = [];
|
||||
|
||||
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
|
||||
intval($_SESSION['uid'])
|
||||
);
|
||||
$member_of = [];
|
||||
if ($cid) {
|
||||
$member_of = self::containing(local_channel(),$cid);
|
||||
}
|
||||
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
$selected = (($group_id == $rr['id']) ? ' group-selected' : '');
|
||||
|
||||
if ($edit) {
|
||||
$groupedit = [ 'href' => "lists/".$rr['id'], 'title' => t('edit') ];
|
||||
}
|
||||
else {
|
||||
$groupedit = null;
|
||||
}
|
||||
|
||||
$groups[] = [
|
||||
'id' => $rr['id'],
|
||||
'enc_cid' => base64url_encode($cid),
|
||||
'cid' => $cid,
|
||||
'text' => $rr['gname'],
|
||||
'selected' => $selected,
|
||||
'href' => (($mode == 0) ? $each.'?f=&gid='.$rr['id'] : $each."/".$rr['id']) . ((x($_GET,'new')) ? '&new=' . $_GET['new'] : '') . ((x($_GET,'order')) ? '&order=' . $_GET['order'] : ''),
|
||||
'edit' => $groupedit,
|
||||
'ismember' => in_array($rr['id'],$member_of),
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$grps[] = [
|
||||
'name' => $rr['gname'],
|
||||
'id' => $rr['hash'],
|
||||
'selected' => ($selected == $rr['hash'])
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return replace_macros(get_markup_template('group_side.tpl'), [
|
||||
'$title' => t('Lists'),
|
||||
'$edittext' => t('Edit list'),
|
||||
'$createtext' => t('Create new list'),
|
||||
'$ungrouped' => (($every === 'contacts') ? t('Channels not in any access list') : ''),
|
||||
'$groups' => $groups,
|
||||
'$add' => t('add'),
|
||||
]);
|
||||
|
||||
if ($after) {
|
||||
$grps[] = $after;
|
||||
}
|
||||
|
||||
logger('select: ' . print_r($grps,true), LOGGER_DATA);
|
||||
|
||||
$o = replace_macros(get_markup_template('group_selection.tpl'), array(
|
||||
'$label' => $label,
|
||||
'$form_id' => $form_id,
|
||||
'$groups' => $grps
|
||||
));
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
static function expand($g) {
|
||||
if (! (is_array($g) && count($g))) {
|
||||
if (!(is_array($g) && count($g))) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -350,8 +322,8 @@ class AccessList {
|
||||
// private profile linked virtual groups
|
||||
|
||||
foreach ($g as $gv) {
|
||||
if (substr($gv,0,3) === 'vp.') {
|
||||
$profile_hash = substr($gv,3);
|
||||
if (substr($gv, 0, 3) === 'vp.') {
|
||||
$profile_hash = substr($gv, 3);
|
||||
if ($profile_hash) {
|
||||
$r = q("select abook_xchan from abook where abook_profile = '%s'",
|
||||
dbesc($profile_hash)
|
||||
@@ -366,10 +338,10 @@ class AccessList {
|
||||
else {
|
||||
$x[] = $gv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($x) {
|
||||
stringify_array_elms($x,true);
|
||||
stringify_array_elms($x, true);
|
||||
$groups = implode(',', $x);
|
||||
if ($groups) {
|
||||
$r = q("SELECT xchan FROM pgrp_member WHERE gid IN ( select id from pgrp where hash in ( $groups ))");
|
||||
@@ -383,9 +355,8 @@ class AccessList {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
static function member_of($c) {
|
||||
$r = q("SELECT pgrp.gname, pgrp.id FROM pgrp LEFT JOIN pgrp_member ON pgrp_member.gid = pgrp.id
|
||||
$r = q("SELECT pgrp.gname, pgrp.id FROM pgrp LEFT JOIN pgrp_member ON pgrp_member.gid = pgrp.id
|
||||
WHERE pgrp_member.xchan = '%s' AND pgrp.deleted = 0 ORDER BY pgrp.gname ASC ",
|
||||
dbesc($c)
|
||||
);
|
||||
@@ -393,7 +364,7 @@ class AccessList {
|
||||
return $r;
|
||||
}
|
||||
|
||||
static function containing($uid,$c) {
|
||||
static function containing($uid, $c) {
|
||||
|
||||
$r = q("SELECT gid FROM pgrp_member WHERE uid = %d AND pgrp_member.xchan = '%s' ",
|
||||
intval($uid),
|
||||
@@ -405,7 +376,8 @@ class AccessList {
|
||||
foreach ($r as $rv)
|
||||
$ret[] = $rv['gid'];
|
||||
}
|
||||
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,7 @@ class ActivityStreams {
|
||||
|
||||
public $raw = null;
|
||||
public $data = null;
|
||||
public $meta = null;
|
||||
public $valid = false;
|
||||
public $deleted = false;
|
||||
public $id = '';
|
||||
@@ -36,10 +37,14 @@ class ActivityStreams {
|
||||
*/
|
||||
function __construct($string) {
|
||||
|
||||
if(!$string)
|
||||
return;
|
||||
|
||||
$this->raw = $string;
|
||||
|
||||
if (is_array($string)) {
|
||||
$this->data = $string;
|
||||
$this->raw = json_encode($string, JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
else {
|
||||
$this->data = json_decode($string, true);
|
||||
@@ -56,18 +61,21 @@ class ActivityStreams {
|
||||
if ($ret['signer']) {
|
||||
$saved = json_encode($this->data, JSON_UNESCAPED_SLASHES);
|
||||
$this->data = $tmp;
|
||||
$this->data['signer'] = $ret['signer'];
|
||||
$this->data['signed_data'] = $saved;
|
||||
$this->meta['signer'] = $ret['signer'];
|
||||
$this->meta['signed_data'] = $saved;
|
||||
if ($ret['hubloc']) {
|
||||
$this->data['hubloc'] = $ret['hubloc'];
|
||||
$this->meta['hubloc'] = $ret['hubloc'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This indicates only that we have sucessfully decoded JSON.
|
||||
$this->valid = true;
|
||||
|
||||
if (array_key_exists('type', $this->data) && array_key_exists('actor', $this->data) && array_key_exists('object', $this->data)) {
|
||||
// Special handling for Mastodon "delete actor" activities which will often fail to verify
|
||||
// because the key cannot be fetched. We will catch this condition elsewhere.
|
||||
if (is_array($this->data) && array_key_exists('type', $this->data) && array_key_exists('actor', $this->data) && array_key_exists('object', $this->data)) {
|
||||
if ($this->data['type'] === 'Delete' && $this->data['actor'] === $this->data['object']) {
|
||||
$this->deleted = $this->data['actor'];
|
||||
$this->valid = false;
|
||||
@@ -76,6 +84,7 @@ class ActivityStreams {
|
||||
|
||||
}
|
||||
|
||||
// Attempt to assemble an Activity from what we were given.
|
||||
if ($this->is_valid()) {
|
||||
$this->id = $this->get_property_obj('id');
|
||||
$this->type = $this->get_primary_type();
|
||||
@@ -87,7 +96,7 @@ class ActivityStreams {
|
||||
|
||||
$this->ldsig = $this->get_compound_property('signature');
|
||||
if ($this->ldsig) {
|
||||
$this->signer = $this->get_compound_property('creator', $this->ldsig);
|
||||
$this->signer = $this->get_actor('creator', $this->ldsig);
|
||||
if ($this->signer && is_array($this->signer) && array_key_exists('publicKey', $this->signer) && is_array($this->signer['publicKey']) && $this->signer['publicKey']['publicKeyPem']) {
|
||||
$this->sigok = LDSignatures::verify($this->data, $this->signer['publicKey']['publicKeyPem']);
|
||||
}
|
||||
@@ -107,17 +116,17 @@ class ActivityStreams {
|
||||
$this->obj['object'] = $this->get_compound_property($this->obj['object']);
|
||||
}
|
||||
|
||||
if ($this->obj && is_array($this->obj) && $this->obj['actor'])
|
||||
if ($this->obj && is_array($this->obj) && isset($this->obj['actor']))
|
||||
$this->obj['actor'] = $this->get_actor('actor', $this->obj);
|
||||
if ($this->tgt && is_array($this->tgt) && $this->tgt['actor'])
|
||||
if ($this->tgt && is_array($this->tgt) && isset($this->tgt['actor']))
|
||||
$this->tgt['actor'] = $this->get_actor('actor', $this->tgt);
|
||||
|
||||
$this->parent_id = $this->get_property_obj('inReplyTo');
|
||||
|
||||
if ((!$this->parent_id) && is_array($this->obj)) {
|
||||
if ((!$this->parent_id) && is_array($this->obj) && isset($this->obj['inReplyTo'])) {
|
||||
$this->parent_id = $this->obj['inReplyTo'];
|
||||
}
|
||||
if ((!$this->parent_id) && is_array($this->obj)) {
|
||||
if ((!$this->parent_id) && is_array($this->obj) && isset($this->obj['id'])) {
|
||||
$this->parent_id = $this->obj['id'];
|
||||
}
|
||||
}
|
||||
@@ -299,28 +308,25 @@ class ActivityStreams {
|
||||
|
||||
function get_actor($property, $base = '', $namespace = '') {
|
||||
$x = $this->get_property_obj($property, $base, $namespace);
|
||||
|
||||
if ($this->is_url($x)) {
|
||||
|
||||
// SECURITY: If we have already stored the actor profile, re-generate it
|
||||
// from cached data - don't refetch it from the network
|
||||
|
||||
$r = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_id_url = '%s' limit 1",
|
||||
dbesc($x)
|
||||
);
|
||||
if ($r) {
|
||||
$y = Activity::encode_person($r[0]);
|
||||
$y['cached'] = true;
|
||||
$y = Activity::get_cached_actor($x);
|
||||
if ($y) {
|
||||
return $y;
|
||||
}
|
||||
}
|
||||
|
||||
$actor = $this->get_compound_property($property, $base, $namespace, true);
|
||||
|
||||
if (is_array($actor) && self::is_an_actor($actor['type'])) {
|
||||
if (array_key_exists('id', $actor) && (!array_key_exists('inbox', $actor))) {
|
||||
$actor = $this->fetch_property($actor['id']);
|
||||
}
|
||||
return $actor;
|
||||
}
|
||||
return null;
|
||||
|
||||
return Activity::get_unknown_actor($this->data);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -351,10 +357,10 @@ class ActivityStreams {
|
||||
if ($ret['signer']) {
|
||||
$saved = json_encode($x, JSON_UNESCAPED_SLASHES);
|
||||
$x = $tmp;
|
||||
$x['signer'] = $ret['signer'];
|
||||
$x['signed_data'] = $saved;
|
||||
$x['meta']['signer'] = $ret['signer'];
|
||||
$x['meta']['signed_data'] = $saved;
|
||||
if ($ret['hubloc']) {
|
||||
$x['hubloc'] = $ret['hubloc'];
|
||||
$x['meta']['hubloc'] = $ret['hubloc'];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -425,15 +431,19 @@ class ActivityStreams {
|
||||
|
||||
static function get_accept_header_string($channel = null) {
|
||||
|
||||
$ret = '';
|
||||
|
||||
$hookdata = [];
|
||||
if ($channel)
|
||||
$hookdata['channel'] = $channel;
|
||||
|
||||
$hookdata['data'] = 'application/x-zot-activity+json';
|
||||
$hookdata['data'] = ['application/x-zot-activity+json'];
|
||||
|
||||
call_hooks('get_accept_header_string', $hookdata);
|
||||
|
||||
return $hookdata['data'];
|
||||
$ret = implode(', ', $hookdata['data']);
|
||||
|
||||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use Zotlabs\Lib\Libsync;
|
||||
use App;
|
||||
|
||||
require_once('include/plugin.php');
|
||||
require_once('include/channel.php');
|
||||
@@ -21,9 +21,10 @@ class Apps {
|
||||
* @brief
|
||||
*
|
||||
* @param boolean $translate (optional) default true
|
||||
* @param boolean $sync (optional) default false used if called from sync_sysapps()
|
||||
* @return array
|
||||
*/
|
||||
static public function get_system_apps($translate = true) {
|
||||
static public function get_system_apps($translate = true, $sync = false) {
|
||||
$ret = [];
|
||||
|
||||
if(is_dir('apps'))
|
||||
@@ -33,7 +34,7 @@ class Apps {
|
||||
|
||||
if($files) {
|
||||
foreach($files as $f) {
|
||||
$x = self::parse_app_description($f,$translate);
|
||||
$x = self::parse_app_description($f, $translate, $sync);
|
||||
if($x) {
|
||||
$ret[] = $x;
|
||||
}
|
||||
@@ -45,7 +46,7 @@ class Apps {
|
||||
$path = explode('/',$f);
|
||||
$plugin = trim($path[1]);
|
||||
if(plugin_is_installed($plugin)) {
|
||||
$x = self::parse_app_description($f,$translate);
|
||||
$x = self::parse_app_description($f, $translate, $sync);
|
||||
if($x) {
|
||||
$x['plugin'] = $plugin;
|
||||
$ret[] = $x;
|
||||
@@ -66,17 +67,17 @@ class Apps {
|
||||
static public function get_base_apps() {
|
||||
$x = get_config('system','base_apps',[
|
||||
'Connections',
|
||||
'Contact Roles',
|
||||
'Network',
|
||||
'Settings',
|
||||
'Files',
|
||||
'Channel Home',
|
||||
'View Profile',
|
||||
'Channel',
|
||||
'Photos',
|
||||
'Calendar',
|
||||
'Directory',
|
||||
'Search',
|
||||
'Help',
|
||||
'Profile Photo'
|
||||
'HQ',
|
||||
'Post'
|
||||
]);
|
||||
|
||||
/**
|
||||
@@ -158,7 +159,7 @@ class Apps {
|
||||
foreach(self::$available_apps as $iapp) {
|
||||
if($iapp['app_id'] == hash('whirlpool',$app['name'])) {
|
||||
$notfound = false;
|
||||
if(($iapp['app_version'] !== $app['version'])
|
||||
if((isset($app['version']) && $iapp['app_version'] !== $app['version'])
|
||||
|| ($app['plugin'] && (! $iapp['app_plugin']))) {
|
||||
return intval($iapp['app_id']);
|
||||
}
|
||||
@@ -207,9 +208,10 @@ class Apps {
|
||||
*
|
||||
* @param string $f filename
|
||||
* @param boolean $translate (optional) default true
|
||||
* @param boolean $sync (optional) default false
|
||||
* @return boolean|array
|
||||
*/
|
||||
static public function parse_app_description($f, $translate = true) {
|
||||
static public function parse_app_description($f, $translate = true, $sync = false) {
|
||||
$ret = [];
|
||||
$matches = [];
|
||||
|
||||
@@ -234,6 +236,7 @@ class Apps {
|
||||
$ret['photo'] = $baseurl . '/' . get_default_profile_photo(80);
|
||||
|
||||
$ret['type'] = 'system';
|
||||
$ret['plugin'] = '';
|
||||
|
||||
foreach($ret as $k => $v) {
|
||||
if(strpos($v,'http') === 0) {
|
||||
@@ -255,7 +258,7 @@ class Apps {
|
||||
if(array_key_exists('categories',$ret))
|
||||
$ret['categories'] = str_replace(array('\'','"'),array(''','&dquot;'),$ret['categories']);
|
||||
|
||||
if(array_key_exists('requires',$ret)) {
|
||||
if(array_key_exists('requires',$ret) && !$sync) {
|
||||
$requires = explode(',',$ret['requires']);
|
||||
foreach($requires as $require) {
|
||||
$require = trim(strtolower($require));
|
||||
@@ -307,14 +310,16 @@ class Apps {
|
||||
}
|
||||
}
|
||||
}
|
||||
if(isset($ret)) {
|
||||
if($translate)
|
||||
self::translate_system_apps($ret);
|
||||
|
||||
return $ret;
|
||||
if(empty($ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
if($translate) {
|
||||
self::translate_system_apps($ret);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -340,7 +345,7 @@ class Apps {
|
||||
'Files' => t('Files'),
|
||||
'Webpages' => t('Webpages'),
|
||||
'Wiki' => t('Wiki'),
|
||||
'Channel Home' => t('Channel Home'),
|
||||
'Channel' => t('Channel'),
|
||||
'View Profile' => t('View Profile'),
|
||||
'Photos' => t('Photos'),
|
||||
'Calendar' => t('Calendar'),
|
||||
@@ -371,7 +376,7 @@ class Apps {
|
||||
'OAuth Apps Manager' => t('OAuth Apps Manager'),
|
||||
'OAuth2 Apps Manager' => t('OAuth2 Apps Manager'),
|
||||
'PDL Editor' => t('PDL Editor'),
|
||||
'Permission Categories' => t('Permission Categories'),
|
||||
'Contact Roles' => t('Contact Roles'),
|
||||
'Public Stream' => t('Public Stream'),
|
||||
'My Chatrooms' => t('My Chatrooms'),
|
||||
'Channel Export' => t('Channel Export')
|
||||
@@ -422,7 +427,7 @@ class Apps {
|
||||
|
||||
self::translate_system_apps($papp);
|
||||
|
||||
if(trim($papp['plugin']) && (! plugin_is_installed(trim($papp['plugin']))))
|
||||
if(isset($papp['plugin']) && trim($papp['plugin']) && (! plugin_is_installed(trim($papp['plugin']))))
|
||||
return '';
|
||||
|
||||
$papp['papp'] = self::papp_encode($papp);
|
||||
@@ -517,14 +522,19 @@ class Apps {
|
||||
$hosturl = '';
|
||||
|
||||
if(local_channel()) {
|
||||
if(self::app_installed(local_channel(),$papp) && !$papp['deleted'])
|
||||
if(self::app_installed(local_channel(),$papp)) {
|
||||
$installed = true;
|
||||
}
|
||||
|
||||
if ($installed && isset($papp['deleted']) && $papp['deleted']) {
|
||||
$installed = false;
|
||||
}
|
||||
|
||||
$hosturl = z_root() . '/';
|
||||
}
|
||||
elseif(remote_channel()) {
|
||||
$observer = \App::get_observer();
|
||||
if($observer && in_array($observer['xchan_network'], ['zot6', 'zot'])) {
|
||||
if($observer && $observer['xchan_network'] === 'zot6') {
|
||||
// some folks might have xchan_url redirected offsite, use the connurl
|
||||
$x = parse_url($observer['xchan_connurl']);
|
||||
if($x) {
|
||||
@@ -536,13 +546,47 @@ class Apps {
|
||||
$install_action = (($installed) ? t('Update') : t('Install'));
|
||||
$icon = ((strpos($papp['photo'],'icon:') === 0) ? substr($papp['photo'],5) : '');
|
||||
|
||||
if (!$installed && $mode === 'module') {
|
||||
$_SESSION['return_url'] = App::$query_string;
|
||||
return replace_macros(get_markup_template('app_install.tpl'), [
|
||||
'$papp' => $papp,
|
||||
'$install' => $install_action
|
||||
]);
|
||||
}
|
||||
|
||||
if($mode === 'navbar') {
|
||||
return replace_macros(get_markup_template('app_nav_pinned.tpl'),array(
|
||||
'$app' => $papp,
|
||||
'$icon' => $icon,
|
||||
));
|
||||
}
|
||||
|
||||
if($mode === 'nav') {
|
||||
return replace_macros(get_markup_template('app_nav.tpl'),array(
|
||||
'$app' => $papp,
|
||||
'$icon' => $icon,
|
||||
));
|
||||
}
|
||||
|
||||
if($mode === 'inline') {
|
||||
return replace_macros(get_markup_template('app_inline.tpl'),array(
|
||||
'$app' => $papp,
|
||||
'$icon' => $icon,
|
||||
'$installed' => $installed,
|
||||
'$purchase' => ((isset($papp['page']) && (! $installed)) ? t('Purchase') : ''),
|
||||
'$action_label' => $install_action
|
||||
));
|
||||
}
|
||||
|
||||
if(in_array($mode, ['nav-order', 'nav-order-pinned'])) {
|
||||
return replace_macros(get_markup_template('app_order.tpl'),array(
|
||||
'$app' => $papp,
|
||||
'$icon' => $icon,
|
||||
'$hosturl' => $hosturl,
|
||||
'$mode' => $mode
|
||||
));
|
||||
}
|
||||
|
||||
if($mode === 'install') {
|
||||
$papp['embed'] = true;
|
||||
}
|
||||
@@ -557,14 +601,12 @@ class Apps {
|
||||
'$edit' => ((local_channel() && $installed && $mode == 'edit') ? t('Edit') : ''),
|
||||
'$delete' => ((local_channel() && $mode == 'edit') ? t('Delete') : ''),
|
||||
'$undelete' => ((local_channel() && $mode == 'edit') ? t('Undelete') : ''),
|
||||
'$settings_url' => ((local_channel() && $installed && $mode == 'list') ? $papp['settings_url'] : ''),
|
||||
'$deleted' => $papp['deleted'],
|
||||
'$settings_url' => ((local_channel() && $installed && $mode == 'list' && isset($papp['settings_url'])) ? $papp['settings_url'] : ''),
|
||||
'$deleted' => $papp['deleted'] ?? false,
|
||||
'$feature' => ((isset($papp['embed']) || $mode == 'edit') ? false : true),
|
||||
'$pin' => ((isset($papp['embed']) || $mode == 'edit') ? false : true),
|
||||
'$featured' => ((strpos($papp['categories'], 'nav_featured_app') === false) ? false : true),
|
||||
'$pinned' => ((strpos($papp['categories'], 'nav_pinned_app') === false) ? false : true),
|
||||
'$navapps' => (($mode == 'nav') ? true : false),
|
||||
'$order' => (($mode === 'nav-order' || $mode === 'nav-order-pinned') ? true : false),
|
||||
'$featured' => ((isset($papp['categories']) && strpos($papp['categories'], 'nav_featured_app') === false) ? false : true),
|
||||
'$pinned' => ((isset($papp['categories']) && strpos($papp['categories'], 'nav_pinned_app') === false) ? false : true),
|
||||
'$mode' => $mode,
|
||||
'$add' => t('Add to app-tray'),
|
||||
'$remove' => t('Remove from app-tray'),
|
||||
@@ -574,6 +616,7 @@ class Apps {
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
static public function app_install($uid,$app) {
|
||||
|
||||
if(! is_array($app)) {
|
||||
@@ -588,10 +631,12 @@ class Apps {
|
||||
|
||||
$app['uid'] = $uid;
|
||||
|
||||
if(self::app_installed($uid,$app,true))
|
||||
if(self::app_installed($uid,$app,true)) {
|
||||
$x = self::app_update($app);
|
||||
else
|
||||
}
|
||||
else {
|
||||
$x = self::app_store($app);
|
||||
}
|
||||
|
||||
if($x['success']) {
|
||||
$r = q("select * from app where app_id = '%s' and app_channel = %d limit 1",
|
||||
@@ -599,13 +644,12 @@ class Apps {
|
||||
intval($uid)
|
||||
);
|
||||
if($r) {
|
||||
if(($app['uid']) && (! $r[0]['app_system'])) {
|
||||
if($app['categories'] && (! $app['term'])) {
|
||||
if($app['uid']) {
|
||||
if((isset($app['categories']) && $app['categories']) && !(isset($app['term']) && $app['term'])) {
|
||||
$r[0]['term'] = q("select * from term where otype = %d and oid = %d",
|
||||
intval(TERM_OBJ_APP),
|
||||
intval($r[0]['id'])
|
||||
);
|
||||
Libsync::build_sync_packet($uid,array('app' => $r[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -634,6 +678,7 @@ class Apps {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -645,38 +690,35 @@ class Apps {
|
||||
dbesc($app['guid']),
|
||||
intval($uid)
|
||||
);
|
||||
if($x) {
|
||||
if(! intval($x[0]['app_deleted'])) {
|
||||
$x[0]['app_deleted'] = 1;
|
||||
if(self::can_delete($uid,$app)) {
|
||||
q("delete from app where app_id = '%s' and app_channel = %d",
|
||||
dbesc($app['guid']),
|
||||
intval($uid)
|
||||
);
|
||||
q("delete from term where otype = %d and oid = %d",
|
||||
intval(TERM_OBJ_APP),
|
||||
intval($x[0]['id'])
|
||||
);
|
||||
/**
|
||||
* @hooks app_destroy
|
||||
* Called after app entry got removed from database
|
||||
* and provide app array from database.
|
||||
*/
|
||||
call_hooks('app_destroy', $x[0]);
|
||||
}
|
||||
else {
|
||||
q("update app set app_deleted = 1 where app_id = '%s' and app_channel = %d",
|
||||
dbesc($app['guid']),
|
||||
intval($uid)
|
||||
);
|
||||
}
|
||||
if(! intval($x[0]['app_system'])) {
|
||||
Libsync::build_sync_packet($uid,array('app' => $x));
|
||||
}
|
||||
}
|
||||
else {
|
||||
self::app_undestroy($uid,$app);
|
||||
}
|
||||
|
||||
if($x && intval($x[0]['app_deleted'])) {
|
||||
self::app_undestroy($uid, $app);
|
||||
return;
|
||||
}
|
||||
|
||||
if(self::can_delete($uid,$app)) {
|
||||
q("delete from app where app_id = '%s' and app_channel = %d",
|
||||
dbesc($app['guid']),
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
q("delete from term where otype = %d and oid = %d",
|
||||
intval(TERM_OBJ_APP),
|
||||
intval($x[0]['id'])
|
||||
);
|
||||
|
||||
/**
|
||||
* @hooks app_destroy
|
||||
* Called after app entry got removed from database
|
||||
* and provide app array from database.
|
||||
*/
|
||||
call_hooks('app_destroy', $x[0]);
|
||||
}
|
||||
else {
|
||||
q("update app set app_deleted = 1 where app_id = '%s' and app_channel = %d",
|
||||
dbesc($app['guid']),
|
||||
intval($uid)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -693,13 +735,11 @@ class Apps {
|
||||
dbesc($app['guid']),
|
||||
intval($uid)
|
||||
);
|
||||
if($x) {
|
||||
if($x[0]['app_system']) {
|
||||
q("update app set app_deleted = 0 where app_id = '%s' and app_channel = %d",
|
||||
dbesc($app['guid']),
|
||||
intval($uid)
|
||||
);
|
||||
}
|
||||
if($x && intval($x[0]['app_deleted']) && $x[0]['app_system']) {
|
||||
q("update app set app_deleted = 0 where app_id = '%s' and app_channel = %d",
|
||||
dbesc($app['guid']),
|
||||
intval($uid)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1150,7 +1190,7 @@ class Apps {
|
||||
$ret['success'] = true;
|
||||
$ret['app_id'] = $darray['app_id'];
|
||||
}
|
||||
if($arr['categories']) {
|
||||
if(isset($arr['categories']) && $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'])
|
||||
@@ -1158,9 +1198,9 @@ class Apps {
|
||||
$y = explode(',',$arr['categories']);
|
||||
if($y) {
|
||||
foreach($y as $t) {
|
||||
$t = trim($t);
|
||||
$t = escape_tags(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)));
|
||||
store_item_tag($darray['app_channel'], $x[0]['id'], TERM_OBJ_APP, TERM_CATEGORY, $t, z_root() . '/apps/?f=&cat=' . $t);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1248,7 +1288,7 @@ class Apps {
|
||||
intval(TERM_OBJ_APP),
|
||||
intval($x[0]['id'])
|
||||
);
|
||||
if($arr['categories']) {
|
||||
if(isset($arr['categories']) && $arr['categories']) {
|
||||
$y = explode(',',$arr['categories']);
|
||||
if($y) {
|
||||
foreach($y as $t) {
|
||||
@@ -1356,4 +1396,17 @@ class Apps {
|
||||
return chunk_split(base64_encode(json_encode($papp)),72,"\n");
|
||||
}
|
||||
|
||||
static public function get_papp($app) {
|
||||
|
||||
$r = q("select * from app where app_id = '%s' and app_channel = 0 limit 1",
|
||||
dbesc(hash('whirlpool', $app))
|
||||
);
|
||||
|
||||
if ($r) {
|
||||
$papp = self::app_encode($r[0]);
|
||||
return $papp;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ class Connect {
|
||||
$xchan_hash = '';
|
||||
$sql_options = (($protocol) ? " and xchan_network = '" . dbesc($protocol) . "' " : '');
|
||||
|
||||
$r = q("select * from xchan where ( xchan_hash = '%s' or xchan_url = '%s' or xchan_addr = '%s') $sql_options ",
|
||||
$r = q("SELECT * FROM xchan LEFT JOIN hubloc ON xchan_hash = hubloc_hash WHERE ( xchan_hash = '%s' or xchan_url = '%s' or xchan_addr = '%s') $sql_options ORDER BY hubloc_id DESC",
|
||||
dbesc($url),
|
||||
dbesc($url),
|
||||
dbesc($url)
|
||||
@@ -80,12 +80,13 @@ class Connect {
|
||||
// reset results to the best record or the first if we don't have the best
|
||||
// note: this is a single record and not an array of results
|
||||
|
||||
$r = Libzot::zot_record_preferred($r,'xchan_network');
|
||||
$r = Libzot::zot_record_preferred($r, 'xchan_network');
|
||||
|
||||
}
|
||||
|
||||
$singleton = false;
|
||||
$d = false;
|
||||
$wf = false;
|
||||
|
||||
if (! $r) {
|
||||
|
||||
@@ -111,7 +112,7 @@ class Connect {
|
||||
// something was discovered - find the record which was just created.
|
||||
|
||||
$r = q("select * from xchan where ( xchan_hash = '%s' or xchan_url = '%s' or xchan_addr = '%s' ) $sql_options",
|
||||
dbesc(($wf) ? $wf : $url),
|
||||
dbesc($wf ?? $url),
|
||||
dbesc($url),
|
||||
dbesc($url)
|
||||
);
|
||||
@@ -119,7 +120,7 @@ class Connect {
|
||||
// convert to a single record (once again preferring a zot solution in the case of multiples)
|
||||
|
||||
if ($r) {
|
||||
$r = Libzot::zot_record_preferred($r,'xchan_network');
|
||||
$r = Libzot::zot_record_preferred($r, 'xchan_network');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +147,7 @@ class Connect {
|
||||
|
||||
}
|
||||
|
||||
$allowed = ((in_array($xchan['xchan_network'],['rss','zot','zot6'])) ? 1 : 0);
|
||||
$allowed = ((in_array($xchan['xchan_network'],['rss', 'zot6'])) ? 1 : 0);
|
||||
|
||||
$hookdata = ['channel_id' => $uid, 'follow_address' => $url, 'xchan' => $xchan, 'allowed' => $allowed, 'singleton' => 0];
|
||||
call_hooks('follow_allow',$hookdata);
|
||||
@@ -261,7 +262,8 @@ class Connect {
|
||||
'abook_feed' => intval(($xchan['xchan_network'] === 'rss') ? 1 : 0),
|
||||
'abook_created' => datetime_convert(),
|
||||
'abook_updated' => datetime_convert(),
|
||||
'abook_instance' => (($singleton) ? z_root() : '')
|
||||
'abook_instance' => (($singleton) ? z_root() : ''),
|
||||
'abook_role' => get_pconfig($uid, 'system', 'default_permcat', 'default')
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -300,7 +302,7 @@ class Connect {
|
||||
/** If there is a default group for this channel, add this connection to it */
|
||||
|
||||
if ($default_group) {
|
||||
$g = AccessList::rec_byhash($uid,$default_group);
|
||||
$g = AccessList::by_hash($uid,$default_group);
|
||||
if ($g) {
|
||||
AccessList::member_add($uid,'',$xchan_hash,$g['id']);
|
||||
}
|
||||
|
||||
@@ -87,6 +87,10 @@ class Crypto {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$alg) {
|
||||
$alg = 'sha256';
|
||||
}
|
||||
|
||||
try {
|
||||
$verify = openssl_verify($data, $sig, $key, $alg);
|
||||
} catch (Exception $e) {
|
||||
|
||||
@@ -87,8 +87,7 @@ class DReport {
|
||||
|
||||
// Is the sender one of our channels?
|
||||
|
||||
$c = q("select channel_id from channel where channel_hash = '%s' or channel_portable_id = '%s' limit 1",
|
||||
dbesc($dr['sender']),
|
||||
$c = q("select channel_id from channel where channel_hash = '%s' limit 1",
|
||||
dbesc($dr['sender'])
|
||||
);
|
||||
|
||||
|
||||
@@ -69,24 +69,24 @@ class Enotify {
|
||||
$sender_name = $product;
|
||||
$hostname = \App::get_hostname();
|
||||
if(strpos($hostname,':'))
|
||||
$hostname = substr($hostname,0,strpos($hostname,':'));
|
||||
$hostname = substr($hostname, 0, strpos($hostname,':'));
|
||||
|
||||
// Do not translate 'noreply' as it must be a legal 7-bit email address
|
||||
|
||||
$reply_email = get_config('system','reply_address');
|
||||
$reply_email = get_config('system', 'reply_address');
|
||||
if(! $reply_email)
|
||||
$reply_email = 'noreply' . '@' . $hostname;
|
||||
|
||||
$sender_email = get_config('system','from_email');
|
||||
$sender_email = get_config('system', 'from_email');
|
||||
if(! $sender_email)
|
||||
$sender_email = 'Administrator' . '@' . $hostname;
|
||||
|
||||
$sender_name = get_config('system','from_email_name');
|
||||
$sender_name = get_config('system', 'from_email_name');
|
||||
if(! $sender_name)
|
||||
$sender_name = \Zotlabs\Lib\System::get_site_name();
|
||||
|
||||
|
||||
$additional_mail_header = "";
|
||||
$additional_mail_header = '';
|
||||
|
||||
if(array_key_exists('item', $params)) {
|
||||
require_once('include/conversation.php');
|
||||
@@ -114,27 +114,31 @@ class Enotify {
|
||||
}
|
||||
|
||||
|
||||
$always_show_in_notices = get_pconfig($recip['channel_id'],'system','always_show_in_notices');
|
||||
$vnotify = get_pconfig($recip['channel_id'],'system','vnotify');
|
||||
$always_show_in_notices = get_pconfig($recip['channel_id'], 'system', 'always_show_in_notices');
|
||||
$vnotify = get_pconfig($recip['channel_id'], 'system', 'vnotify');
|
||||
|
||||
$salutation = $recip['channel_name'];
|
||||
|
||||
// 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('[$Projectname:Notify] New mail received at %s'),$sitename);
|
||||
$parent_mid = '';
|
||||
$parent_item = [];
|
||||
|
||||
$preamble = sprintf( t('%1$s sent you a new private message at %2$s.'), $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'];
|
||||
// @@TODO: consider using switch instead of those elseif
|
||||
if (isset($params['type']) && $params['type'] == NOTIFY_MAIL) {
|
||||
logger('notification: mail');
|
||||
$subject = sprintf( t('[$Projectname:Notify] New direct message received at %s'), $sitename);
|
||||
|
||||
$preamble = sprintf( t('%1$s sent you a new direct message at %2$s'), $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 direct message') . '[/zrl]');
|
||||
$sitelink = t('Please visit %s to view and/or reply to your direct messages.');
|
||||
$tsitelink = sprintf( $sitelink, $siteurl . '/hq/' . gen_link_id($params['item']['mid']));
|
||||
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '/hq/' . gen_link_id($params['item']['mid']) . '">' . $sitename . '</a>');
|
||||
$itemlink = $siteurl . '/hq/' . gen_link_id($params['item']['mid']);
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_COMMENT) {
|
||||
elseif (isset($params['type']) && $params['type'] === NOTIFY_COMMENT) {
|
||||
//logger("notification: params = " . print_r($params, true), LOGGER_DEBUG);
|
||||
|
||||
$moderated = (($params['item']['item_blocked'] == ITEM_MODERATED) ? true : false);
|
||||
@@ -166,12 +170,11 @@ class Enotify {
|
||||
|
||||
}
|
||||
|
||||
$parent_mid = $params['parent_mid'];
|
||||
$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'])
|
||||
@@ -196,6 +199,7 @@ class Enotify {
|
||||
|
||||
xchan_query($p);
|
||||
|
||||
//@@FIXME $p can be null (line 188)
|
||||
$item_post_type = item_post_type($p[0]);
|
||||
// $private = $p[0]['item_private'];
|
||||
$parent_id = $p[0]['id'];
|
||||
@@ -237,7 +241,7 @@ class Enotify {
|
||||
$subject = sprintf( t('[$Projectname:Notify] Moderated Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
|
||||
else
|
||||
$subject = sprintf( t('[$Projectname:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
|
||||
$preamble = sprintf( t('%1$s commented on an item/conversation you have been following.'), $sender['xchan_name']);
|
||||
$preamble = sprintf( t('%1$s commented on an item/conversation you have been following'), $sender['xchan_name']);
|
||||
$epreamble = $dest_str;
|
||||
|
||||
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
|
||||
@@ -250,25 +254,24 @@ class Enotify {
|
||||
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_LIKE) {
|
||||
elseif (isset($params['type']) && $params['type'] === NOTIFY_LIKE) {
|
||||
// logger("notification: params = " . print_r($params, true), LOGGER_DEBUG);
|
||||
|
||||
$itemlink = $params['link'];
|
||||
|
||||
if (array_key_exists('item',$params) && (! activity_match($params['item']['verb'],ACTIVITY_LIKE))) {
|
||||
if(! $always_show_in_notices || !($vnotify & VNOTIFY_LIKE)) {
|
||||
if (array_key_exists('item',$params) && (activity_match($params['item']['verb'], ACTIVITY_LIKE) || activity_match($params['item']['verb'], ACTIVITY_DISLIKE))) {
|
||||
if(! $always_show_in_notices || !($vnotify & VNOTIFY_LIKE) || !feature_enabled($recip['channel_id'], 'dislike')) {
|
||||
logger('notification: not a visible activity. Ignoring.');
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$parent_mid = $params['parent_mid'];
|
||||
$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'])
|
||||
@@ -291,8 +294,12 @@ class Enotify {
|
||||
);
|
||||
}
|
||||
|
||||
xchan_query($p);
|
||||
if (!$p) {
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
|
||||
xchan_query($p);
|
||||
|
||||
$item_post_type = item_post_type($p[0]);
|
||||
// $private = $p[0]['item_private'];
|
||||
@@ -300,13 +307,16 @@ class Enotify {
|
||||
|
||||
$parent_item = $p[0];
|
||||
|
||||
$verb = ((activity_match($params['item']['verb'], ACTIVITY_DISLIKE)) ? t('disliked') : t('liked'));
|
||||
|
||||
// "your post"
|
||||
if($p[0]['owner']['xchan_name'] == $p[0]['author']['xchan_name'] && intval($p[0]['item_wall']))
|
||||
$dest_str = sprintf(t('%1$s liked [zrl=%2$s]your %3$s[/zrl]'),
|
||||
if($p[0]['owner']['xchan_name'] === $p[0]['author']['xchan_name'] && intval($p[0]['item_wall']))
|
||||
$dest_str = sprintf(t('%1$s %2$s [zrl=%3$s]your %4$s[/zrl]'),
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
|
||||
$verb,
|
||||
$itemlink,
|
||||
$item_post_type);
|
||||
$item_post_type
|
||||
);
|
||||
else {
|
||||
pop_lang();
|
||||
return;
|
||||
@@ -318,7 +328,7 @@ class Enotify {
|
||||
// differents subjects for messages on the same thread.
|
||||
|
||||
$subject = sprintf( t('[$Projectname:Notify] Like received to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
|
||||
$preamble = sprintf( t('%1$s liked an item/conversation you created.'), $sender['xchan_name']);
|
||||
$preamble = sprintf( t('%1$s liked an item/conversation you created'), $sender['xchan_name']);
|
||||
$epreamble = $dest_str;
|
||||
|
||||
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
|
||||
@@ -328,7 +338,7 @@ class Enotify {
|
||||
|
||||
|
||||
|
||||
if($params['type'] == NOTIFY_WALL) {
|
||||
elseif(isset($params['type']) && $params['type'] === NOTIFY_WALL) {
|
||||
$subject = sprintf( t('[$Projectname:Notify] %s posted to your profile wall') , $sender['xchan_name']);
|
||||
|
||||
$preamble = sprintf( t('%1$s posted to your profile wall at %2$s') , $sender['xchan_name'], $sitename);
|
||||
@@ -343,9 +353,8 @@ class Enotify {
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_TAGSELF) {
|
||||
elseif (isset($params['type']) && $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'])
|
||||
@@ -368,7 +377,7 @@ class Enotify {
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_POKE) {
|
||||
elseif (isset($params['type']) && $params['type'] === NOTIFY_POKE) {
|
||||
$subject = sprintf( t('[$Projectname:Notify] %1$s poked you') , $sender['xchan_name']);
|
||||
$preamble = sprintf( t('%1$s poked you at %2$s') , $sender['xchan_name'], $sitename);
|
||||
$epreamble = sprintf( t('%1$s [zrl=%2$s]poked you[/zrl].') ,
|
||||
@@ -385,7 +394,7 @@ class Enotify {
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_TAGSHARE) {
|
||||
elseif (isset($params['type']) && $params['type'] === NOTIFY_TAGSHARE) {
|
||||
$subject = sprintf( t('[$Projectname:Notify] %s tagged your post') , $sender['xchan_name']);
|
||||
$preamble = sprintf( t('%1$s tagged your post at %2$s'),$sender['xchan_name'], $sitename);
|
||||
$epreamble = sprintf( t('%1$s tagged [zrl=%2$s]your post[/zrl]') ,
|
||||
@@ -398,7 +407,7 @@ class Enotify {
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_INTRO) {
|
||||
elseif (isset($params['type']) && $params['type'] === NOTIFY_INTRO) {
|
||||
$subject = sprintf( t('[$Projectname:Notify] Introduction received'));
|
||||
$preamble = sprintf( t('You\'ve received an new connection request from \'%1$s\' at %2$s'), $sender['xchan_name'], $sitename);
|
||||
$epreamble = sprintf( t('You\'ve received [zrl=%1$s]a new connection request[/zrl] from %2$s.'),
|
||||
@@ -412,7 +421,7 @@ class Enotify {
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_SUGGEST) {
|
||||
elseif (isset($params['type']) && $params['type'] === NOTIFY_SUGGEST) {
|
||||
$subject = sprintf( t('[$Projectname:Notify] Friend suggestion received'));
|
||||
$preamble = sprintf( t('You\'ve received a friend suggestion from \'%1$s\' at %2$s'), $sender['xchan_name'], $sitename);
|
||||
$epreamble = sprintf( t('You\'ve received [zrl=%1$s]a friend suggestion[/zrl] for %2$s from %3$s.'),
|
||||
@@ -430,11 +439,11 @@ class Enotify {
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_CONFIRM) {
|
||||
elseif (isset($params['type']) && $params['type'] === NOTIFY_CONFIRM) {
|
||||
// ?
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_SYSTEM) {
|
||||
elseif (isset($params['type']) && $params['type'] === NOTIFY_SYSTEM) {
|
||||
// ?
|
||||
}
|
||||
|
||||
@@ -477,7 +486,7 @@ class Enotify {
|
||||
} while ($dups === true);
|
||||
|
||||
|
||||
$datarray = array();
|
||||
$datarray = [];
|
||||
$datarray['hash'] = $hash;
|
||||
$datarray['sender_hash'] = $sender['xchan_hash'];
|
||||
$datarray['xname'] = $sender['xchan_name'];
|
||||
@@ -489,12 +498,13 @@ class Enotify {
|
||||
$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['ntype'] = $params['type'] ?? '';
|
||||
$datarray['verb'] = $params['verb'] ?? '';
|
||||
$datarray['otype'] = $params['otype'] ?? '';
|
||||
$datarray['abort'] = false;
|
||||
$datarray['seen'] = 0;
|
||||
|
||||
$datarray['item'] = $params['item'];
|
||||
$datarray['item'] = $params['item'] ?? [];
|
||||
|
||||
call_hooks('enotify_store', $datarray);
|
||||
|
||||
@@ -505,7 +515,6 @@ class Enotify {
|
||||
|
||||
|
||||
// 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
|
||||
@@ -514,8 +523,8 @@ class Enotify {
|
||||
// (probably would be better that way)
|
||||
|
||||
if (!$always_show_in_notices) {
|
||||
if (($params['type'] == NOTIFY_WALL) || ($params['type'] == NOTIFY_MAIL) || ($params['type'] == NOTIFY_INTRO)) {
|
||||
$seen = 1;
|
||||
if (($params['type'] === NOTIFY_WALL) || ($params['type'] === NOTIFY_MAIL) || ($params['type'] === NOTIFY_INTRO)) {
|
||||
$datarray['seen'] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -531,7 +540,7 @@ class Enotify {
|
||||
intval($datarray['uid']),
|
||||
dbesc($datarray['link']),
|
||||
dbesc($datarray['parent']),
|
||||
intval($seen),
|
||||
intval($datarray['seen']),
|
||||
intval($datarray['ntype']),
|
||||
dbesc($datarray['verb']),
|
||||
dbesc($datarray['otype'])
|
||||
@@ -550,12 +559,12 @@ class Enotify {
|
||||
}
|
||||
|
||||
$itemlink = z_root() . '/notify/view/' . $notify_id;
|
||||
$msg = str_replace('$itemlink',$itemlink,$epreamble);
|
||||
$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);
|
||||
$msg = substr($msg, strpos($msg,', ')+1);
|
||||
|
||||
$datarray['id'] = $notify_id;
|
||||
$datarray['msg'] = $msg;
|
||||
@@ -575,7 +584,7 @@ class Enotify {
|
||||
|
||||
logger('notification: sending notification email');
|
||||
|
||||
$hn = get_pconfig($recip['channel_id'],'system','email_notify_host');
|
||||
$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();
|
||||
@@ -584,7 +593,7 @@ class Enotify {
|
||||
|
||||
$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)));
|
||||
$htmlversion = bbcode(stripslashes(str_replace(array("\\r","\\n"), array('',"<br />\n"),$body)));
|
||||
|
||||
|
||||
// use $_SESSION['zid_override'] to force zid() to use
|
||||
@@ -601,14 +610,14 @@ class Enotify {
|
||||
unset($_SESSION['zid_override']);
|
||||
unset($_SESSION['zrl_override']);
|
||||
|
||||
$datarray = array();
|
||||
$datarray = [];
|
||||
$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['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'];
|
||||
@@ -675,7 +684,6 @@ class Enotify {
|
||||
'$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'],
|
||||
@@ -697,7 +705,6 @@ class Enotify {
|
||||
'$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'],
|
||||
@@ -758,9 +765,9 @@ class Enotify {
|
||||
$messageSubject = email_header_encode(html_entity_decode($params['messageSubject'],ENT_QUOTES,'UTF-8'),'UTF-8');
|
||||
|
||||
// generate a mime boundary
|
||||
$mimeBoundary = rand(0, 9) . "-"
|
||||
.rand(100000000, 999999999) . "-"
|
||||
.rand(100000000, 999999999) . "=:"
|
||||
$mimeBoundary = rand(0, 9) . '-'
|
||||
.rand(100000000, 999999999) . '-'
|
||||
.rand(100000000, 999999999) . '=:'
|
||||
.rand(10000, 99999);
|
||||
|
||||
// generate a multipart/alternative message header
|
||||
@@ -768,7 +775,7 @@ class Enotify {
|
||||
$params['additionalMailHeader'] .
|
||||
"From: $fromName <{$params['fromEmail']}>" . PHP_EOL .
|
||||
"Reply-To: $fromName <{$params['replyTo']}>" . PHP_EOL .
|
||||
"MIME-Version: 1.0" . PHP_EOL .
|
||||
'MIME-Version: 1.0' . PHP_EOL .
|
||||
"Content-Type: multipart/alternative; boundary=\"{$mimeBoundary}\"";
|
||||
|
||||
// assemble the final multipart message body with the text and html types included
|
||||
@@ -776,15 +783,15 @@ class Enotify {
|
||||
$htmlBody = chunk_split(base64_encode($params['htmlVersion']));
|
||||
|
||||
$multipartMessageBody =
|
||||
"--" . $mimeBoundary . PHP_EOL . // plain text section
|
||||
"Content-Type: text/plain; charset=UTF-8" . PHP_EOL .
|
||||
"Content-Transfer-Encoding: base64" . PHP_EOL . PHP_EOL .
|
||||
'--' . $mimeBoundary . PHP_EOL . // plain text section
|
||||
'Content-Type: text/plain; charset=UTF-8' . PHP_EOL .
|
||||
'Content-Transfer-Encoding: base64' . PHP_EOL . PHP_EOL .
|
||||
$textBody . PHP_EOL .
|
||||
"--" . $mimeBoundary . PHP_EOL . // text/html section
|
||||
"Content-Type: text/html; charset=UTF-8" . PHP_EOL .
|
||||
"Content-Transfer-Encoding: base64" . PHP_EOL . PHP_EOL .
|
||||
'--' . $mimeBoundary . PHP_EOL . // text/html section
|
||||
'Content-Type: text/html; charset=UTF-8' . PHP_EOL .
|
||||
'Content-Transfer-Encoding: base64' . PHP_EOL . PHP_EOL .
|
||||
$htmlBody . PHP_EOL .
|
||||
"--" . $mimeBoundary . "--" . PHP_EOL; // message ending
|
||||
'--' . $mimeBoundary . '--' . PHP_EOL; // message ending
|
||||
|
||||
// send the message
|
||||
$res = mail(
|
||||
@@ -793,7 +800,7 @@ class Enotify {
|
||||
$multipartMessageBody, // message body
|
||||
$messageHeader // message headers
|
||||
);
|
||||
logger("notification: enotify::send returns " . (($res) ? 'success' : 'failure'), LOGGER_DEBUG);
|
||||
logger('notification: enotify::send returns ' . (($res) ? 'success' : 'failure'), LOGGER_DEBUG);
|
||||
return $res;
|
||||
}
|
||||
|
||||
@@ -809,10 +816,10 @@ class Enotify {
|
||||
|
||||
localize_item($item);
|
||||
|
||||
if($item['shortlocalize']) {
|
||||
if(isset($item['shortlocalize'])) {
|
||||
$itemem_text = $item['shortlocalize'];
|
||||
}
|
||||
elseif($item['localize']) {
|
||||
elseif(isset($item['localize'])) {
|
||||
$itemem_text = $item['localize'];
|
||||
}
|
||||
else {
|
||||
@@ -825,6 +832,14 @@ class Enotify {
|
||||
$itemem_text = sprintf( t('repeated %s\'s post'), '[bdi]' . $item['author']['xchan_name'] . '[/bdi]');
|
||||
}
|
||||
|
||||
if($item['verb'] === ACTIVITY_LIKE) {
|
||||
$itemem_text = sprintf( t('liked %s\'s post'), '[bdi]' . $item['author']['xchan_name'] . '[/bdi]');
|
||||
}
|
||||
|
||||
if($item['verb'] === ACTIVITY_DISLIKE) {
|
||||
$itemem_text = sprintf( t('disliked %s\'s post'), '[bdi]' . $item['author']['xchan_name'] . '[/bdi]');
|
||||
}
|
||||
|
||||
if(in_array($item['obj_type'], ['Document', 'Video', 'Audio', 'Image'])) {
|
||||
$itemem_text = t('shared a file with you');
|
||||
}
|
||||
@@ -833,13 +848,12 @@ class Enotify {
|
||||
$edit = false;
|
||||
|
||||
if($item['edited'] > $item['created']) {
|
||||
$edit = true;
|
||||
if($item['item_thread_top']) {
|
||||
$itemem_text = sprintf( t('edited a post dated %s'), relative_date($item['created']));
|
||||
$edit = true;
|
||||
}
|
||||
else {
|
||||
$itemem_text = sprintf( t('edited a comment dated %s'), relative_date($item['created']));
|
||||
$edit = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -847,27 +861,31 @@ class Enotify {
|
||||
// convert this logic into a json array just like the system notifications
|
||||
|
||||
$who = (($item['verb'] === ACTIVITY_SHARE) ? 'owner' : 'author');
|
||||
$body = html2plain(bbcode($item['body'], ['drop_media' => true, 'tryoembed' => false]), 75, true);
|
||||
if ($body) {
|
||||
$body = htmlentities($body, ENT_QUOTES, 'UTF-8', false);
|
||||
}
|
||||
|
||||
$x = array(
|
||||
'notify_link' => $item['llink'],
|
||||
'name' => $item[$who]['xchan_name'],
|
||||
'addr' => (($item[$who]['xchan_addr']) ? $item[$who]['xchan_addr'] : $item[$who]['xchan_url']),
|
||||
'addr' => $item[$who]['xchan_addr'] ?? $item[$who]['xchan_url'],
|
||||
'url' => $item[$who]['xchan_url'],
|
||||
'photo' => $item[$who]['xchan_photo_s'],
|
||||
'when' => (($edit) ? datetime_convert('UTC', date_default_timezone_get(), $item['edited']) : datetime_convert('UTC', date_default_timezone_get(), $item['created'])),
|
||||
'class' => (intval($item['item_unseen']) ? 'notify-unseen' : 'notify-seen'),
|
||||
'b64mid' => (($item['mid']) ? 'b64.' . base64url_encode($item['mid']) : ''),
|
||||
//'b64mid' => ((in_array($item['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) ? 'b64.' . base64url_encode($item['thr_parent']) : 'b64.' . base64url_encode($item['mid'])),
|
||||
'b64mid' => (($item['mid']) ? gen_link_id($item['mid']) : ''),
|
||||
//'b64mid' => ((in_array($item['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) ? gen_link_id($item['thr_parent']) : gen_link_id($item['mid'])),
|
||||
'thread_top' => (($item['item_thread_top']) ? true : false),
|
||||
'message' => bbcode(escape_tags($itemem_text)),
|
||||
'body' => htmlentities(html2plain(bbcode($item['body']), 75, true), ENT_QUOTES, 'UTF-8', false),
|
||||
'body' => $body,
|
||||
// these are for the superblock addon
|
||||
'hash' => $item[$who]['xchan_hash'],
|
||||
'uid' => $item['uid'],
|
||||
'display' => true
|
||||
);
|
||||
|
||||
call_hooks('enotify_format',$x);
|
||||
call_hooks('enotify_format', $x);
|
||||
if(! $x['display']) {
|
||||
return [];
|
||||
}
|
||||
@@ -884,9 +902,9 @@ class Enotify {
|
||||
|
||||
$mid = basename($tt['link']);
|
||||
|
||||
$b64mid = ((strpos($mid, 'b64.') === 0) ? $mid : 'b64.' . base64url_encode($mid));
|
||||
$b64mid = gen_link_id($mid);
|
||||
$x = [
|
||||
'notify_link' => z_root() . '/notify/view/' . $tt['id'],
|
||||
'notify_link' => (($tt['ntype'] === NOTIFY_MAIL) ? $tt['link'] : z_root() . '/notify/view/' . $tt['id']),
|
||||
'name' => $tt['xname'],
|
||||
'url' => $tt['url'],
|
||||
'photo' => $tt['photo'],
|
||||
@@ -903,8 +921,8 @@ class Enotify {
|
||||
|
||||
static public function format_intros($rr) {
|
||||
|
||||
$x = [
|
||||
'notify_link' => z_root() . '/connections/ifpending',
|
||||
return [
|
||||
'notify_link' => z_root() . '/connections#' . $rr['abook_id'],
|
||||
'name' => $rr['xchan_name'],
|
||||
'addr' => $rr['xchan_addr'],
|
||||
'url' => $rr['xchan_url'],
|
||||
@@ -914,13 +932,11 @@ class Enotify {
|
||||
'message' => t('added your channel')
|
||||
];
|
||||
|
||||
return $x;
|
||||
|
||||
}
|
||||
|
||||
static public function format_files($rr) {
|
||||
|
||||
$x = [
|
||||
return [
|
||||
'notify_link' => z_root() . '/sharedwithme',
|
||||
'name' => $rr['author']['xchan_name'],
|
||||
'addr' => $rr['author']['xchan_addr'],
|
||||
@@ -931,13 +947,11 @@ class Enotify {
|
||||
'message' => t('shared a file with you')
|
||||
];
|
||||
|
||||
return $x;
|
||||
|
||||
}
|
||||
|
||||
static public function format_mail($rr) {
|
||||
|
||||
$x = [
|
||||
return [
|
||||
'notify_link' => z_root() . '/mail/' . $rr['id'],
|
||||
'name' => $rr['xchan_name'],
|
||||
'addr' => $rr['xchan_addr'],
|
||||
@@ -945,11 +959,9 @@ class Enotify {
|
||||
'photo' => $rr['xchan_photo_s'],
|
||||
'when' => datetime_convert('UTC', date_default_timezone_get(), $rr['created']),
|
||||
'hclass' => (intval($rr['mail_seen']) ? 'notify-seen' : 'notify-unseen'),
|
||||
'message' => t('sent you a private message'),
|
||||
'message' => t('sent you a direct message'),
|
||||
];
|
||||
|
||||
return $x;
|
||||
|
||||
}
|
||||
|
||||
static public function format_all_events($rr) {
|
||||
@@ -959,7 +971,7 @@ class Enotify {
|
||||
$today = ((substr($strt, 0, 10) === datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y-m-d')) ? true : false);
|
||||
$when = day_translate(datetime_convert('UTC', (($rr['adjust']) ? date_default_timezone_get() : 'UTC'), $rr['dtstart'], $bd_format)) . (($today) ? ' ' . t('[today]') : '');
|
||||
|
||||
$x = [
|
||||
return [
|
||||
'notify_link' => z_root() . '/cdav/calendar/' . $rr['event_hash'],
|
||||
'name' => $rr['xchan_name'],
|
||||
'addr' => $rr['xchan_addr'],
|
||||
@@ -970,13 +982,12 @@ class Enotify {
|
||||
'message' => t('created an event')
|
||||
];
|
||||
|
||||
return $x;
|
||||
|
||||
}
|
||||
|
||||
static public function format_register($rr) {
|
||||
|
||||
$x = [
|
||||
return [
|
||||
'notify_link' => z_root() . '/admin/accounts',
|
||||
'name' => $rr['reg_did2'],
|
||||
//'addr' => '',
|
||||
@@ -986,7 +997,5 @@ class Enotify {
|
||||
'message' => t('status verified')
|
||||
];
|
||||
|
||||
return $x;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,405 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use Zotlabs\Lib\Libsync;
|
||||
|
||||
|
||||
class Group {
|
||||
|
||||
static function add($uid,$name,$public = 0) {
|
||||
|
||||
$ret = false;
|
||||
if(x($uid) && x($name)) {
|
||||
$r = self::byname($uid,$name); // check for dups
|
||||
if($r !== false) {
|
||||
|
||||
// This could be a problem.
|
||||
// Let's assume we've just created a group which we once deleted
|
||||
// all the old members are gone, but the group remains so we don't break any security
|
||||
// access lists. What we're doing here is reviving the dead group, but old content which
|
||||
// was restricted to this group may now be seen by the new group members.
|
||||
|
||||
$z = q("SELECT * FROM pgrp WHERE id = %d LIMIT 1",
|
||||
intval($r)
|
||||
);
|
||||
if(($z) && $z[0]['deleted']) {
|
||||
q('UPDATE pgrp SET deleted = 0 WHERE id = %d', intval($z[0]['id']));
|
||||
notice( t('A deleted group with this name was revived. Existing item permissions <strong>may</strong> apply to this group and any future members. If this is not what you intended, please create another group with a different name.') . EOL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
do {
|
||||
$dups = false;
|
||||
$hash = random_string(32) . str_replace(['<','>'],['.','.'], $name);
|
||||
|
||||
$r = q("SELECT id FROM pgrp WHERE hash = '%s' LIMIT 1", dbesc($hash));
|
||||
if($r)
|
||||
$dups = true;
|
||||
} while($dups == true);
|
||||
|
||||
|
||||
$r = q("INSERT INTO pgrp ( hash, uid, visible, gname )
|
||||
VALUES( '%s', %d, %d, '%s' ) ",
|
||||
dbesc($hash),
|
||||
intval($uid),
|
||||
intval($public),
|
||||
dbesc($name)
|
||||
);
|
||||
$ret = $r;
|
||||
}
|
||||
|
||||
Libsync::build_sync_packet($uid,null,true);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
static function remove($uid,$name) {
|
||||
$ret = false;
|
||||
if(x($uid) && x($name)) {
|
||||
$r = q("SELECT id, hash FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1",
|
||||
intval($uid),
|
||||
dbesc($name)
|
||||
);
|
||||
if($r) {
|
||||
$group_id = $r[0]['id'];
|
||||
$group_hash = $r[0]['hash'];
|
||||
}
|
||||
|
||||
if(! $group_id)
|
||||
return false;
|
||||
|
||||
// remove group from default posting lists
|
||||
$r = q("SELECT channel_default_group, channel_allow_gid, channel_deny_gid FROM channel WHERE channel_id = %d LIMIT 1",
|
||||
intval($uid)
|
||||
);
|
||||
if($r) {
|
||||
$user_info = $r[0];
|
||||
$change = false;
|
||||
|
||||
if($user_info['channel_default_group'] == $group_hash) {
|
||||
$user_info['channel_default_group'] = '';
|
||||
$change = true;
|
||||
}
|
||||
if(strpos($user_info['channel_allow_gid'], '<' . $group_hash . '>') !== false) {
|
||||
$user_info['channel_allow_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_allow_gid']);
|
||||
$change = true;
|
||||
}
|
||||
if(strpos($user_info['channel_deny_gid'], '<' . $group_hash . '>') !== false) {
|
||||
$user_info['channel_deny_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_deny_gid']);
|
||||
$change = true;
|
||||
}
|
||||
|
||||
if($change) {
|
||||
q("UPDATE channel SET channel_default_group = '%s', channel_allow_gid = '%s', channel_deny_gid = '%s'
|
||||
WHERE channel_id = %d",
|
||||
intval($user_info['channel_default_group']),
|
||||
dbesc($user_info['channel_allow_gid']),
|
||||
dbesc($user_info['channel_deny_gid']),
|
||||
intval($uid)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// remove all members
|
||||
$r = q("DELETE FROM pgrp_member WHERE uid = %d AND gid = %d ",
|
||||
intval($uid),
|
||||
intval($group_id)
|
||||
);
|
||||
|
||||
// remove group
|
||||
$r = q("UPDATE pgrp SET deleted = 1 WHERE uid = %d AND gname = '%s'",
|
||||
intval($uid),
|
||||
dbesc($name)
|
||||
);
|
||||
|
||||
$ret = $r;
|
||||
|
||||
}
|
||||
|
||||
Libsync::build_sync_packet($uid,null,true);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
static function byname($uid,$name) {
|
||||
if((! $uid) || (! strlen($name)))
|
||||
return false;
|
||||
$r = q("SELECT * FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1",
|
||||
intval($uid),
|
||||
dbesc($name)
|
||||
);
|
||||
if($r)
|
||||
return $r[0]['id'];
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static function rec_byhash($uid,$hash) {
|
||||
if((! $uid) || (! strlen($hash)))
|
||||
return false;
|
||||
$r = q("SELECT * FROM pgrp WHERE uid = %d AND hash = '%s' LIMIT 1",
|
||||
intval($uid),
|
||||
dbesc($hash)
|
||||
);
|
||||
if($r)
|
||||
return $r[0];
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static function member_remove($uid,$name,$member) {
|
||||
$gid = self::byname($uid,$name);
|
||||
if(! $gid)
|
||||
return false;
|
||||
if(! ( $uid && $gid && $member))
|
||||
return false;
|
||||
$r = q("DELETE FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' ",
|
||||
intval($uid),
|
||||
intval($gid),
|
||||
dbesc($member)
|
||||
);
|
||||
|
||||
Libsync::build_sync_packet($uid,null,true);
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
static function member_add($uid,$name,$member,$gid = 0) {
|
||||
if(! $gid)
|
||||
$gid = self::byname($uid,$name);
|
||||
if((! $gid) || (! $uid) || (! $member))
|
||||
return false;
|
||||
|
||||
$r = q("SELECT * FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' LIMIT 1",
|
||||
intval($uid),
|
||||
intval($gid),
|
||||
dbesc($member)
|
||||
);
|
||||
if($r)
|
||||
return true; // You might question this, but
|
||||
// we indicate success because the group member was in fact created
|
||||
// -- It was just created at another time
|
||||
if(! $r)
|
||||
$r = q("INSERT INTO pgrp_member (uid, gid, xchan)
|
||||
VALUES( %d, %d, '%s' ) ",
|
||||
intval($uid),
|
||||
intval($gid),
|
||||
dbesc($member)
|
||||
);
|
||||
|
||||
Libsync::build_sync_packet($uid,null,true);
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
static function members($gid) {
|
||||
$ret = array();
|
||||
if(intval($gid)) {
|
||||
$r = q("SELECT * FROM pgrp_member
|
||||
LEFT JOIN abook ON abook_xchan = pgrp_member.xchan left join xchan on xchan_hash = abook_xchan
|
||||
WHERE gid = %d AND abook_channel = %d and pgrp_member.uid = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 ORDER BY xchan_name ASC ",
|
||||
intval($gid),
|
||||
intval(local_channel()),
|
||||
intval(local_channel())
|
||||
);
|
||||
if($r)
|
||||
$ret = $r;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
static function members_xchan($gid) {
|
||||
$ret = [];
|
||||
if(intval($gid)) {
|
||||
$r = q("SELECT xchan FROM pgrp_member WHERE gid = %d AND uid = %d",
|
||||
intval($gid),
|
||||
intval(local_channel())
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$ret[] = $rr['xchan'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
static function members_profile_xchan($uid,$gid) {
|
||||
$ret = [];
|
||||
|
||||
if(intval($gid)) {
|
||||
$r = q("SELECT abook_xchan as xchan from abook left join profile on abook_profile = profile_guid where profile.id = %d and profile.uid = %d",
|
||||
intval($gid),
|
||||
intval($uid)
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$ret[] = $rr['xchan'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static function select($uid,$group = '') {
|
||||
|
||||
$grps = [];
|
||||
$o = '';
|
||||
|
||||
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
|
||||
intval($uid)
|
||||
);
|
||||
$grps[] = array('name' => '', 'hash' => '0', 'selected' => '');
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$grps[] = array('name' => $rr['gname'], 'id' => $rr['hash'], 'selected' => (($group == $rr['hash']) ? 'true' : ''));
|
||||
}
|
||||
|
||||
}
|
||||
logger('select: ' . print_r($grps,true), LOGGER_DATA);
|
||||
|
||||
$o = replace_macros(get_markup_template('group_selection.tpl'), array(
|
||||
'$label' => t('Add new connections to this privacy group'),
|
||||
'$groups' => $grps
|
||||
));
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static function widget($every="connections",$each="group",$edit = false, $group_id = 0, $cid = '',$mode = 1) {
|
||||
|
||||
$o = '';
|
||||
|
||||
if(! (local_channel() && feature_enabled(local_channel(),'groups'))) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$groups = array();
|
||||
|
||||
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
|
||||
intval($_SESSION['uid'])
|
||||
);
|
||||
$member_of = array();
|
||||
if($cid) {
|
||||
$member_of = self::containing(local_channel(),$cid);
|
||||
}
|
||||
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$selected = (($group_id == $rr['id']) ? ' group-selected' : '');
|
||||
|
||||
if ($edit) {
|
||||
$groupedit = [ 'href' => "group/".$rr['id'], 'title' => t('edit') ];
|
||||
}
|
||||
else {
|
||||
$groupedit = null;
|
||||
}
|
||||
|
||||
$groups[] = [
|
||||
'id' => $rr['id'],
|
||||
'enc_cid' => base64url_encode($cid),
|
||||
'cid' => $cid,
|
||||
'text' => $rr['gname'],
|
||||
'selected' => $selected,
|
||||
'href' => (($mode == 0) ? $each.'?f=&gid='.$rr['id'] : $each."/".$rr['id']) . ((x($_GET,'new')) ? '&new=' . $_GET['new'] : '') . ((x($_GET,'order')) ? '&order=' . $_GET['order'] : ''),
|
||||
'edit' => $groupedit,
|
||||
'ismember' => in_array($rr['id'],$member_of),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$tpl = get_markup_template("group_side.tpl");
|
||||
$o = replace_macros($tpl, array(
|
||||
'$title' => t('Privacy Groups'),
|
||||
'$edittext' => t('Edit group'),
|
||||
'$createtext' => t('Add privacy group'),
|
||||
'$ungrouped' => (($every === 'contacts') ? t('Channels not in any privacy group') : ''),
|
||||
'$groups' => $groups,
|
||||
'$add' => t('add'),
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
static function expand($g) {
|
||||
if(! (is_array($g) && count($g)))
|
||||
return array();
|
||||
|
||||
$ret = [];
|
||||
$x = [];
|
||||
|
||||
// private profile linked virtual groups
|
||||
|
||||
foreach($g as $gv) {
|
||||
if(substr($gv,0,3) === 'vp.') {
|
||||
$profile_hash = substr($gv,3);
|
||||
if($profile_hash) {
|
||||
$r = q("select abook_xchan from abook where abook_profile = '%s'",
|
||||
dbesc($profile_hash)
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rv) {
|
||||
$ret[] = $rv['abook_xchan'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$x[] = $gv;
|
||||
}
|
||||
}
|
||||
|
||||
if($x) {
|
||||
stringify_array_elms($x,true);
|
||||
$groups = implode(',', $x);
|
||||
if($groups) {
|
||||
$r = q("SELECT xchan FROM pgrp_member WHERE gid IN ( select id from pgrp where hash in ( $groups ))");
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$ret[] = $rr['xchan'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
static function member_of($c) {
|
||||
$r = q("SELECT pgrp.gname, pgrp.id FROM pgrp LEFT JOIN pgrp_member ON pgrp_member.gid = pgrp.id WHERE pgrp_member.xchan = '%s' AND pgrp.deleted = 0 ORDER BY pgrp.gname ASC ",
|
||||
dbesc($c)
|
||||
);
|
||||
|
||||
return $r;
|
||||
|
||||
}
|
||||
|
||||
static function containing($uid,$c) {
|
||||
|
||||
$r = q("SELECT gid FROM pgrp_member WHERE uid = %d AND pgrp_member.xchan = '%s' ",
|
||||
intval($uid),
|
||||
dbesc($c)
|
||||
);
|
||||
|
||||
$ret = array();
|
||||
if($r) {
|
||||
foreach($r as $rr)
|
||||
$ret[] = $rr['gid'];
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
@@ -75,22 +75,23 @@ class LDSignatures {
|
||||
}
|
||||
|
||||
static function hash($obj) {
|
||||
|
||||
return hash('sha256',self::normalise($obj));
|
||||
return hash('sha256', self::normalise($obj));
|
||||
}
|
||||
|
||||
static function normalise($data) {
|
||||
$ret = '';
|
||||
|
||||
if(is_string($data)) {
|
||||
$data = json_decode($data);
|
||||
}
|
||||
|
||||
if(! is_object($data))
|
||||
return '';
|
||||
return $ret;
|
||||
|
||||
jsonld_set_document_loader('jsonld_document_loader');
|
||||
|
||||
try {
|
||||
$d = jsonld_normalize($data,[ 'algorithm' => 'URDNA2015', 'format' => 'application/nquads' ]);
|
||||
$ret = jsonld_normalize($data,[ 'algorithm' => 'URDNA2015', 'format' => 'application/nquads' ]);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
// Don't log the exception - this can exhaust memory
|
||||
@@ -98,7 +99,7 @@ class LDSignatures {
|
||||
logger('normalise error: ' . print_r($data,true));
|
||||
}
|
||||
|
||||
return $d;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
static function salmon_sign($data,$channel) {
|
||||
|
||||
@@ -141,7 +141,6 @@ class Libsync {
|
||||
logger('Packet: ' . print_r($info, true), LOGGER_DATA, LOG_DEBUG);
|
||||
|
||||
$total = count($synchubs);
|
||||
|
||||
foreach ($synchubs as $hub) {
|
||||
$hash = random_string();
|
||||
$n = Libzot::build_packet($channel, 'sync', $env_recips, json_encode($info), 'hz', $hub['hubloc_sitekey'], $hub['site_crypto']);
|
||||
@@ -186,7 +185,6 @@ class Libsync {
|
||||
require_once('include/import.php');
|
||||
|
||||
$result = [];
|
||||
|
||||
$keychange = ((array_key_exists('keychange', $arr)) ? true : false);
|
||||
|
||||
foreach ($deliveries as $d) {
|
||||
@@ -204,6 +202,8 @@ class Libsync {
|
||||
|
||||
$channel = $r[0];
|
||||
|
||||
$mid = 'sync';
|
||||
|
||||
$DR->set_name($channel['channel_name'] . ' <' . channel_reddress($channel) . '>');
|
||||
|
||||
$max_friends = service_class_fetch($channel['channel_id'], 'total_channels');
|
||||
@@ -232,8 +232,35 @@ class Libsync {
|
||||
|
||||
if (array_key_exists('config', $arr) && is_array($arr['config']) && count($arr['config'])) {
|
||||
foreach ($arr['config'] as $cat => $k) {
|
||||
foreach ($arr['config'][$cat] as $k => $v)
|
||||
set_pconfig($channel['channel_id'], $cat, $k, $v);
|
||||
$pconfig_updated = [];
|
||||
|
||||
foreach($arr['config'][$cat] as $k => $v) {
|
||||
if ($cat === 'hz_delpconfig' && strpos($k, 'b64.') === 0) {
|
||||
$delpconfig = explode(':', unpack_link_id($k));
|
||||
|
||||
// delete the provided pconfig
|
||||
del_pconfig($channel['channel_id'], $delpconfig[0], $delpconfig[1], $v);
|
||||
|
||||
// delete the messenger pconfig
|
||||
del_pconfig($channel['channel_id'], 'hz_delpconfig', $k);
|
||||
}
|
||||
|
||||
if (strpos($k,'pcfgud:') === 0) {
|
||||
$realk = substr($k,7);
|
||||
$pconfig_updated[$realk] = $v;
|
||||
unset($arr['config'][$cat][$k]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach($arr['config'][$cat] as $k => $v) {
|
||||
if (!isset($pconfig_updated[$k])) {
|
||||
$pconfig_updated[$k] = NULL;
|
||||
}
|
||||
|
||||
if ($cat !== 'hz_delpconfig') {
|
||||
set_pconfig($channel['channel_id'],$cat,$k,$v,$pconfig_updated[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,6 +273,10 @@ class Libsync {
|
||||
if (array_key_exists('app', $arr) && $arr['app'])
|
||||
sync_apps($channel, $arr['app']);
|
||||
|
||||
if (array_key_exists('sysapp',$arr) && $arr['sysapp']) {
|
||||
sync_sysapps($channel, $arr['sysapp']);
|
||||
}
|
||||
|
||||
if (array_key_exists('addressbook', $arr) && $arr['addressbook'])
|
||||
sync_addressbook($channel, $arr['addressbook']);
|
||||
|
||||
@@ -255,11 +286,8 @@ class Libsync {
|
||||
if (array_key_exists('chatroom', $arr) && $arr['chatroom'])
|
||||
sync_chatrooms($channel, $arr['chatroom']);
|
||||
|
||||
if (array_key_exists('conv', $arr) && $arr['conv'])
|
||||
import_conv($channel, $arr['conv']);
|
||||
|
||||
if (array_key_exists('mail', $arr) && $arr['mail'])
|
||||
sync_mail($channel, $arr['mail']);
|
||||
//if (array_key_exists('mail', $arr) && $arr['mail'])
|
||||
// sync_mail($channel, $arr['mail']);
|
||||
|
||||
if (array_key_exists('event', $arr) && $arr['event'])
|
||||
sync_events($channel, $arr['event']);
|
||||
@@ -267,14 +295,16 @@ class Libsync {
|
||||
if (array_key_exists('event_item', $arr) && $arr['event_item'])
|
||||
sync_items($channel, $arr['event_item'], ((array_key_exists('relocate', $arr)) ? $arr['relocate'] : null));
|
||||
|
||||
if (array_key_exists('item', $arr) && $arr['item'])
|
||||
if (array_key_exists('item', $arr) && $arr['item']) {
|
||||
sync_items($channel, $arr['item'], ((array_key_exists('relocate', $arr)) ? $arr['relocate'] : null));
|
||||
$mid = $arr['item']['mid'] . '#sync';
|
||||
}
|
||||
|
||||
// deprecated, maintaining for a few months for upward compatibility
|
||||
// this should sync webpages, but the logic is a bit subtle
|
||||
|
||||
if (array_key_exists('item_id', $arr) && $arr['item_id'])
|
||||
sync_items($channel, $arr['item_id']);
|
||||
//if (array_key_exists('item_id', $arr) && $arr['item_id'])
|
||||
// sync_items($channel, $arr['item_id']);
|
||||
|
||||
if (array_key_exists('menu', $arr) && $arr['menu'])
|
||||
sync_menus($channel, $arr['menu']);
|
||||
@@ -385,19 +415,42 @@ class Libsync {
|
||||
// This relies on the undocumented behaviour that red sites send xchan info with the abook
|
||||
// and import_author_xchan will look them up on all federated networks
|
||||
|
||||
if ($abook['abook_xchan'] && $abook['xchan_addr']) {
|
||||
$found = false;
|
||||
if ($abook['abook_xchan'] && $abook['xchan_addr'] && (! in_array($abook['xchan_network'], [ 'token', 'unknown' ]))) {
|
||||
$h = Libzot::get_hublocs($abook['abook_xchan']);
|
||||
if (!$h) {
|
||||
if ($h) {
|
||||
$found = true;
|
||||
}
|
||||
else {
|
||||
$xhash = import_author_xchan(encode_item_xchan($abook));
|
||||
if (!$xhash) {
|
||||
if ($xhash) {
|
||||
$found = true;
|
||||
}
|
||||
else {
|
||||
logger('Import of ' . $abook['xchan_addr'] . ' failed.');
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found && !in_array($abook['xchan_network'], ['zot6', 'activitypub', 'diaspora'])) {
|
||||
// just import the record.
|
||||
$xc = [];
|
||||
foreach ($abook as $k => $v) {
|
||||
if (strpos($k,'xchan_') === 0) {
|
||||
$xc[$k] = $v;
|
||||
}
|
||||
}
|
||||
$r = q("select * from xchan where xchan_hash = '%s'",
|
||||
dbesc($xc['xchan_hash'])
|
||||
);
|
||||
if (! $r) {
|
||||
xchan_store_lowlevel($xc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach ($abook as $k => $v) {
|
||||
if (in_array($k, $disallowed) || (strpos($k, 'abook') !== 0)) {
|
||||
if (in_array($k, $disallowed) || (strpos($k, 'abook_') !== 0)) {
|
||||
continue;
|
||||
}
|
||||
if (!in_array($k, $fields)) {
|
||||
@@ -411,6 +464,13 @@ class Libsync {
|
||||
|
||||
if (array_key_exists('abook_instance', $clean) && $clean['abook_instance'] && strpos($clean['abook_instance'], z_root()) === false) {
|
||||
$clean['abook_not_here'] = 1;
|
||||
|
||||
// guest pass or access token - don't try to probe since it is one-way
|
||||
// we are relying on the undocumented behaviour that the abook record also contains the xchan
|
||||
if ($abook['xchan_network'] === 'token') {
|
||||
$clean['abook_instance'] .= ',';
|
||||
$clean['abook_instance'] .= z_root();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -684,7 +744,7 @@ class Libsync {
|
||||
*/
|
||||
call_hooks('process_channel_sync_delivery', $addon);
|
||||
|
||||
$DR = new DReport(z_root(), $d, $d, 'sync', 'channel sync delivered');
|
||||
$DR = new DReport(z_root(), $d, $d, $mid, 'channel sync processed');
|
||||
|
||||
$DR->set_name($channel['channel_name'] . ' <' . channel_reddress($channel) . '>');
|
||||
|
||||
@@ -706,8 +766,19 @@ class Libsync {
|
||||
static function sync_locations($sender, $arr, $absolute = false) {
|
||||
|
||||
$ret = [];
|
||||
$what = '';
|
||||
$changed = false;
|
||||
|
||||
if ($arr['locations']) {
|
||||
// If a sender reports that the channel has been deleted, delete its hubloc
|
||||
if (isset($arr['deleted_locally']) && intval($arr['deleted_locally'])) {
|
||||
q("UPDATE hubloc SET hubloc_deleted = 1, hubloc_updated = '%s' WHERE hubloc_hash = '%s' AND hubloc_url = '%s'",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($sender['hash']),
|
||||
dbesc($sender['site']['url'])
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($arr['locations']) && $arr['locations']) {
|
||||
|
||||
if ($absolute)
|
||||
Libzot::check_location_move($sender['hash'], $arr['locations']);
|
||||
@@ -760,14 +831,13 @@ class Libsync {
|
||||
|
||||
// match as many fields as possible in case anything at all changed.
|
||||
|
||||
$r = q("select * from hubloc where hubloc_hash = '%s' and hubloc_guid = '%s' and hubloc_guid_sig = '%s' and hubloc_id_url = '%s' and hubloc_url = '%s' and hubloc_url_sig = '%s' and hubloc_site_id = '%s' and hubloc_host = '%s' and hubloc_addr = '%s' and hubloc_callback = '%s' and hubloc_sitekey = '%s' ",
|
||||
$r = q("select * from hubloc where hubloc_hash = '%s' and hubloc_guid = '%s' and hubloc_guid_sig = '%s' and hubloc_id_url = '%s' and hubloc_url = '%s' and hubloc_url_sig = '%s' and hubloc_host = '%s' and hubloc_addr = '%s' and hubloc_callback = '%s' and hubloc_sitekey = '%s' ",
|
||||
dbesc($sender['hash']),
|
||||
dbesc($sender['id']),
|
||||
dbesc($sender['id_sig']),
|
||||
dbesc($location['id_url']),
|
||||
dbesc($location['url']),
|
||||
dbesc($location['url_sig']),
|
||||
dbesc($location['site_id']),
|
||||
dbesc($location['host']),
|
||||
dbesc($location['address']),
|
||||
dbesc($location['callback']),
|
||||
@@ -776,6 +846,15 @@ class Libsync {
|
||||
if ($r) {
|
||||
logger('Hub exists: ' . $location['url'], LOGGER_DEBUG);
|
||||
|
||||
// generate a new hubloc_site_id if it's wrong due to historical bugs 2021-11-30
|
||||
|
||||
if ($r[0]['hubloc_site_id'] !== $location['site_id']) {
|
||||
q("update hubloc set hubloc_site_id = '%s' where hubloc_id = %d",
|
||||
dbesc(Libzot::make_xchan_hash($location['url'], $location['sitekey'])),
|
||||
intval($r[0]['hubloc_id'])
|
||||
);
|
||||
}
|
||||
|
||||
// update connection timestamp if this is the site we're talking to
|
||||
// This only happens when called from import_xchan
|
||||
|
||||
@@ -864,6 +943,7 @@ class Libsync {
|
||||
$what .= 'delete_hub ';
|
||||
$changed = true;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -145,8 +145,8 @@ class Libzotdir {
|
||||
if(! $directory_sort_order)
|
||||
$directory_sort_order = 'date';
|
||||
|
||||
$current_order = (($_REQUEST['order']) ? $_REQUEST['order'] : $directory_sort_order);
|
||||
$suggest = (($_REQUEST['suggest']) ? '&suggest=' . $_REQUEST['suggest'] : '');
|
||||
$current_order = $_REQUEST['order'] ?? $directory_sort_order;
|
||||
$suggest = ((isset($_REQUEST['suggest'])) ? '&suggest=' . $_REQUEST['suggest'] : '');
|
||||
|
||||
$url = 'directory?f=';
|
||||
|
||||
@@ -207,8 +207,6 @@ class Libzotdir {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// If there are no directory servers, setup the fallback master
|
||||
/** @FIXME What to do if we're in a different realm? */
|
||||
|
||||
@@ -249,11 +247,12 @@ class Libzotdir {
|
||||
|
||||
$syncdate = (($rr['site_sync'] <= NULL_DATE) ? datetime_convert('UTC','UTC','now - 2 days') : $rr['site_sync']);
|
||||
$x = z_fetch_url($rr['site_directory'] . '?f=&sync=' . urlencode($syncdate) . (($token) ? '&t=' . $token : ''));
|
||||
|
||||
if (! $x['success'])
|
||||
continue;
|
||||
|
||||
$j = json_decode($x['body'],true);
|
||||
if (!($j['transactions']) || ($j['ratings']))
|
||||
if (!$j['transactions'])
|
||||
continue;
|
||||
|
||||
q("update site set site_sync = '%s' where site_url = '%s'",
|
||||
@@ -265,6 +264,11 @@ class Libzotdir {
|
||||
|
||||
if (is_array($j['transactions']) && count($j['transactions'])) {
|
||||
foreach ($j['transactions'] as $t) {
|
||||
|
||||
if (empty($t['hash']) || empty($t['transaction_id']) || empty($t['address'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$r = q("select * from updates where ud_guid = '%s' limit 1",
|
||||
dbesc($t['transaction_id'])
|
||||
);
|
||||
@@ -319,6 +323,14 @@ class Libzotdir {
|
||||
}
|
||||
if(array_path_exists('signature/signer',$zf) && $zf['signature']['signer'] === $href && intval($zf['signature']['header_valid'])) {
|
||||
$xc = Libzot::import_xchan($zf['data'], 0, $ud);
|
||||
// This is a workaround for a missing xchan_updated column
|
||||
// TODO: implement xchan_updated in the xchan table and update this column instead
|
||||
if($zf['data']['primary_location']['address'] && $zf['data']['primary_location']['url']) {
|
||||
q("UPDATE hubloc SET hubloc_updated = '%s' WHERE hubloc_id_url = '%s' AND hubloc_primary = 1",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($zf['data']['primary_location']['url'])
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
q("update updates set ud_last = '%s' where ud_addr = '%s'",
|
||||
@@ -345,7 +357,7 @@ class Libzotdir {
|
||||
|
||||
logger('local_dir_update: uid: ' . $uid, LOGGER_DEBUG);
|
||||
|
||||
$p = q("select channel.channel_hash, channel_address, channel_timezone, channel_portable_id, profile.* from profile left join channel on channel_id = uid where uid = %d and is_default = 1",
|
||||
$p = q("select channel.channel_hash, channel_address, channel_timezone, profile.* from profile left join channel on channel_id = uid where uid = %d and is_default = 1",
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
@@ -354,7 +366,6 @@ class Libzotdir {
|
||||
|
||||
if ($p) {
|
||||
$hash = $p[0]['channel_hash'];
|
||||
$legacy_hash = $p[0]['channel_portable_id'];
|
||||
|
||||
$profile['description'] = $p[0]['pdesc'];
|
||||
$profile['birthday'] = $p[0]['dob'];
|
||||
@@ -393,10 +404,9 @@ class Libzotdir {
|
||||
);
|
||||
|
||||
if(intval($r[0]['xchan_hidden']) != $hidden) {
|
||||
$r = q("update xchan set xchan_hidden = %d where xchan_hash in ('%s', '%s')",
|
||||
$r = q("update xchan set xchan_hidden = %d where xchan_hash = '%s'",
|
||||
intval($hidden),
|
||||
dbesc($hash),
|
||||
dbesc($legacy_hash)
|
||||
dbesc($hash)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -410,13 +420,11 @@ class Libzotdir {
|
||||
}
|
||||
else {
|
||||
// they may have made it private
|
||||
q("delete from xprof where xprof_hash in ('%s', '%s')",
|
||||
dbesc($hash),
|
||||
dbesc($legacy_hash)
|
||||
q("delete from xprof where xprof_hash = '%s'",
|
||||
dbesc($hash)
|
||||
);
|
||||
q("delete from xtag where xtag_hash in ('%s', '%s')",
|
||||
dbesc($hash),
|
||||
dbesc($legacy_hash)
|
||||
q("delete from xtag where xtag_hash = '%s'",
|
||||
dbesc($hash)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -445,22 +453,29 @@ class Libzotdir {
|
||||
if (! $hash)
|
||||
return false;
|
||||
|
||||
$arr = array();
|
||||
$arr = [];
|
||||
|
||||
$arr['xprof_hash'] = $hash;
|
||||
$arr['xprof_dob'] = (($profile['birthday'] === '0000-00-00') ? $profile['birthday'] : datetime_convert('','',$profile['birthday'],'Y-m-d')); // !!!! check this for 0000 year
|
||||
$arr['xprof_age'] = (($profile['age']) ? intval($profile['age']) : 0);
|
||||
$arr['xprof_desc'] = (($profile['description']) ? htmlspecialchars($profile['description'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_gender'] = (($profile['gender']) ? htmlspecialchars($profile['gender'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_marital'] = (($profile['marital']) ? htmlspecialchars($profile['marital'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_sexual'] = (($profile['sexual']) ? htmlspecialchars($profile['sexual'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_locale'] = (($profile['locale']) ? htmlspecialchars($profile['locale'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_region'] = (($profile['region']) ? htmlspecialchars($profile['region'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_postcode'] = (($profile['postcode']) ? htmlspecialchars($profile['postcode'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_country'] = (($profile['country']) ? htmlspecialchars($profile['country'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_about'] = (($profile['about']) ? htmlspecialchars($profile['about'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_homepage'] = (($profile['homepage']) ? htmlspecialchars($profile['homepage'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_hometown'] = (($profile['hometown']) ? htmlspecialchars($profile['hometown'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_hash'] = $hash;
|
||||
$arr['xprof_dob'] = '0000-00-00';
|
||||
|
||||
if (isset($profile['birthday'])) {
|
||||
$arr['xprof_dob'] = (($profile['birthday'] === '0000-00-00')
|
||||
? $profile['birthday']
|
||||
: datetime_convert('', '', $profile['birthday'], 'Y-m-d')); // !!!! check this for 0000 year
|
||||
}
|
||||
|
||||
$arr['xprof_age'] = ((isset($profile['age']) && $profile['age']) ? intval($profile['age']) : 0);
|
||||
$arr['xprof_desc'] = ((isset($profile['description']) && $profile['description']) ? htmlspecialchars($profile['description'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_gender'] = ((isset($profile['gender']) && $profile['gender']) ? htmlspecialchars($profile['gender'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_marital'] = ((isset($profile['marital']) && $profile['marital']) ? htmlspecialchars($profile['marital'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_sexual'] = ((isset($profile['sexual']) && $profile['sexual']) ? htmlspecialchars($profile['sexual'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_locale'] = ((isset($profile['locale']) && $profile['locale']) ? htmlspecialchars($profile['locale'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_region'] = ((isset($profile['region']) && $profile['region']) ? htmlspecialchars($profile['region'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_postcode'] = ((isset($profile['postcode']) && $profile['postcode']) ? htmlspecialchars($profile['postcode'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_country'] = ((isset($profile['country']) && $profile['country']) ? htmlspecialchars($profile['country'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_about'] = ((isset($profile['about']) && $profile['about']) ? htmlspecialchars($profile['about'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_homepage'] = ((isset($profile['homepage']) && $profile['homepage']) ? htmlspecialchars($profile['homepage'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_hometown'] = ((isset($profile['hometown']) && $profile['hometown']) ? htmlspecialchars($profile['hometown'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
|
||||
$clean = array();
|
||||
if (array_key_exists('keywords', $profile) and is_array($profile['keywords'])) {
|
||||
@@ -635,8 +650,13 @@ class Libzotdir {
|
||||
|
||||
$dirmode = intval(get_config('system', 'directory_mode'));
|
||||
|
||||
if($dirmode == DIRECTORY_MODE_NORMAL)
|
||||
if($dirmode == DIRECTORY_MODE_NORMAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($hash) || empty($guid) || empty($addr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if($flags) {
|
||||
q("insert into updates (ud_hash, ud_guid, ud_date, ud_flags, ud_addr ) values ( '%s', '%s', '%s', %d, '%s' )",
|
||||
@@ -656,9 +676,4 @@ class Libzotdir {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -2,87 +2,120 @@
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
|
||||
require_once('include/html2plain.php');
|
||||
|
||||
class MessageFilter {
|
||||
|
||||
public static function evaluate($item, $incl, $excl) {
|
||||
|
||||
static public function evaluate($item,$incl,$excl) {
|
||||
|
||||
require_once('include/html2plain.php');
|
||||
|
||||
unobscure($item);
|
||||
|
||||
$text = prepare_text($item['body'],$item['mimetype']);
|
||||
$text = prepare_text($item['body'],((isset($item['mimetype'])) ? $item['mimetype'] : 'text/bbcode'));
|
||||
$text = html2plain(($item['title']) ? $item['title'] . ' ' . $text : $text);
|
||||
|
||||
|
||||
$lang = null;
|
||||
|
||||
if((strpos($incl,'lang=') !== false) || (strpos($excl,'lang=') !== false) || (strpos($incl,'lang!=') !== false) || (strpos($excl,'lang!=') !== false)) {
|
||||
if ((strpos($incl, 'lang=') !== false) || (strpos($excl, 'lang=') !== false) || (strpos($incl, 'lang!=') !== false) || (strpos($excl, 'lang!=') !== false)) {
|
||||
$lang = detect_language($text);
|
||||
}
|
||||
|
||||
$tags = ((is_array($item['term']) && count($item['term'])) ? $item['term'] : false);
|
||||
$tags = ((isset($item['term']) && is_array($item['term']) && count($item['term'])) ? $item['term'] : false);
|
||||
|
||||
// exclude always has priority
|
||||
|
||||
$exclude = (($excl) ? explode("\n",$excl) : null);
|
||||
$exclude = (($excl) ? explode("\n", $excl) : null);
|
||||
|
||||
if($exclude) {
|
||||
foreach($exclude as $word) {
|
||||
if ($exclude) {
|
||||
foreach ($exclude as $word) {
|
||||
$word = trim($word);
|
||||
if(! $word)
|
||||
if (! $word) {
|
||||
continue;
|
||||
if(substr($word,0,1) === '#' && $tags) {
|
||||
foreach($tags as $t)
|
||||
if((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*')))
|
||||
return false;
|
||||
}
|
||||
elseif(substr($word,0,1) === '$' && $tags) {
|
||||
foreach($tags as $t)
|
||||
if(($t['ttype'] == TERM_CATEGORY) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*')))
|
||||
return false;
|
||||
if (isset($lang) && ((strpos($word, 'lang=') === 0) || (strpos($word, 'lang!=') === 0))) {
|
||||
if (!strlen($lang)) {
|
||||
// Result is ambiguous. As we are matching deny rules only at this time, continue tests.
|
||||
// Any matching deny rule concludes testing.
|
||||
continue;
|
||||
}
|
||||
if (strpos($word, 'lang=') === 0 && strcasecmp($lang, trim(substr($word, 5))) == 0) {
|
||||
return false;
|
||||
} elseif (strpos($word, 'lang!=') === 0 && strcasecmp($lang, trim(substr($word, 6))) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
elseif((strpos($word,'/') === 0) && preg_match($word,$text))
|
||||
elseif (substr($word, 0, 1) === '#' && $tags) {
|
||||
foreach ($tags as $t) {
|
||||
if ((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word, 1)) || (substr($word, 1) === '*'))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} elseif (substr($word, 0, 1) === '$' && $tags) {
|
||||
foreach ($tags as $t) {
|
||||
if (($t['ttype'] == TERM_CATEGORY) && (($t['term'] === substr($word, 1)) || (substr($word, 1) === '*'))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} elseif (substr($word, 0, 2) === '?+') {
|
||||
if (self::test_condition(substr($word, 2), $item['obj'])) {
|
||||
return false;
|
||||
}
|
||||
} elseif (substr($word, 0, 1) === '?') {
|
||||
if (self::test_condition(substr($word, 1), $item)) {
|
||||
return false;
|
||||
}
|
||||
} elseif ((strpos($word, '/') === 0) && preg_match($word, $text)) {
|
||||
return false;
|
||||
elseif((strpos($word,'lang=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,5))) == 0))
|
||||
return false;
|
||||
elseif((strpos($word,'lang!=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,6))) != 0))
|
||||
return false;
|
||||
elseif(stristr($text,$word) !== false)
|
||||
} elseif (stristr($text, $word) !== false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$include = (($incl) ? explode("\n",$incl) : null);
|
||||
$include = (($incl) ? explode("\n", $incl) : null);
|
||||
|
||||
if($include) {
|
||||
foreach($include as $word) {
|
||||
if ($include) {
|
||||
foreach ($include as $word) {
|
||||
$word = trim($word);
|
||||
if(! $word)
|
||||
if (! $word) {
|
||||
continue;
|
||||
if(substr($word,0,1) === '#' && $tags) {
|
||||
foreach($tags as $t)
|
||||
if((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*')))
|
||||
return true;
|
||||
}
|
||||
elseif(substr($word,0,1) === '$' && $tags) {
|
||||
foreach($tags as $t)
|
||||
if(($t['ttype'] == TERM_CATEGORY) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*')))
|
||||
return true;
|
||||
if (isset($lang) && ((strpos($word, 'lang=') === 0) || (strpos($word, 'lang!=') === 0))) {
|
||||
if (!strlen($lang)) {
|
||||
// Result is ambiguous. However we are checking allow rules
|
||||
// and an ambiguous language is always permitted.
|
||||
return true;
|
||||
}
|
||||
if (strpos($word, 'lang=') === 0 && strcasecmp($lang, trim(substr($word, 5))) == 0) {
|
||||
return true;
|
||||
} elseif (strpos($word, 'lang!=') === 0 && strcasecmp($lang, trim(substr($word, 6))) != 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
elseif((strpos($word,'/') === 0) && preg_match($word,$text))
|
||||
elseif (substr($word, 0, 1) === '#' && $tags) {
|
||||
foreach ($tags as $t) {
|
||||
if ((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word, 1)) || (substr($word, 1) === '*'))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} elseif (substr($word, 0, 1) === '$' && $tags) {
|
||||
foreach ($tags as $t) {
|
||||
if (($t['ttype'] == TERM_CATEGORY) && (($t['term'] === substr($word, 1)) || (substr($word, 1) === '*'))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} elseif (substr($word, 0, 2) === '?+') {
|
||||
if (self::test_condition(substr($word, 2), $item['obj'])) {
|
||||
return true;
|
||||
}
|
||||
} elseif (substr($word, 0, 1) === '?') {
|
||||
if (self::test_condition(substr($word, 1), $item)) {
|
||||
return true;
|
||||
}
|
||||
} elseif ((strpos($word, '/') === 0) && preg_match($word, $text)) {
|
||||
return true;
|
||||
elseif((strpos($word,'lang=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,5))) == 0))
|
||||
return true;
|
||||
elseif((strpos($word,'lang!=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,6))) != 0))
|
||||
return true;
|
||||
elseif(stristr($text,$word) !== false)
|
||||
} elseif (stristr($text, $word) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -90,4 +123,123 @@ class MessageFilter {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Test for Conditional Execution conditions. Shamelessly ripped off from Code/Render/Comanche
|
||||
*
|
||||
* This is extensible. The first version of variable testing supports tests of the forms:
|
||||
*
|
||||
* - ?foo ~= baz which will check if item.foo contains the string 'baz';
|
||||
* - ?foo == baz which will check if item.foo is the string 'baz';
|
||||
* - ?foo != baz which will check if item.foo is not the string 'baz';
|
||||
* - ?foo >= 3 which will check if item.foo is greater than or equal to 3;
|
||||
* - ?foo > 3 which will check if item.foo is greater than 3;
|
||||
* - ?foo <= 3 which will check if item.foo is less than or equal to 3;
|
||||
* - ?foo < 3 which will check if item.foo is less than 3;
|
||||
*
|
||||
* - ?foo {} baz which will check if 'baz' is an array element in item.foo
|
||||
* - ?foo {*} baz which will check if 'baz' is an array key in item.foo
|
||||
* - ?foo which will check for a return of a true condition for item.foo;
|
||||
* - ?!foo which will check for a return of a false condition for item.foo;
|
||||
*
|
||||
* The values 0, '', an empty array, and an unset value will all evaluate to false.
|
||||
*
|
||||
* @param string $s
|
||||
* @param array $item
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public static function test_condition($s,$item) {
|
||||
|
||||
if (preg_match('/(.*?)\s\~\=\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if (stripos($x, trim($matches[2])) !== false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/(.*?)\s\=\=\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x == trim($matches[2])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/(.*?)\s\!\=\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x != trim($matches[2])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/(.*?)\s\>\=\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x >= trim($matches[2])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/(.*?)\s\<\=\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x <= trim($matches[2])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/(.*?)\s\>\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x > trim($matches[2])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/(.*?)\s\>\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x < trim($matches[2])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/[\$](.*?)\s\{\}\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if (is_array($x) && in_array(trim($matches[2]), $x)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/(.*?)\s\{\*\}\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if (is_array($x) && array_key_exists(trim($matches[2]), $x)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ordering of this check (for falsiness) with relation to the following one (check for truthiness) is important.
|
||||
if (preg_match('/\!(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if (!$x) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,324 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use Zotlabs\Lib\Libsync;
|
||||
|
||||
define ( 'NWIKI_ITEM_RESOURCE_TYPE', 'nwiki' );
|
||||
|
||||
class NativeWiki {
|
||||
|
||||
|
||||
public static function listwikis($channel, $observer_hash) {
|
||||
|
||||
$sql_extra = item_permissions_sql($channel['channel_id'], $observer_hash);
|
||||
$wikis = q("SELECT * FROM item
|
||||
WHERE resource_type = '%s' AND mid = parent_mid AND uid = %d AND item_deleted = 0 $sql_extra",
|
||||
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
if($wikis) {
|
||||
foreach($wikis as &$w) {
|
||||
|
||||
$w['json_allow_cid'] = acl2json($w['allow_cid']);
|
||||
$w['json_allow_gid'] = acl2json($w['allow_gid']);
|
||||
$w['json_deny_cid'] = acl2json($w['deny_cid']);
|
||||
$w['json_deny_gid'] = acl2json($w['deny_gid']);
|
||||
|
||||
$w['rawName'] = get_iconfig($w, 'wiki', 'rawName');
|
||||
$w['htmlName'] = escape_tags($w['rawName']);
|
||||
//$w['urlName'] = urlencode(urlencode($w['rawName']));
|
||||
$w['urlName'] = self::name_encode($w['rawName']);
|
||||
$w['mimeType'] = get_iconfig($w, 'wiki', 'mimeType');
|
||||
$w['typelock'] = get_iconfig($w, 'wiki', 'typelock');
|
||||
$w['lockstate'] = (($w['allow_cid'] || $w['allow_gid'] || $w['deny_cid'] || $w['deny_gid']) ? 'lock' : 'unlock');
|
||||
}
|
||||
}
|
||||
// TODO: query db for wikis the observer can access. Return with two lists, for read and write access
|
||||
return array('wikis' => $wikis);
|
||||
}
|
||||
|
||||
|
||||
public static function create_wiki($channel, $observer_hash, $wiki, $acl) {
|
||||
|
||||
$resource_id = new_uuid();
|
||||
$uuid = new_uuid();
|
||||
|
||||
$ac = $acl->get();
|
||||
$mid = z_root() . '/item/' . $uuid;
|
||||
|
||||
$arr = array(); // Initialize the array of parameters for the post
|
||||
$item_hidden = ((intval($wiki['postVisible']) === 0) ? 1 : 0);
|
||||
$wiki_url = z_root() . '/wiki/' . $channel['channel_address'] . '/' . $wiki['urlName'];
|
||||
$arr['aid'] = $channel['channel_account_id'];
|
||||
$arr['uuid'] = $uuid;
|
||||
$arr['uid'] = $channel['channel_id'];
|
||||
$arr['mid'] = $mid;
|
||||
$arr['parent_mid'] = $mid;
|
||||
$arr['item_hidden'] = $item_hidden;
|
||||
$arr['resource_type'] = NWIKI_ITEM_RESOURCE_TYPE;
|
||||
$arr['resource_id'] = $resource_id;
|
||||
$arr['owner_xchan'] = $channel['channel_hash'];
|
||||
$arr['author_xchan'] = $observer_hash;
|
||||
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']);
|
||||
$arr['llink'] = $arr['plink'];
|
||||
$arr['title'] = $wiki['htmlName']; // name of new wiki;
|
||||
$arr['allow_cid'] = $ac['allow_cid'];
|
||||
$arr['allow_gid'] = $ac['allow_gid'];
|
||||
$arr['deny_cid'] = $ac['deny_cid'];
|
||||
$arr['deny_gid'] = $ac['deny_gid'];
|
||||
$arr['item_wall'] = 1;
|
||||
$arr['item_origin'] = 1;
|
||||
$arr['item_thread_top'] = 1;
|
||||
$arr['item_private'] = intval($acl->is_private());
|
||||
$arr['verb'] = ACTIVITY_CREATE;
|
||||
$arr['obj_type'] = 'Document';
|
||||
$arr['body'] = '[table][tr][td][h1]New Wiki[/h1][/td][/tr][tr][td][zrl=' . $wiki_url . ']' . $wiki['htmlName'] . '[/zrl][/td][/tr][/table]';
|
||||
|
||||
$arr['public_policy'] = map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'view_wiki'),true);
|
||||
|
||||
// Save the wiki name information using iconfig. This is shareable.
|
||||
if(! set_iconfig($arr, 'wiki', 'rawName', $wiki['rawName'], true)) {
|
||||
return array('item' => null, 'success' => false);
|
||||
}
|
||||
if(! set_iconfig($arr, 'wiki', 'mimeType', $wiki['mimeType'], true)) {
|
||||
return array('item' => null, 'success' => false);
|
||||
}
|
||||
|
||||
set_iconfig($arr,'wiki','typelock',$wiki['typelock'],true);
|
||||
|
||||
$post = item_store($arr);
|
||||
|
||||
$item_id = $post['item_id'];
|
||||
|
||||
if($item_id) {
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier', 'activity', $item_id));
|
||||
return array('item' => $post['item'], 'item_id' => $item_id, 'success' => true);
|
||||
}
|
||||
else {
|
||||
return array('item' => null, 'success' => false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function update_wiki($channel_id, $observer_hash, $arr, $acl) {
|
||||
|
||||
$w = self::get_wiki($channel_id, $observer_hash, $arr['resource_id']);
|
||||
$item = $w['wiki'];
|
||||
|
||||
if(! $item) {
|
||||
return array('item' => null, 'success' => false);
|
||||
}
|
||||
|
||||
$x = $acl->get();
|
||||
|
||||
$item['allow_cid'] = $x['allow_cid'];
|
||||
$item['allow_gid'] = $x['allow_gid'];
|
||||
$item['deny_cid'] = $x['deny_cid'];
|
||||
$item['deny_gid'] = $x['deny_gid'];
|
||||
$item['item_private'] = intval($acl->is_private());
|
||||
|
||||
$update_title = false;
|
||||
|
||||
if($item['title'] !== $arr['updateRawName']) {
|
||||
$update_title = true;
|
||||
$item['title'] = $arr['updateRawName'];
|
||||
}
|
||||
|
||||
$update = item_store_update($item);
|
||||
|
||||
$item_id = $update['item_id'];
|
||||
|
||||
// update acl for any existing wiki pages
|
||||
|
||||
q("update item set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', item_private = %d where resource_type = 'nwikipage' and resource_id = '%s'",
|
||||
dbesc($item['allow_cid']),
|
||||
dbesc($item['allow_gid']),
|
||||
dbesc($item['deny_cid']),
|
||||
dbesc($item['deny_gid']),
|
||||
dbesc($item['item_private']),
|
||||
dbesc($arr['resource_id'])
|
||||
);
|
||||
|
||||
|
||||
if($update['item_id']) {
|
||||
info( t('Wiki updated successfully'));
|
||||
if($update_title) {
|
||||
// Update the wiki name information using iconfig.
|
||||
if(! set_iconfig($update['item_id'], 'wiki', 'rawName', $arr['updateRawName'], true)) {
|
||||
return array('item' => null, 'success' => false);
|
||||
}
|
||||
}
|
||||
return array('item' => $update['item'], 'item_id' => $update['item_id'], 'success' => $update['success']);
|
||||
}
|
||||
else {
|
||||
return array('item' => null, 'success' => false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function sync_a_wiki_item($uid,$id,$resource_id) {
|
||||
|
||||
$r = q("SELECT * from item WHERE uid = %d AND ( id = %d OR ( resource_type = '%s' and resource_id = '%s' )) ",
|
||||
intval($uid),
|
||||
intval($id),
|
||||
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
|
||||
dbesc($resource_id)
|
||||
);
|
||||
if($r) {
|
||||
|
||||
$q = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s'",
|
||||
dbesc($r[0]['resource_id'])
|
||||
);
|
||||
if($q) {
|
||||
$r = array_merge($r,$q);
|
||||
}
|
||||
xchan_query($r);
|
||||
$sync_item = fetch_post_tags($r);
|
||||
if($sync_item) {
|
||||
$pkt = [];
|
||||
foreach($sync_item as $w) {
|
||||
$pkt[] = encode_item($w,true);
|
||||
}
|
||||
Libsync::build_sync_packet($uid,array('wiki' => $pkt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function delete_wiki($channel_id,$observer_hash,$resource_id) {
|
||||
|
||||
$w = self::get_wiki($channel_id,$observer_hash,$resource_id);
|
||||
if(! $w['wiki']) {
|
||||
return [ 'success' => false ];
|
||||
}
|
||||
else {
|
||||
|
||||
$r = q("SELECT id FROM item WHERE uid = %s AND resource_id = '%s'",
|
||||
intval($channel_id),
|
||||
dbesc($resource_id)
|
||||
);
|
||||
|
||||
$ids = array_column($r, 'id');
|
||||
drop_items($ids, true, DROPITEM_PHASE1);
|
||||
|
||||
info(t('Wiki files deleted successfully'));
|
||||
|
||||
return [ 'success' => true ];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function get_wiki($channel_id, $observer_hash, $resource_id) {
|
||||
|
||||
$sql_extra = item_permissions_sql($channel_id,$observer_hash);
|
||||
|
||||
$item = q("SELECT * FROM item WHERE uid = %d AND resource_type = '%s' AND resource_id = '%s' AND item_deleted = 0
|
||||
$sql_extra ORDER BY id LIMIT 1",
|
||||
intval($channel_id),
|
||||
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
|
||||
dbesc($resource_id)
|
||||
);
|
||||
if(! $item) {
|
||||
return [ 'wiki' => null ];
|
||||
}
|
||||
else {
|
||||
|
||||
$w = $item[0]; // wiki item table record
|
||||
// Get wiki metadata
|
||||
$rawName = get_iconfig($w, 'wiki', 'rawName');
|
||||
$mimeType = get_iconfig($w, 'wiki', 'mimeType');
|
||||
$typelock = get_iconfig($w, 'wiki', 'typelock');
|
||||
|
||||
return array(
|
||||
'wiki' => $w,
|
||||
'rawName' => $rawName,
|
||||
'htmlName' => escape_tags($rawName),
|
||||
//'urlName' => urlencode(urlencode($rawName)),
|
||||
'urlName' => self::name_encode($rawName),
|
||||
'mimeType' => $mimeType,
|
||||
'typelock' => $typelock
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function exists_by_name($uid, $urlName) {
|
||||
|
||||
$sql_extra = item_permissions_sql($uid);
|
||||
|
||||
$item = q("SELECT item.id, resource_id FROM item left join iconfig on iconfig.iid = item.id
|
||||
WHERE resource_type = '%s' AND iconfig.v = '%s' AND uid = %d
|
||||
AND item_deleted = 0 $sql_extra limit 1",
|
||||
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
|
||||
//dbesc(urldecode($urlName)),
|
||||
dbesc(self::name_decode($urlName)),
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
if($item) {
|
||||
return array('id' => $item[0]['id'], 'resource_id' => $item[0]['resource_id']);
|
||||
}
|
||||
else {
|
||||
return array('id' => null, 'resource_id' => null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function get_permissions($resource_id, $owner_id, $observer_hash) {
|
||||
|
||||
// TODO: For now, only the owner can edit
|
||||
$sql_extra = item_permissions_sql($owner_id, $observer_hash);
|
||||
|
||||
if(local_channel() && local_channel() == $owner_id) {
|
||||
return [ 'read' => true, 'write' => true, 'success' => true ];
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM item WHERE uid = %d and resource_type = '%s' AND resource_id = '%s' $sql_extra LIMIT 1",
|
||||
intval($owner_id),
|
||||
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
|
||||
dbesc($resource_id)
|
||||
);
|
||||
|
||||
if(! $r) {
|
||||
return array('read' => false, 'write' => false, 'success' => true);
|
||||
}
|
||||
else {
|
||||
// TODO: Create a new permission setting for wiki analogous to webpages. Until
|
||||
// then, use webpage permissions
|
||||
$write = perm_is_allowed($owner_id, $observer_hash,'write_wiki');
|
||||
return array('read' => true, 'write' => $write, 'success' => true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function name_encode ($string) {
|
||||
|
||||
$string = html_entity_decode($string);
|
||||
$encoding = mb_internal_encoding();
|
||||
mb_internal_encoding("UTF-8");
|
||||
$ret = mb_ereg_replace_callback ('[^A-Za-z0-9\-\_\.\~]',function ($char) {
|
||||
$charhex = unpack('H*',$char[0]);
|
||||
$ret = '('.$charhex[1].')';
|
||||
return $ret;
|
||||
}
|
||||
,$string);
|
||||
mb_internal_encoding($encoding);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
public static function name_decode ($string) {
|
||||
|
||||
$encoding = mb_internal_encoding();
|
||||
mb_internal_encoding("UTF-8");
|
||||
$ret = mb_ereg_replace_callback ('(\(([0-9a-f]+)\))',function ($chars) {
|
||||
return pack('H*',$chars[2]);
|
||||
}
|
||||
,$string);
|
||||
mb_internal_encoding($encoding);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,718 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use \Zotlabs\Lib as Zlib;
|
||||
|
||||
class NativeWikiPage {
|
||||
|
||||
static public function page_list($channel_id,$observer_hash, $resource_id) {
|
||||
|
||||
// TODO: Create item table records for pages so that metadata like title can be applied
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id,$observer_hash,$resource_id);
|
||||
|
||||
$pages[] = [
|
||||
'resource_id' => '',
|
||||
'title' => 'Home',
|
||||
'url' => 'Home',
|
||||
'link_id' => 'id_wiki_home_0'
|
||||
];
|
||||
|
||||
$sql_extra = item_permissions_sql($channel_id,$observer_hash);
|
||||
|
||||
$r = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' and uid = %d and item_deleted = 0
|
||||
$sql_extra order by title asc",
|
||||
dbesc($resource_id),
|
||||
intval($channel_id)
|
||||
);
|
||||
if($r) {
|
||||
$x = [];
|
||||
$y = [];
|
||||
|
||||
foreach($r as $rv) {
|
||||
if(! in_array($rv['mid'],$x)) {
|
||||
$y[] = $rv;
|
||||
$x[] = $rv['mid'];
|
||||
}
|
||||
}
|
||||
|
||||
$items = fetch_post_tags($y,true);
|
||||
|
||||
foreach($items as $page_item) {
|
||||
$title = get_iconfig($page_item['id'],'nwikipage','pagetitle',t('(No Title)'));
|
||||
if(urldecode($title) !== 'Home') {
|
||||
$pages[] = [
|
||||
'resource_id' => $resource_id,
|
||||
'title' => escape_tags($title),
|
||||
//'url' => str_replace('%2F','/',urlencode(str_replace('%2F','/',urlencode($title)))),
|
||||
'url' => Zlib\NativeWiki::name_encode($title),
|
||||
'link_id' => 'id_' . substr($resource_id, 0, 10) . '_' . $page_item['id']
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array('pages' => $pages, 'wiki' => $w);
|
||||
}
|
||||
|
||||
|
||||
static public function create_page($channel_id, $observer_hash, $name, $resource_id, $mimetype = 'text/bbcode') {
|
||||
|
||||
logger('mimetype: ' . $mimetype);
|
||||
|
||||
if(! in_array($mimetype,[ 'text/markdown','text/bbcode','text/plain','text/html' ]))
|
||||
$mimetype = 'text/markdown';
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
|
||||
if (! $w['wiki']) {
|
||||
return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
|
||||
}
|
||||
|
||||
// backslashes won't work well in the javascript functions
|
||||
$name = str_replace('\\','',$name);
|
||||
|
||||
// create an empty activity
|
||||
|
||||
$arr = [];
|
||||
$arr['uid'] = $channel_id;
|
||||
$arr['author_xchan'] = $observer_hash;
|
||||
$arr['mimetype'] = $mimetype;
|
||||
$arr['title'] = $name;
|
||||
$arr['resource_type'] = 'nwikipage';
|
||||
$arr['resource_id'] = $resource_id;
|
||||
$arr['allow_cid'] = $w['wiki']['allow_cid'];
|
||||
$arr['allow_gid'] = $w['wiki']['allow_gid'];
|
||||
$arr['deny_cid'] = $w['wiki']['deny_cid'];
|
||||
$arr['deny_gid'] = $w['wiki']['deny_gid'];
|
||||
|
||||
$arr['public_policy'] = map_scope(\Zotlabs\Access\PermissionLimits::Get($channel_id,'view_wiki'),true);
|
||||
|
||||
// We may wish to change this some day.
|
||||
$arr['item_unpublished'] = 1;
|
||||
|
||||
set_iconfig($arr,'nwikipage','pagetitle',(($name) ? $name : t('(No Title)')),true);
|
||||
|
||||
$p = post_activity_item($arr, false, false);
|
||||
|
||||
if($p['item_id']) {
|
||||
$page = [
|
||||
'rawName' => $name,
|
||||
'htmlName' => escape_tags($name),
|
||||
//'urlName' => urlencode($name),
|
||||
'urlName' => Zlib\NativeWiki::name_encode($name)
|
||||
|
||||
];
|
||||
|
||||
return array('page' => $page, 'item_id' => $p['item_id'], 'item' => $p['activity'], 'wiki' => $w, 'message' => '', 'success' => true);
|
||||
}
|
||||
return [ 'success' => false, 'message' => t('Wiki page create failed.') ];
|
||||
}
|
||||
|
||||
|
||||
static public function rename_page($arr) {
|
||||
|
||||
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
|
||||
$pageNewName = ((array_key_exists('pageNewName',$arr)) ? $arr['pageNewName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
|
||||
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if(! $w['wiki']) {
|
||||
return array('message' => t('Wiki not found.'), 'success' => false);
|
||||
}
|
||||
|
||||
|
||||
$ic = q("select * from iconfig left join item on iconfig.iid = item.id
|
||||
where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
|
||||
intval($channel_id),
|
||||
dbesc($pageNewName)
|
||||
);
|
||||
|
||||
if($ic) {
|
||||
return [ 'success' => false, 'message' => t('Destination name already exists') ];
|
||||
}
|
||||
|
||||
|
||||
$ids = [];
|
||||
|
||||
$ic = q("select *, item.id as item_id from iconfig left join item on iconfig.iid = item.id
|
||||
where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
|
||||
intval($channel_id),
|
||||
dbesc($pageUrlName)
|
||||
);
|
||||
|
||||
if($ic) {
|
||||
foreach($ic as $c) {
|
||||
set_iconfig($c['item_id'],'nwikipage','pagetitle',$pageNewName);
|
||||
$ids[] = $c['item_id'];
|
||||
}
|
||||
|
||||
$str_ids = implode(',', $ids);
|
||||
q("update item set title = '%s' where id in ($str_ids)",
|
||||
dbesc($pageNewName)
|
||||
);
|
||||
|
||||
$page = [
|
||||
'rawName' => $pageNewName,
|
||||
'htmlName' => escape_tags($pageNewName),
|
||||
//'urlName' => urlencode(escape_tags($pageNewName))
|
||||
'urlName' => Zlib\NativeWiki::name_encode($pageNewName)
|
||||
];
|
||||
|
||||
return [ 'success' => true, 'page' => $page ];
|
||||
}
|
||||
|
||||
return [ 'success' => false, 'message' => t('Page not found') ];
|
||||
|
||||
}
|
||||
|
||||
|
||||
static public function get_page_content($arr) {
|
||||
|
||||
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
|
||||
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id',$arr)) ? intval($arr['channel_id']) : 0);
|
||||
$revision = ((array_key_exists('revision',$arr)) ? intval($arr['revision']) : (-1));
|
||||
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if (! $w['wiki']) {
|
||||
return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
|
||||
}
|
||||
|
||||
$item = self::load_page($arr);
|
||||
|
||||
if($item) {
|
||||
$content = $item['body'];
|
||||
|
||||
return [
|
||||
'content' => $content,
|
||||
'mimeType' => $w['mimeType'],
|
||||
'pageMimeType' => $item['mimetype'],
|
||||
'message' => '',
|
||||
'success' => true
|
||||
];
|
||||
}
|
||||
|
||||
return array('content' => null, 'message' => t('Error reading page content'), 'success' => false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static public function page_history($arr) {
|
||||
|
||||
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
|
||||
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if (!$w['wiki']) {
|
||||
return array('history' => null, 'message' => 'Error reading wiki', 'success' => false);
|
||||
}
|
||||
|
||||
$items = self::load_page_history($arr);
|
||||
|
||||
$history = [];
|
||||
|
||||
if($items) {
|
||||
$processed = 0;
|
||||
foreach($items as $item) {
|
||||
if($processed > 1000)
|
||||
break;
|
||||
$processed ++;
|
||||
$history[] = [
|
||||
'revision' => $item['revision'],
|
||||
'date' => datetime_convert('UTC',date_default_timezone_get(),$item['edited']),
|
||||
'name' => $item['author']['xchan_name'],
|
||||
'title' => get_iconfig($item,'nwikipage','commit_msg')
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
return [ 'success' => true, 'history' => $history ];
|
||||
}
|
||||
|
||||
return [ 'success' => false ];
|
||||
|
||||
}
|
||||
|
||||
|
||||
static public function load_page($arr) {
|
||||
|
||||
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
|
||||
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
|
||||
$revision = ((array_key_exists('revision',$arr)) ? $arr['revision'] : (-1));
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
|
||||
if (! $w['wiki']) {
|
||||
return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
|
||||
}
|
||||
|
||||
$ids = '';
|
||||
|
||||
$ic = q("select * from iconfig left join item on iconfig.iid = item.id where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
|
||||
intval($channel_id),
|
||||
dbesc($pageUrlName)
|
||||
);
|
||||
|
||||
if($ic) {
|
||||
foreach($ic as $c) {
|
||||
if($ids)
|
||||
$ids .= ',';
|
||||
$ids .= intval($c['iid']);
|
||||
}
|
||||
}
|
||||
|
||||
$sql_extra = item_permissions_sql($channel_id,$observer_hash);
|
||||
|
||||
if($revision == (-1))
|
||||
$sql_extra .= " order by revision desc ";
|
||||
elseif($revision)
|
||||
$sql_extra .= " and revision = " . intval($revision) . " ";
|
||||
|
||||
$r = null;
|
||||
|
||||
|
||||
if($ids) {
|
||||
$r = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' and uid = %d and id in ( $ids ) $sql_extra limit 1",
|
||||
dbesc($resource_id),
|
||||
intval($channel_id)
|
||||
);
|
||||
|
||||
if($r) {
|
||||
$items = fetch_post_tags($r,true);
|
||||
return $items[0];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
static public function load_page_history($arr) {
|
||||
|
||||
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
|
||||
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
|
||||
$revision = ((array_key_exists('revision',$arr)) ? $arr['revision'] : (-1));
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if (! $w['wiki']) {
|
||||
return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
|
||||
}
|
||||
|
||||
$ids = '';
|
||||
|
||||
$ic = q("select * from iconfig left join item on iconfig.iid = item.id where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
|
||||
intval($channel_id),
|
||||
dbesc($pageUrlName)
|
||||
);
|
||||
|
||||
if($ic) {
|
||||
foreach($ic as $c) {
|
||||
if($ids)
|
||||
$ids .= ',';
|
||||
$ids .= intval($c['iid']);
|
||||
}
|
||||
}
|
||||
|
||||
$sql_extra = item_permissions_sql($channel_id,$observer_hash);
|
||||
|
||||
$sql_extra .= " order by revision desc ";
|
||||
|
||||
$r = null;
|
||||
if($ids) {
|
||||
$r = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' and uid = %d and id in ( $ids ) and item_deleted = 0 $sql_extra",
|
||||
dbesc($resource_id),
|
||||
intval($channel_id)
|
||||
);
|
||||
if($r) {
|
||||
xchan_query($r);
|
||||
$items = fetch_post_tags($r,true);
|
||||
return $items;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
static public function save_page($arr) {
|
||||
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
|
||||
$content = ((array_key_exists('content',$arr)) ? $arr['content'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
|
||||
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
|
||||
$revision = ((array_key_exists('revision',$arr)) ? $arr['revision'] : 0);
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
|
||||
if (!$w['wiki']) {
|
||||
return array('message' => t('Error reading wiki'), 'success' => false);
|
||||
}
|
||||
|
||||
|
||||
// fetch the most recently saved revision.
|
||||
|
||||
$item = self::load_page($arr);
|
||||
|
||||
if(! $item) {
|
||||
return array('message' => t('Page not found'), 'success' => false);
|
||||
}
|
||||
|
||||
$mimetype = $item['mimetype'];
|
||||
|
||||
// change just the fields we need to change to create a revision;
|
||||
|
||||
unset($item['id']);
|
||||
unset($item['author']);
|
||||
$item['parent'] = 0;
|
||||
$item['body'] = $content;
|
||||
$item['author_xchan'] = $observer_hash;
|
||||
$item['revision'] = (($arr['revision']) ? intval($arr['revision']) + 1 : intval($item['revision']) + 1);
|
||||
$item['edited'] = datetime_convert();
|
||||
$item['mimetype'] = $mimetype;
|
||||
|
||||
if($item['iconfig'] && is_array($item['iconfig']) && count($item['iconfig'])) {
|
||||
for($x = 0; $x < count($item['iconfig']); $x ++) {
|
||||
unset($item['iconfig'][$x]['id']);
|
||||
unset($item['iconfig'][$x]['iid']);
|
||||
}
|
||||
}
|
||||
|
||||
$ret = item_store($item, false, false);
|
||||
|
||||
if($ret['item_id'])
|
||||
return array('message' => '', 'item_id' => $ret['item_id'], 'filename' => $pageUrlName, 'success' => true);
|
||||
else
|
||||
return array('message' => t('Page update failed.'), 'success' => false);
|
||||
}
|
||||
|
||||
|
||||
static public function delete_page($arr) {
|
||||
|
||||
$pageUrlName = (array_key_exists('pageUrlName',$arr) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = (array_key_exists('resource_id',$arr) ? $arr['resource_id'] : '');
|
||||
$observer_hash = (array_key_exists('observer_hash',$arr) ? $arr['observer_hash'] : '');
|
||||
$channel_id = (array_key_exists('channel_id',$arr) ? $arr['channel_id'] : 0);
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if(! $w['wiki']) {
|
||||
return [ 'success' => false, 'message' => t('Error reading wiki') ];
|
||||
}
|
||||
|
||||
$ids = [];
|
||||
|
||||
$ic = q("select * from iconfig left join item on iconfig.iid = item.id
|
||||
where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
|
||||
intval($channel_id),
|
||||
dbesc($pageUrlName)
|
||||
);
|
||||
|
||||
if($ic) {
|
||||
foreach($ic as $c) {
|
||||
$ids[] = intval($c['iid']);
|
||||
}
|
||||
}
|
||||
|
||||
if($ids) {
|
||||
drop_items($ids, true, DROPITEM_PHASE1);
|
||||
return [ 'success' => true ];
|
||||
}
|
||||
|
||||
return [ 'success' => false, 'message' => t('Nothing deleted') ];
|
||||
}
|
||||
|
||||
|
||||
static public function revert_page($arr) {
|
||||
|
||||
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
|
||||
$commitHash = ((array_key_exists('commitHash',$arr)) ? $arr['commitHash'] : null);
|
||||
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
|
||||
|
||||
if (! $commitHash) {
|
||||
return array('message' => 'No commit was provided', 'success' => false);
|
||||
}
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if (!$w['wiki']) {
|
||||
return array('message' => 'Error reading wiki', 'success' => false);
|
||||
}
|
||||
|
||||
$x = $arr;
|
||||
|
||||
if(intval($commitHash) > 0) {
|
||||
unset($x['commitHash']);
|
||||
$x['revision'] = intval($commitHash) - 1;
|
||||
$loaded = self::load_page($x);
|
||||
|
||||
if($loaded) {
|
||||
$content = $loaded['body'];
|
||||
return [ 'content' => $content, 'success' => true ];
|
||||
}
|
||||
return [ 'success' => false ];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static public function compare_page($arr) {
|
||||
|
||||
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
|
||||
$currentCommit = ((array_key_exists('currentCommit',$arr)) ? $arr['currentCommit'] : (-1));
|
||||
$compareCommit = ((array_key_exists('compareCommit',$arr)) ? $arr['compareCommit'] : 0);
|
||||
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
|
||||
if (!$w['wiki']) {
|
||||
return array('message' => t('Error reading wiki'), 'success' => false);
|
||||
}
|
||||
|
||||
$x = $arr;
|
||||
$x['revision'] = (-1);
|
||||
|
||||
$currpage = self::load_page($x);
|
||||
if($currpage)
|
||||
$currentContent = $currpage['body'];
|
||||
|
||||
$x['revision'] = $compareCommit;
|
||||
$comppage = self::load_page($x);
|
||||
if($comppage)
|
||||
$compareContent = $comppage['body'];
|
||||
|
||||
if($currpage && $comppage) {
|
||||
require_once('library/class.Diff.php');
|
||||
$diff = \Diff::toTable(\Diff::compare($currentContent, $compareContent));
|
||||
|
||||
return [ 'success' => true, 'diff' => $diff ];
|
||||
}
|
||||
return [ 'success' => false, 'message' => t('Compare: object not found.') ];
|
||||
|
||||
}
|
||||
|
||||
|
||||
static public function commit($arr) {
|
||||
|
||||
$commit_msg = ((array_key_exists('commit_msg', $arr)) ? $arr['commit_msg'] : t('Page updated'));
|
||||
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
|
||||
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : t('Untitled'));
|
||||
|
||||
if(array_key_exists('resource_id', $arr)) {
|
||||
$resource_id = $arr['resource_id'];
|
||||
}
|
||||
else {
|
||||
return array('message' => t('Wiki resource_id required for git commit'), 'success' => false);
|
||||
}
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if (! $w['wiki']) {
|
||||
return array('message' => t('Error reading wiki'), 'success' => false);
|
||||
}
|
||||
|
||||
|
||||
$page = self::load_page($arr);
|
||||
|
||||
if($page) {
|
||||
set_iconfig($page['id'],'nwikipage','commit_msg',escape_tags($commit_msg),true);
|
||||
return [ 'success' => true, 'item_id' => $page['id'], 'page' => $page ];
|
||||
}
|
||||
|
||||
return [ 'success' => false, 'message' => t('Page not found.') ];
|
||||
|
||||
}
|
||||
|
||||
static public function convert_links($s, $wikiURL) {
|
||||
|
||||
if (strpos($s,'[[') !== false) {
|
||||
preg_match_all("/\[\[(.*?)\]\]/", $s, $match);
|
||||
$pages = $pageURLs = array();
|
||||
foreach ($match[1] as $m) {
|
||||
// TODO: Why do we need to double urlencode for this to work?
|
||||
//$pageURLs[] = urlencode(urlencode(escape_tags($m)));
|
||||
$titleUri = explode('|',$m);
|
||||
$page = $titleUri[0] ?? '';
|
||||
$title = $titleUri[1] ?? $page;
|
||||
$pageURLs[] = Zlib\NativeWiki::name_encode(escape_tags($page));
|
||||
$pages[] = $title;
|
||||
}
|
||||
$idx = 0;
|
||||
while(strpos($s,'[[') !== false) {
|
||||
$replace = '<a href="'.$wikiURL.'/'.$pageURLs[$idx].'">'.$pages[$idx].'</a>';
|
||||
$s = preg_replace("/\[\[(.*?)\]\]/", $replace, $s, 1);
|
||||
$idx++;
|
||||
}
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
static public function render_page_history($arr) {
|
||||
|
||||
$pageUrlName = ((array_key_exists('pageUrlName', $arr)) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
|
||||
|
||||
$pageHistory = self::page_history([
|
||||
'channel_id' => \App::$profile_uid,
|
||||
'observer_hash' => get_observer_hash(),
|
||||
'resource_id' => $resource_id,
|
||||
'pageUrlName' => $pageUrlName
|
||||
]);
|
||||
|
||||
return replace_macros(get_markup_template('nwiki_page_history.tpl'), array(
|
||||
'$pageHistory' => $pageHistory['history'],
|
||||
'$permsWrite' => $arr['permsWrite'],
|
||||
'$name_lbl' => t('Name'),
|
||||
'$msg_label' => t('Message','wiki_history'),
|
||||
'$date_lbl' => t('Date'),
|
||||
'$revert_btn' => t('Revert'),
|
||||
'$compare_btn' => t('Compare')
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replace the instances of the string [toc] with a list element that will be populated by
|
||||
* a table of contents by the JavaScript library
|
||||
* @param string $s
|
||||
* @return string
|
||||
*/
|
||||
static public function generate_toc($s) {
|
||||
if (strpos($s,'[toc]') !== false) {
|
||||
//$toc_md = wiki_toc($s); // Generate Markdown-formatted list prior to HTML render
|
||||
$toc_md = '<ul id="wiki-toc"></ul>'; // use the available jQuery plugin http://ndabas.github.io/toc/
|
||||
$s = preg_replace("/\[toc\]/", $toc_md, $s, -1);
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a select set of bbcode tags. Much of the code is copied from include/bbcode.php
|
||||
* @param string $s
|
||||
* @return string
|
||||
*/
|
||||
static public function bbcode($s) {
|
||||
|
||||
$s = str_replace(array('[baseurl]', '[sitename]'), array(z_root(), get_config('system', 'sitename')), $s);
|
||||
|
||||
$s = preg_replace_callback("/\[observer\.language\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_callback', $s);
|
||||
|
||||
$s = preg_replace_callback("/\[observer\.language\!\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_necallback', $s);
|
||||
|
||||
|
||||
$observer = \App::get_observer();
|
||||
if ($observer) {
|
||||
$s1 = '<span class="bb_observer" title="' . t('Different viewers will see this text differently') . '">';
|
||||
$s2 = '</span>';
|
||||
$obsBaseURL = $observer['xchan_connurl'];
|
||||
$obsBaseURL = preg_replace("/\/poco\/.*$/", '', $obsBaseURL);
|
||||
$s = str_replace('[observer.baseurl]', $obsBaseURL, $s);
|
||||
$s = str_replace('[observer.url]', $observer['xchan_url'], $s);
|
||||
$s = str_replace('[observer.name]', $s1 . $observer['xchan_name'] . $s2, $s);
|
||||
$s = str_replace('[observer.address]', $s1 . $observer['xchan_addr'] . $s2, $s);
|
||||
$s = str_replace('[observer.webname]', substr($observer['xchan_addr'], 0, strpos($observer['xchan_addr'], '@')), $s);
|
||||
$s = str_replace('[observer.photo]', '', $s);
|
||||
}
|
||||
else {
|
||||
$s = str_replace('[observer.baseurl]', '', $s);
|
||||
$s = str_replace('[observer.url]', '', $s);
|
||||
$s = str_replace('[observer.name]', '', $s);
|
||||
$s = str_replace('[observer.address]', '', $s);
|
||||
$s = str_replace('[observer.webname]', '', $s);
|
||||
$s = str_replace('[observer.photo]', '', $s);
|
||||
}
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
||||
static public function get_file_ext($arr) {
|
||||
|
||||
if($arr['mimetype'] === 'text/bbcode')
|
||||
return '.bb';
|
||||
elseif($arr['mimetype'] === 'text/markdown')
|
||||
return '.md';
|
||||
elseif($arr['mimetype'] === 'text/plain')
|
||||
return '.txt';
|
||||
|
||||
}
|
||||
|
||||
// This function is derived from
|
||||
// http://stackoverflow.com/questions/32068537/generate-table-of-contents-from-markdown-in-php
|
||||
static public function toc($content) {
|
||||
// ensure using only "\n" as line-break
|
||||
$source = str_replace(["\r\n", "\r"], "\n", $content);
|
||||
|
||||
// look for markdown TOC items
|
||||
preg_match_all(
|
||||
'/^(?:=|-|#).*$/m',
|
||||
$source,
|
||||
$matches,
|
||||
PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE
|
||||
);
|
||||
|
||||
// preprocess: iterate matched lines to create an array of items
|
||||
// where each item is an array(level, text)
|
||||
$file_size = strlen($source);
|
||||
foreach ($matches[0] as $item) {
|
||||
$found_mark = substr($item[0], 0, 1);
|
||||
if ($found_mark == '#') {
|
||||
// text is the found item
|
||||
$item_text = $item[0];
|
||||
$item_level = strrpos($item_text, '#') + 1;
|
||||
$item_text = substr($item_text, $item_level);
|
||||
} else {
|
||||
// text is the previous line (empty if <hr>)
|
||||
$item_offset = $item[1];
|
||||
$prev_line_offset = strrpos($source, "\n", -($file_size - $item_offset + 2));
|
||||
$item_text =
|
||||
substr($source, $prev_line_offset, $item_offset - $prev_line_offset - 1);
|
||||
$item_text = trim($item_text);
|
||||
$item_level = $found_mark == '=' ? 1 : 2;
|
||||
}
|
||||
if (!trim($item_text) OR strpos($item_text, '|') !== FALSE) {
|
||||
// item is an horizontal separator or a table header, don't mind
|
||||
continue;
|
||||
}
|
||||
$raw_toc[] = ['level' => $item_level, 'text' => trim($item_text)];
|
||||
}
|
||||
$o = '';
|
||||
foreach($raw_toc as $t) {
|
||||
$level = intval($t['level']);
|
||||
$text = $t['text'];
|
||||
switch ($level) {
|
||||
case 1:
|
||||
$li = '* ';
|
||||
break;
|
||||
case 2:
|
||||
$li = ' * ';
|
||||
break;
|
||||
case 3:
|
||||
$li = ' * ';
|
||||
break;
|
||||
case 4:
|
||||
$li = ' * ';
|
||||
break;
|
||||
default:
|
||||
$li = '* ';
|
||||
break;
|
||||
}
|
||||
$o .= $li . $text . "\n";
|
||||
}
|
||||
return $o;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use App;
|
||||
|
||||
/**
|
||||
* @brief Class for handling channel specific configurations.
|
||||
*
|
||||
@@ -32,15 +34,15 @@ class PConfig {
|
||||
if(is_null($uid) || $uid === false)
|
||||
return false;
|
||||
|
||||
if(! is_array(\App::$config)) {
|
||||
if(! is_array(App::$config)) {
|
||||
btlogger('App::$config not an array');
|
||||
}
|
||||
|
||||
if(! array_key_exists($uid, \App::$config)) {
|
||||
\App::$config[$uid] = array();
|
||||
if(! array_key_exists($uid, App::$config)) {
|
||||
App::$config[$uid] = array();
|
||||
}
|
||||
|
||||
if(! is_array(\App::$config[$uid])) {
|
||||
if(! is_array(App::$config[$uid])) {
|
||||
btlogger('App::$config[$uid] not an array: ' . $uid);
|
||||
}
|
||||
|
||||
@@ -52,12 +54,12 @@ class PConfig {
|
||||
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;
|
||||
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'];
|
||||
\App::$config[$uid][$c]['pcfgud:'.$k] = $rr['updated'];
|
||||
App::$config[$uid][$c][$k] = $rr['v'];
|
||||
App::$config[$uid][$c]['pcfgud:'.$k] = $rr['updated'];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,15 +88,15 @@ class PConfig {
|
||||
if(is_null($uid) || $uid === false)
|
||||
return $default;
|
||||
|
||||
if(! array_key_exists($uid, \App::$config))
|
||||
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])))
|
||||
if((! array_key_exists($family, App::$config[$uid])) || (! array_key_exists($key, App::$config[$uid][$family])))
|
||||
return $default;
|
||||
|
||||
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]
|
||||
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]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -133,6 +135,7 @@ class PConfig {
|
||||
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
|
||||
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
|
||||
$new = false;
|
||||
$update = false;
|
||||
|
||||
$now = datetime_convert();
|
||||
if (! $updated) {
|
||||
@@ -143,23 +146,22 @@ class PConfig {
|
||||
$updated = datetime_convert('UTC','UTC','-2 seconds');
|
||||
}
|
||||
|
||||
$hash = hash('sha256',$family.':'.$key);
|
||||
$hash = gen_link_id($family.':'.$key);
|
||||
|
||||
if (self::Get($uid, 'hz_delpconfig', $hash) !== false) {
|
||||
if (self::Get($uid, 'hz_delpconfig', $hash) > $now) {
|
||||
logger('Refusing to update pconfig with outdated info (Item deleted more recently).', LOGGER_NORMAL, LOG_ERR);
|
||||
return self::Get($uid,$family,$key);
|
||||
} else {
|
||||
self::Delete($uid,'hz_delpconfig',$hash);
|
||||
self::Delete($uid, 'hz_delpconfig', $hash);
|
||||
}
|
||||
}
|
||||
|
||||
if(self::Get($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();
|
||||
|
||||
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, updated ) VALUES ( %d, '%s', '%s', '%s', '%s' ) ",
|
||||
intval($uid),
|
||||
@@ -177,13 +179,14 @@ class PConfig {
|
||||
logger("Error: Insert to pconfig failed.",LOGGER_NORMAL, LOG_ERR);
|
||||
}
|
||||
|
||||
\App::$config[$uid][$family]['pcfgud:'.$key] = $updated;
|
||||
$new = true;
|
||||
App::$config[$uid][$family]['pcfgud:'.$key] = $updated;
|
||||
|
||||
}
|
||||
else {
|
||||
$new = (\App::$config[$uid][$family]['pcfgud:'.$key] < $now);
|
||||
$update = (App::$config[$uid][$family]['pcfgud:'.$key] < $now);
|
||||
|
||||
if ($new) {
|
||||
if ($update) {
|
||||
|
||||
// @NOTE There is still a possible race condition under limited circumstances
|
||||
// where a value will be updated by another thread with more current data than
|
||||
@@ -198,7 +201,7 @@ class PConfig {
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
\App::$config[$uid][$family]['pcfgud:'.$key] = $updated;
|
||||
App::$config[$uid][$family]['pcfgud:'.$key] = $updated;
|
||||
|
||||
} else {
|
||||
logger('Refusing to update pconfig with outdated info.', LOGGER_NORMAL, LOG_ERR);
|
||||
@@ -211,16 +214,16 @@ class PConfig {
|
||||
// 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();
|
||||
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][$family][$key] = $value;
|
||||
|
||||
if ($new) {
|
||||
\App::$config[$uid]['transient'][$family][$key] = $value;
|
||||
\App::$config[$uid]['transient'][$family]['pcfgud:'.$key] = $updated;
|
||||
if ($new || $update) {
|
||||
App::$config[$uid]['transient'][$family][$key] = $value;
|
||||
App::$config[$uid]['transient'][$family]['pcfgud:'.$key] = $updated;
|
||||
}
|
||||
|
||||
if($ret)
|
||||
@@ -253,7 +256,7 @@ class PConfig {
|
||||
|
||||
$updated = ($updated) ? $updated : datetime_convert('UTC','UTC','-2 seconds');
|
||||
$now = datetime_convert();
|
||||
$newer = (\App::$config[$uid][$family]['pcfgud:'.$key] < $now);
|
||||
$newer = (App::$config[$uid][$family]['pcfgud:'.$key] < $now);
|
||||
|
||||
if (! $newer) {
|
||||
logger('Refusing to delete pconfig with outdated delete request.', LOGGER_NORMAL, LOG_ERR);
|
||||
@@ -262,12 +265,12 @@ class PConfig {
|
||||
|
||||
$ret = false;
|
||||
|
||||
if (isset(\App::$config[$uid][$family][$key])) {
|
||||
unset(\App::$config[$uid][$family][$key]);
|
||||
if (isset(App::$config[$uid][$family][$key])) {
|
||||
unset(App::$config[$uid][$family][$key]);
|
||||
}
|
||||
|
||||
if (isset(\App::$config[$uid][$family]['pcfgud:'.$key])) {
|
||||
unset(\App::$config[$uid][$family]['pcfgud:'.$key]);
|
||||
if (isset(App::$config[$uid][$family]['pcfgud:'.$key])) {
|
||||
unset(App::$config[$uid][$family]['pcfgud:'.$key]);
|
||||
}
|
||||
|
||||
$ret = q("DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s'",
|
||||
@@ -278,9 +281,9 @@ class PConfig {
|
||||
|
||||
// Synchronize delete with clones.
|
||||
|
||||
if ($family != 'hz_delpconfig') {
|
||||
$hash = hash('sha256',$family.':'.$key);
|
||||
set_pconfig($uid,'hz_delpconfig',$hash,$updated);
|
||||
if ($family !== 'hz_delpconfig') {
|
||||
$hash = gen_link_id($family.':'.$key);
|
||||
set_pconfig($uid, 'hz_delpconfig', $hash, $updated);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Zotlabs\Lib;
|
||||
|
||||
use Zotlabs\Access\PermissionRoles;
|
||||
use Zotlabs\Access\Permissions;
|
||||
use Zotlabs\Daemon\Master;
|
||||
|
||||
/**
|
||||
* @brief Permission Categories. Permission rules for various classes of connections.
|
||||
@@ -38,33 +39,33 @@ class Permcat {
|
||||
|
||||
// first check role perms for a perms_connect setting
|
||||
|
||||
$role = get_pconfig($channel_id,'system','permissions_role');
|
||||
if($role) {
|
||||
$role = get_pconfig($channel_id, 'system', 'permissions_role');
|
||||
if ($role) {
|
||||
$x = PermissionRoles::role_perms($role);
|
||||
if($x['perms_connect']) {
|
||||
if ($x['perms_connect']) {
|
||||
$perms = Permissions::FilledPerms($x['perms_connect']);
|
||||
}
|
||||
}
|
||||
|
||||
// if no role perms it may be a custom role, see if there any autoperms
|
||||
|
||||
if(! $perms) {
|
||||
if (!$perms) {
|
||||
$perms = Permissions::FilledAutoPerms($channel_id);
|
||||
}
|
||||
|
||||
// if no autoperms it may be a custom role with manual perms
|
||||
|
||||
if(! $perms) {
|
||||
if (!$perms) {
|
||||
$r = q("select channel_hash from channel where channel_id = %d",
|
||||
intval($channel_id)
|
||||
);
|
||||
if($r) {
|
||||
if ($r) {
|
||||
$x = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'my_perms'",
|
||||
intval($channel_id),
|
||||
dbesc($r[0]['channel_hash'])
|
||||
);
|
||||
if($x) {
|
||||
foreach($x as $xv) {
|
||||
if ($x) {
|
||||
foreach ($x as $xv) {
|
||||
$perms[$xv['k']] = intval($xv['v']);
|
||||
}
|
||||
}
|
||||
@@ -73,25 +74,27 @@ class Permcat {
|
||||
|
||||
// nothing was found - create a filled permission array where all permissions are 0
|
||||
|
||||
if(! $perms) {
|
||||
if (!$perms) {
|
||||
$perms = Permissions::FilledPerms([]);
|
||||
}
|
||||
|
||||
$this->permcats[] = [
|
||||
'name' => 'default',
|
||||
'localname' => t('default','permcat'),
|
||||
'localname' => t('Default', 'permcat'),
|
||||
'perms' => Permissions::Operms($perms),
|
||||
'raw_perms' => $perms,
|
||||
'system' => 1
|
||||
];
|
||||
|
||||
|
||||
$p = $this->load_permcats($channel_id);
|
||||
if($p) {
|
||||
for($x = 0; $x < count($p); $x++) {
|
||||
if ($p) {
|
||||
for ($x = 0; $x < count($p); $x++) {
|
||||
$this->permcats[] = [
|
||||
'name' => $p[$x][0],
|
||||
'localname' => $p[$x][1],
|
||||
'perms' => Permissions::Operms(Permissions::FilledPerms($p[$x][2])),
|
||||
'raw_perms' => Permissions::FilledPerms($p[$x][2]),
|
||||
'system' => intval($p[$x][3])
|
||||
];
|
||||
}
|
||||
@@ -116,9 +119,9 @@ class Permcat {
|
||||
* * \e bool \b error if $name not found in permcats true
|
||||
*/
|
||||
public function fetch($name) {
|
||||
if($name && $this->permcats) {
|
||||
foreach($this->permcats as $permcat) {
|
||||
if(strcasecmp($permcat['name'], $name) === 0) {
|
||||
if ($name && $this->permcats) {
|
||||
foreach ($this->permcats as $permcat) {
|
||||
if (strcasecmp($permcat['name'], $name) === 0) {
|
||||
return $permcat;
|
||||
}
|
||||
}
|
||||
@@ -128,31 +131,28 @@ class Permcat {
|
||||
}
|
||||
|
||||
public function load_permcats($uid) {
|
||||
|
||||
/*
|
||||
$permcats = [
|
||||
[ 'follower', t('follower','permcat'),
|
||||
[ 'view_stream','view_profile','view_contacts','view_storage','view_pages','view_wiki',
|
||||
'post_like' ], 1
|
||||
],
|
||||
[ 'contributor', t('contributor','permcat'),
|
||||
[ 'view_stream','view_profile','view_contacts','view_storage','view_pages','view_wiki',
|
||||
'post_wall','post_comments','write_wiki','post_like','tag_deliver','chat' ], 1
|
||||
],
|
||||
[ 'publisher', t('publisher','permcat'),
|
||||
[ 'contributor', t('Contributor','permcat'),
|
||||
[ 'view_stream','view_profile','view_contacts','view_storage','view_pages',
|
||||
'write_storage','post_wall','write_pages','write_wiki','post_comments','post_like','tag_deliver',
|
||||
'chat', 'republish' ], 1
|
||||
]
|
||||
'write_storage','post_wall','write_pages','write_wiki','post_comments', 'post_mail', 'post_like',
|
||||
'chat' ], 1
|
||||
],
|
||||
[ 'muted', t('Muted','permcat'),
|
||||
[ 'view_stream','view_profile','view_contacts','view_storage','view_pages','view_wiki',
|
||||
'post_comments','write_wiki','post_like' ], 1
|
||||
],
|
||||
];
|
||||
|
||||
if($uid) {
|
||||
*/
|
||||
if ($uid) {
|
||||
$x = q("select * from pconfig where uid = %d and cat = 'permcat'",
|
||||
intval($uid)
|
||||
);
|
||||
if($x) {
|
||||
foreach($x as $xv) {
|
||||
$value = ((preg_match('|^a:[0-9]+:{.*}$|s', $xv['v'])) ? unserialize($xv['v']) : $xv['v']);
|
||||
$permcats[] = [ $xv['k'], $xv['k'], $value, 0 ];
|
||||
|
||||
if ($x) {
|
||||
foreach ($x as $xv) {
|
||||
$value = ((preg_match('|^a:[0-9]+:{.*}$|s', $xv['v'])) ? unserialize($xv['v']) : $xv['v']);
|
||||
$permcats[] = [$xv['k'], $xv['k'], $value, 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,11 +167,11 @@ class Permcat {
|
||||
}
|
||||
|
||||
static public function find_permcat($arr, $name) {
|
||||
if((! $arr) || (! $name))
|
||||
if ((!$arr) || (!$name))
|
||||
return false;
|
||||
|
||||
foreach($arr as $p)
|
||||
if($p['name'] == $name)
|
||||
foreach ($arr as $p)
|
||||
if ($p['name'] == $name)
|
||||
return $p['value'];
|
||||
}
|
||||
|
||||
@@ -183,4 +183,105 @@ class Permcat {
|
||||
PConfig::Delete($channel_id, 'permcat', $name);
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* @brief assign a contact role to contacts
|
||||
*
|
||||
* @param array $channel
|
||||
* @param string $role the name of the role
|
||||
* @param array $contacts an array of contact hashes
|
||||
*/
|
||||
public static function assign($channel, $role, $contacts) {
|
||||
|
||||
if (!isset($channel['channel_id'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_array($contacts) || empty($contacts)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$role) {
|
||||
// lookup the default
|
||||
$role = get_pconfig($channel['channel_id'], 'system', 'default_permcat', 'default');
|
||||
}
|
||||
|
||||
|
||||
// Doublecheck that we do not assign a role to ourself.
|
||||
// It does not make a difference but could be confusing.
|
||||
if (in_array($channel['channel_hash'], $contacts)) {
|
||||
$contacts = array_diff($contacts, [$channel['channel_hash']]);
|
||||
}
|
||||
|
||||
$all_perms = Permissions::Perms();
|
||||
$permcats = new Permcat($channel['channel_id']);
|
||||
$role_perms = $permcats->fetch($role);
|
||||
|
||||
if (isset($role_perms['error'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$perms = $role_perms['raw_perms'];
|
||||
|
||||
$values_sql = '';
|
||||
stringify_array_elms($contacts, true);
|
||||
|
||||
if ($all_perms && $perms) {
|
||||
|
||||
foreach ($contacts as $contact) {
|
||||
foreach ($all_perms as $perm => $desc) {
|
||||
if (array_key_exists($perm, $perms)) {
|
||||
$values_sql .= " (" . intval($channel['channel_id']) . ", " . protect_sprintf($contact) . ", 'my_perms', '" . dbesc($perm) . "', " . intval($perms[$perm]) . "),";
|
||||
}
|
||||
else {
|
||||
$values_sql .= " (" . intval($channel['channel_id']) . ", " . protect_sprintf($contact) . ", 'my_perms', '" . dbesc($perm) . "', 0), ";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$values_sql = rtrim($values_sql, ',');
|
||||
|
||||
dbq("DELETE FROM abconfig WHERE chan = " . intval($channel['channel_id']) . " AND cat = 'my_perms' AND xchan IN (" . protect_sprintf(implode(',', $contacts)) . ")");
|
||||
|
||||
dbq("INSERT INTO abconfig ( chan, xchan, cat, k, v ) VALUES $values_sql");
|
||||
|
||||
q("UPDATE abook SET abook_role = '%s'
|
||||
WHERE abook_xchan IN (" . protect_sprintf(implode(',', $contacts)) . ") AND abook_channel = %d",
|
||||
dbesc($role),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
$r = q("SELECT abook.*, xchan.* FROM abook LEFT JOIN xchan ON abook.abook_xchan = xchan.xchan_hash WHERE abook.abook_xchan IN (" . protect_sprintf(implode(',', $contacts)) . ") AND abook.abook_channel = %d AND abook_self = 0",
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
foreach ($r as $rr) {
|
||||
|
||||
if (intval($rr['abook_self'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Master::Summon([
|
||||
'Notifier',
|
||||
'permission_update',
|
||||
$rr['abook_id']
|
||||
]);
|
||||
|
||||
$clone = $rr;
|
||||
|
||||
unset($clone['abook_id']);
|
||||
unset($clone['abook_account']);
|
||||
unset($clone['abook_channel']);
|
||||
|
||||
$abconfig = load_abconfig($channel['channel_id'], $clone['abook_xchan']);
|
||||
if ($abconfig)
|
||||
$clone['abconfig'] = $abconfig;
|
||||
|
||||
Libsync::build_sync_packet(0 /* use the current local_channel */, ['abook' => [$clone]]);
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use Zotlabs\Zot6\Receiver;
|
||||
use Zotlabs\Zot6\Zot6Handler;
|
||||
|
||||
class Queue {
|
||||
|
||||
static function update($id, $add_priority = 0) {
|
||||
@@ -28,19 +31,19 @@ class Queue {
|
||||
$might_be_down = ((datetime_convert('UTC','UTC',$y[0]['earliest']) < datetime_convert('UTC','UTC','now - 2 days')) ? true : false);
|
||||
|
||||
|
||||
// Set all other records for this destination way into the future.
|
||||
// Set all other records for this destination way into the future.
|
||||
// The queue delivers by destination. We'll keep one queue item for
|
||||
// this destination (this one) with a shorter delivery. If we succeed
|
||||
// once, we'll try to deliver everything for that destination.
|
||||
// The delivery will be set to at most once per hour, and if the
|
||||
// The delivery will be set to at most once per hour, and if the
|
||||
// queue item is less than 12 hours old, we'll schedule for fifteen
|
||||
// minutes.
|
||||
// minutes.
|
||||
|
||||
q("UPDATE outq SET outq_scheduled = '%s' WHERE outq_posturl = '%s'",
|
||||
dbesc(datetime_convert('UTC','UTC','now + 5 days')),
|
||||
dbesc($x[0]['outq_posturl'])
|
||||
);
|
||||
|
||||
|
||||
$since = datetime_convert('UTC','UTC',$x[0]['outq_created']);
|
||||
|
||||
if(($might_be_down) || ($since < datetime_convert('UTC','UTC','now - 12 hour'))) {
|
||||
@@ -50,9 +53,9 @@ class Queue {
|
||||
$next = datetime_convert('UTC','UTC','now + ' . intval($add_priority) . ' minutes');
|
||||
}
|
||||
|
||||
q("UPDATE outq SET outq_updated = '%s',
|
||||
outq_priority = outq_priority + %d,
|
||||
outq_scheduled = '%s'
|
||||
q("UPDATE outq SET outq_updated = '%s',
|
||||
outq_priority = outq_priority + %d,
|
||||
outq_scheduled = '%s'
|
||||
WHERE outq_hash = '%s'",
|
||||
|
||||
dbesc(datetime_convert()),
|
||||
@@ -66,7 +69,7 @@ class Queue {
|
||||
static function remove($id,$channel_id = 0) {
|
||||
logger('queue: remove queue item ' . $id,LOGGER_DEBUG);
|
||||
$sql_extra = (($channel_id) ? " and outq_channel = " . intval($channel_id) . " " : '');
|
||||
|
||||
|
||||
q("DELETE FROM outq WHERE outq_hash = '%s' $sql_extra",
|
||||
dbesc($id)
|
||||
);
|
||||
@@ -75,7 +78,7 @@ class Queue {
|
||||
|
||||
static function remove_by_posturl($posturl) {
|
||||
logger('queue: remove queue posturl ' . $posturl,LOGGER_DEBUG);
|
||||
|
||||
|
||||
q("DELETE FROM outq WHERE outq_posturl = '%s' ",
|
||||
dbesc($posturl)
|
||||
);
|
||||
@@ -88,7 +91,7 @@ class Queue {
|
||||
$sql_extra = (($channel['channel_id']) ? " and outq_channel = " . intval($channel['channel_id']) . " " : '');
|
||||
|
||||
// Set the next scheduled run date so far in the future that it will be expired
|
||||
// long before it ever makes it back into the delivery chain.
|
||||
// long before it ever makes it back into the delivery chain.
|
||||
|
||||
q("update outq set outq_delivered = 1, outq_updated = '%s', outq_scheduled = '%s' where outq_hash = '%s' $sql_extra ",
|
||||
dbesc(datetime_convert()),
|
||||
@@ -107,21 +110,30 @@ class Queue {
|
||||
return false;
|
||||
}
|
||||
|
||||
$hash = $arr['hash'] ?? '';
|
||||
$account_id = $arr['account_id'] ?? 0;
|
||||
$channel_id = $arr['channel_id'] ?? 0;
|
||||
$driver = $arr['driver'] ?? 'zot6';
|
||||
$posturl = $arr['posturl'] ?? '';
|
||||
$priority = $arr['priority'] ?? 0;
|
||||
$notify = $arr['notify'] ?? '';
|
||||
$msg = $arr['msg'] ?? '';
|
||||
|
||||
$x = q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_priority,
|
||||
outq_created, outq_updated, outq_scheduled, outq_notify, outq_msg )
|
||||
outq_created, outq_updated, outq_scheduled, outq_notify, outq_msg )
|
||||
values ( '%s', %d, %d, '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s' )",
|
||||
dbesc($arr['hash']),
|
||||
intval($arr['account_id']),
|
||||
intval($arr['channel_id']),
|
||||
dbesc(($arr['driver']) ? $arr['driver'] : 'zot6'),
|
||||
dbesc($arr['posturl']),
|
||||
dbesc($hash),
|
||||
intval($account_id),
|
||||
intval($channel_id),
|
||||
dbesc($driver),
|
||||
dbesc($posturl),
|
||||
intval(1),
|
||||
intval(isset($arr['priority']) ? $arr['priority'] : 0),
|
||||
intval($priority),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($arr['notify']),
|
||||
dbesc(($arr['msg']) ? $arr['msg'] : '')
|
||||
dbesc($notify),
|
||||
dbesc($msg)
|
||||
);
|
||||
return $x;
|
||||
|
||||
@@ -133,7 +145,7 @@ class Queue {
|
||||
|
||||
$base = null;
|
||||
$h = parse_url($outq['outq_posturl']);
|
||||
if($h !== false)
|
||||
if($h !== false)
|
||||
$base = $h['scheme'] . '://' . $h['host'] . (isset($h['port']) ? ':' . $h['port'] : '');
|
||||
|
||||
if(($base) && ($base !== z_root()) && ($immediate)) {
|
||||
@@ -147,7 +159,7 @@ class Queue {
|
||||
return;
|
||||
}
|
||||
if($y[0]['site_update'] < datetime_convert('UTC','UTC','now - 1 month')) {
|
||||
self::update($outq['outq_hash'],10);
|
||||
self::update($outq['outq_hash'], 10);
|
||||
logger('immediate delivery deferred for site ' . $base);
|
||||
return;
|
||||
}
|
||||
@@ -158,12 +170,12 @@ class Queue {
|
||||
// your site has existed. Since we don't know for sure what these sites are,
|
||||
// call them unknown
|
||||
|
||||
site_store_lowlevel(
|
||||
site_store_lowlevel(
|
||||
[
|
||||
'site_url' => $base,
|
||||
'site_update' => datetime_convert(),
|
||||
'site_dead' => 0,
|
||||
'site_type' => intval(($outq['outq_driver'] === 'post') ? SITE_TYPE_NOTZOT : SITE_TYPE_UNKNOWN),
|
||||
'site_type' => SITE_TYPE_UNKNOWN,
|
||||
'site_crypto' => ''
|
||||
]
|
||||
);
|
||||
@@ -171,65 +183,17 @@ class Queue {
|
||||
}
|
||||
|
||||
$arr = array('outq' => $outq, 'base' => $base, 'handled' => false, 'immediate' => $immediate);
|
||||
call_hooks('queue_deliver',$arr);
|
||||
call_hooks('queue_deliver', $arr);
|
||||
if($arr['handled'])
|
||||
return;
|
||||
|
||||
// "post" queue driver - used for diaspora and friendica-over-diaspora communications.
|
||||
|
||||
if($outq['outq_driver'] === 'post') {
|
||||
$result = z_post_url($outq['outq_posturl'],$outq['outq_msg']);
|
||||
if($result['success'] && $result['return_code'] < 300) {
|
||||
logger('deliver: queue post success to ' . $outq['outq_posturl'], LOGGER_DEBUG);
|
||||
if($base) {
|
||||
q("update site set site_update = '%s', site_dead = 0 where site_url = '%s' ",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($base)
|
||||
);
|
||||
}
|
||||
q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'",
|
||||
dbesc('accepted for delivery'),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($outq['outq_hash'])
|
||||
);
|
||||
self::remove($outq['outq_hash']);
|
||||
|
||||
// server is responding - see if anything else is going to this destination and is piled up
|
||||
// and try to send some more. We're relying on the fact that do_delivery() results in an
|
||||
// immediate delivery otherwise we could get into a queue loop.
|
||||
|
||||
if(! $immediate) {
|
||||
$x = q("select outq_hash from outq where outq_posturl = '%s' and outq_delivered = 0",
|
||||
dbesc($outq['outq_posturl'])
|
||||
);
|
||||
|
||||
$piled_up = array();
|
||||
if($x) {
|
||||
foreach($x as $xx) {
|
||||
$piled_up[] = $xx['outq_hash'];
|
||||
}
|
||||
}
|
||||
if($piled_up) {
|
||||
// call do_delivery() with the force flag
|
||||
do_delivery($piled_up, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
logger('deliver: queue post returned ' . $result['return_code']
|
||||
. ' from ' . $outq['outq_posturl'],LOGGER_DEBUG);
|
||||
self::update($outq['outq_hash'],10);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// normal zot delivery
|
||||
|
||||
logger('deliver: dest: ' . $outq['outq_posturl'], LOGGER_DEBUG);
|
||||
|
||||
if($outq['outq_posturl'] === z_root() . '/zot') {
|
||||
// local delivery
|
||||
$zot = new \Zotlabs\Zot6\Receiver(new \Zotlabs\Zot6\Zot6Handler(),$outq['outq_notify']);
|
||||
$zot = new Receiver(new Zot6Handler(), $outq['outq_notify']);
|
||||
$result = $zot->run();
|
||||
logger('returned_json: ' . json_encode($result,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES), LOGGER_DATA);
|
||||
logger('deliver: local zot delivery succeeded to ' . $outq['outq_posturl']);
|
||||
@@ -240,13 +204,14 @@ class Queue {
|
||||
$channel = null;
|
||||
|
||||
if($outq['outq_channel']) {
|
||||
$channel = channelx_by_n($outq['outq_channel']);
|
||||
$channel = channelx_by_n($outq['outq_channel'], true);
|
||||
}
|
||||
|
||||
$host_crypto = null;
|
||||
|
||||
if($channel && $base) {
|
||||
$h = q("select hubloc_sitekey, site_crypto from hubloc left join site on hubloc_url = site_url where site_url = '%s' and hubloc_sitekey != '' order by hubloc_id desc limit 1",
|
||||
$h = q("SELECT hubloc_sitekey, site_crypto FROM hubloc LEFT JOIN site ON hubloc_url = site_url
|
||||
WHERE site_url = '%s' AND hubloc_network = 'zot6' AND hubloc_deleted = 0 ORDER BY hubloc_primary DESC, hubloc_id DESC LIMIT 1",
|
||||
dbesc($base)
|
||||
);
|
||||
if($h) {
|
||||
@@ -256,7 +221,7 @@ class Queue {
|
||||
|
||||
$msg = $outq['outq_notify'];
|
||||
|
||||
$result = Libzot::zot($outq['outq_posturl'],$msg,$channel,$host_crypto);
|
||||
$result = Libzot::zot($outq['outq_posturl'], $msg, $channel, $host_crypto);
|
||||
|
||||
if($result['success']) {
|
||||
logger('deliver: remote zot delivery succeeded to ' . $outq['outq_posturl']);
|
||||
@@ -265,7 +230,7 @@ class Queue {
|
||||
else {
|
||||
logger('deliver: remote zot delivery failed to ' . $outq['outq_posturl']);
|
||||
logger('deliver: remote zot delivery fail data: ' . print_r($result,true), LOGGER_DATA);
|
||||
self::update($outq['outq_hash'],10);
|
||||
self::update($outq['outq_hash'], 10);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -8,13 +8,13 @@ class Share {
|
||||
|
||||
|
||||
public function __construct($post_id) {
|
||||
|
||||
|
||||
if(! $post_id)
|
||||
return;
|
||||
|
||||
|
||||
if(! (local_channel() || remote_channel()))
|
||||
return;
|
||||
|
||||
|
||||
$r = q("SELECT * from item left join xchan on author_xchan = xchan_hash WHERE id = %d LIMIT 1",
|
||||
intval($post_id)
|
||||
);
|
||||
@@ -23,26 +23,26 @@ class Share {
|
||||
|
||||
if(($r[0]['item_private']) && ($r[0]['xchan_network'] !== 'rss'))
|
||||
return;
|
||||
|
||||
|
||||
$sql_extra = item_permissions_sql($r[0]['uid']);
|
||||
|
||||
|
||||
$r = q("select * from item where id = %d $sql_extra",
|
||||
intval($post_id)
|
||||
);
|
||||
if(! $r)
|
||||
return;
|
||||
|
||||
|
||||
if($r[0]['mimetype'] !== 'text/bbcode')
|
||||
return;
|
||||
|
||||
|
||||
/** @FIXME eventually we want to post remotely via rpost on your home site */
|
||||
// When that works remove this next bit:
|
||||
|
||||
|
||||
if(! local_channel())
|
||||
return;
|
||||
|
||||
xchan_query($r);
|
||||
|
||||
|
||||
$this->item = $r[0];
|
||||
return;
|
||||
}
|
||||
@@ -66,14 +66,14 @@ class Share {
|
||||
'address' => $this->item['author']['xchan_addr'],
|
||||
'network' => $this->item['author']['xchan_network'],
|
||||
'link' => [
|
||||
[
|
||||
'rel' => 'alternate',
|
||||
'type' => 'text/html',
|
||||
[
|
||||
'rel' => 'alternate',
|
||||
'type' => 'text/html',
|
||||
'href' => $this->item['author']['xchan_url']
|
||||
],
|
||||
[
|
||||
'rel' => 'photo',
|
||||
'type' => $this->item['author']['xchan_photo_mimetype'],
|
||||
'rel' => 'photo',
|
||||
'type' => $this->item['author']['xchan_photo_mimetype'],
|
||||
'href' => $this->item['author']['xchan_photo_m']
|
||||
]
|
||||
]
|
||||
@@ -84,14 +84,14 @@ class Share {
|
||||
'address' => $this->item['owner']['xchan_addr'],
|
||||
'network' => $this->item['owner']['xchan_network'],
|
||||
'link' => [
|
||||
[
|
||||
'rel' => 'alternate',
|
||||
'type' => 'text/html',
|
||||
[
|
||||
'rel' => 'alternate',
|
||||
'type' => 'text/html',
|
||||
'href' => $this->item['owner']['xchan_url']
|
||||
],
|
||||
[
|
||||
'rel' => 'photo',
|
||||
'type' => $this->item['owner']['xchan_photo_mimetype'],
|
||||
'rel' => 'photo',
|
||||
'type' => $this->item['owner']['xchan_photo_mimetype'],
|
||||
'href' => $this->item['owner']['xchan_photo_m']
|
||||
]
|
||||
]
|
||||
@@ -117,7 +117,7 @@ class Share {
|
||||
$object = json_decode($this->item['obj'],true);
|
||||
$photo_bb = $object['body'];
|
||||
}
|
||||
|
||||
|
||||
if (strpos($this->item['body'], "[/share]") !== false) {
|
||||
$pos = strpos($this->item['body'], "[share");
|
||||
$bb = substr($this->item['body'], $pos);
|
||||
@@ -126,7 +126,7 @@ class Share {
|
||||
"' profile='" . $this->item['author']['xchan_url'] .
|
||||
"' avatar='" . $this->item['author']['xchan_photo_s'] .
|
||||
"' link='" . $this->item['plink'] .
|
||||
"' auth='" . ((in_array($this->item['author']['xchan_network'], ['zot6', 'zot'])) ? 'true' : 'false') .
|
||||
"' auth='" . (($this->item['author']['xchan_network'] === 'zot6') ? 'true' : 'false') .
|
||||
"' posted='" . $this->item['created'] .
|
||||
"' message_id='" . $this->item['mid'] .
|
||||
"']";
|
||||
|
||||
@@ -16,13 +16,13 @@ class System {
|
||||
}
|
||||
|
||||
static public function get_site_name() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['sitename'])
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && isset(\App::$config['system']['sitename']))
|
||||
return \App::$config['system']['sitename'];
|
||||
return '';
|
||||
}
|
||||
|
||||
static public function get_project_version() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['hide_version'])
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && isset(\App::$config['system']['hide_version']))
|
||||
return '';
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && array_key_exists('std_version',\App::$config['system']))
|
||||
return \App::$config['system']['std_version'];
|
||||
@@ -31,33 +31,33 @@ class System {
|
||||
}
|
||||
|
||||
static public function get_update_version() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['hide_version'])
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && isset(\App::$config['system']['hide_version']))
|
||||
return '';
|
||||
return DB_UPDATE_VERSION;
|
||||
}
|
||||
|
||||
|
||||
static public function get_notify_icon() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['email_notify_icon_url'])
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && isset(\App::$config['system']['email_notify_icon_url']))
|
||||
return \App::$config['system']['email_notify_icon_url'];
|
||||
return z_root() . DEFAULT_NOTIFY_ICON;
|
||||
}
|
||||
|
||||
static public function get_site_icon() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['site_icon_url'])
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && isset(\App::$config['system']['site_icon_url']))
|
||||
return \App::$config['system']['site_icon_url'];
|
||||
return z_root() . DEFAULT_PLATFORM_ICON ;
|
||||
}
|
||||
|
||||
|
||||
static public function get_project_link() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['project_link'])
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && isset(\App::$config['system']['project_link']))
|
||||
return \App::$config['system']['project_link'];
|
||||
return 'https://hubzilla.org';
|
||||
}
|
||||
|
||||
static public function get_project_srclink() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['project_srclink'])
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && isset(\App::$config['system']['project_srclink']))
|
||||
return \App::$config['system']['project_srclink'];
|
||||
return 'https://framagit.org/hubzilla/core.git';
|
||||
}
|
||||
@@ -68,7 +68,7 @@ class System {
|
||||
|
||||
|
||||
static public function get_zot_revision() {
|
||||
$x = [ 'revision' => ZOT_REVISION ];
|
||||
$x = [ 'revision' => ZOT_REVISION ];
|
||||
call_hooks('zot_revision',$x);
|
||||
return $x['revision'];
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Lib\Apps;
|
||||
use Zotlabs\Access\AccessList;
|
||||
|
||||
require_once('include/text.php');
|
||||
|
||||
@@ -58,6 +60,9 @@ class ThreadItem {
|
||||
$child = new ThreadItem($item);
|
||||
$this->add_child($child);
|
||||
}
|
||||
|
||||
// performance: we have already added the children
|
||||
unset($this->data['children']);
|
||||
}
|
||||
|
||||
// allow a site to configure the order and content of the reaction emoji list
|
||||
@@ -79,10 +84,8 @@ class ThreadItem {
|
||||
|
||||
public function get_template_data($conv_responses, $thread_level=1, $conv_flags = []) {
|
||||
|
||||
$result = array();
|
||||
|
||||
$item = $this->get_data();
|
||||
|
||||
$result = [];
|
||||
$item = $this->get_data();
|
||||
$commentww = '';
|
||||
$sparkle = '';
|
||||
$buttons = '';
|
||||
@@ -93,16 +96,30 @@ class ThreadItem {
|
||||
$is_item = false;
|
||||
$osparkle = '';
|
||||
$total_children = $this->count_descendants();
|
||||
$unseen_comments = (($item['real_uid']) ? 0 : $this->count_unseen_descendants());
|
||||
$unseen_comments = ((isset($item['real_uid']) && $item['real_uid']) ? 0 : $this->count_unseen_descendants());
|
||||
|
||||
$conv = $this->get_conversation();
|
||||
$observer = $conv->get_observer();
|
||||
|
||||
$lock = (((intval($item['item_private'])) || (($item['uid'] == local_channel()) && (strlen($item['allow_cid']) || strlen($item['allow_gid'])
|
||||
|| strlen($item['deny_cid']) || strlen($item['deny_gid']))))
|
||||
? t('Private Message')
|
||||
$acl = new AccessList(false);
|
||||
$acl->set($item);
|
||||
|
||||
$lock = ((intval($item['item_private']) || ($item['uid'] == local_channel() && $acl->is_private()))
|
||||
? t('Restricted message')
|
||||
: false);
|
||||
$locktype = $item['item_private'];
|
||||
|
||||
// 1 = restricted message, 2 = direct message
|
||||
$locktype = intval($item['item_private']);
|
||||
|
||||
if ($locktype === 2) {
|
||||
$lock = t('Direct message');
|
||||
}
|
||||
|
||||
// 0 = limited based on public policy
|
||||
if ($item['uid'] == local_channel() && intval($item['item_private']) && !$acl->is_private() && strlen($item['public_policy'])) {
|
||||
$lock = t('Public Policy');
|
||||
$locktype = 0;
|
||||
}
|
||||
|
||||
$shareable = ((($conv->get_profile_owner() == local_channel() && local_channel()) && ($item['item_private'] != 1)) ? true : false);
|
||||
|
||||
@@ -110,6 +127,16 @@ class ThreadItem {
|
||||
if($item['author']['xchan_network'] === 'rss')
|
||||
$shareable = true;
|
||||
|
||||
// @fixme
|
||||
// Have recently added code to properly handle polls in group reshares by redirecting all of the poll responses to the group.
|
||||
// Sharing a poll using a regular embedded share is harder because the poll will need to fork. This is due to comment permissions.
|
||||
// The original poll author may not accept responses from strangers. Forking the poll will receive responses from the sharer's
|
||||
// followers, but there's no elegant way to merge these two sets of results together. For now, we'll disable sharing polls.
|
||||
|
||||
if ($item['obj_type'] === 'Question') {
|
||||
$shareable = false;
|
||||
}
|
||||
|
||||
$privacy_warning = false;
|
||||
if(intval($item['item_private']) && ($item['owner']['xchan_network'] === 'activitypub')) {
|
||||
$recips = get_iconfig($item['parent'], 'activitypub', 'recips');
|
||||
@@ -119,7 +146,7 @@ class ThreadItem {
|
||||
}
|
||||
|
||||
if ($lock) {
|
||||
if (($item['mid'] == $item['parent_mid']) && count(get_terms_oftype($item['term'],TERM_FORUM))) {
|
||||
if (($item['mid'] == $item['parent_mid']) && isset($item['term']) && count(get_terms_oftype($item['term'], TERM_FORUM))) {
|
||||
$privacy_warning = true;
|
||||
$conv_flags['parent_privacy_warning'] = true;
|
||||
}
|
||||
@@ -133,24 +160,11 @@ class ThreadItem {
|
||||
|
||||
$mode = $conv->get_mode();
|
||||
|
||||
switch($item['item_type']) {
|
||||
case ITEM_TYPE_CARD:
|
||||
$edlink = 'card_edit';
|
||||
break;
|
||||
case ITEM_TYPE_ARTICLE:
|
||||
$edlink = 'article_edit';
|
||||
break;
|
||||
default:
|
||||
$edlink = 'editpost';
|
||||
break;
|
||||
}
|
||||
|
||||
if(local_channel() && $observer['xchan_hash'] === $item['author_xchan'])
|
||||
$edpost = array(z_root() . '/' . $edlink . '/' . $item['id'], t('Edit'));
|
||||
$edpost = array(z_root() . '/editpost/' . $item['id'], t('Edit'));
|
||||
else
|
||||
$edpost = false;
|
||||
|
||||
|
||||
if($observer && $observer['xchan_hash']
|
||||
&& ($observer['xchan_hash'] == $this->get_data_value('author_xchan')
|
||||
|| $observer['xchan_hash'] == $this->get_data_value('owner_xchan')
|
||||
@@ -164,7 +178,7 @@ class ThreadItem {
|
||||
$dropping = false;
|
||||
}
|
||||
|
||||
|
||||
$drop = [];
|
||||
if($dropping) {
|
||||
$drop = array(
|
||||
'dropping' => $dropping,
|
||||
@@ -175,13 +189,6 @@ class ThreadItem {
|
||||
$drop = [ 'dropping' => true, 'delete' => t('Admin 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'];
|
||||
@@ -191,7 +198,6 @@ class ThreadItem {
|
||||
$location = format_location($item);
|
||||
$isevent = false;
|
||||
$attend = null;
|
||||
$canvote = false;
|
||||
|
||||
// process action responses - e.g. like/dislike/attend/agree/whatever
|
||||
$response_verbs = array('like');
|
||||
@@ -211,17 +217,6 @@ class ThreadItem {
|
||||
$response_verbs[] = 'answer';
|
||||
}
|
||||
|
||||
$consensus = (intval($item['item_consensus']) ? true : false);
|
||||
if($consensus) {
|
||||
$response_verbs[] = 'agree';
|
||||
$response_verbs[] = 'disagree';
|
||||
$response_verbs[] = 'abstain';
|
||||
if($this->is_commentable() && $observer) {
|
||||
$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']);
|
||||
|
||||
@@ -229,7 +224,8 @@ class ThreadItem {
|
||||
|
||||
$my_responses = [];
|
||||
foreach($response_verbs as $v) {
|
||||
$my_responses[$v] = (($conv_responses[$v][$item['mid'] . '-m']) ? 1 : 0);
|
||||
|
||||
$my_responses[$v] = ((isset($conv_responses[$v][$item['mid'] . '-m'])) ? 1 : 0);
|
||||
}
|
||||
|
||||
$like_count = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid']] : '');
|
||||
@@ -242,6 +238,7 @@ class ThreadItem {
|
||||
}
|
||||
$like_button_label = tt('Like','Likes',$like_count,'noun');
|
||||
|
||||
$showdislike = '';
|
||||
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'] : '');
|
||||
@@ -252,11 +249,11 @@ class ThreadItem {
|
||||
} else {
|
||||
$dislike_list_part = '';
|
||||
}
|
||||
|
||||
$showdislike = ((x($conv_responses['dislike'],$item['mid'])) ? format_like($conv_responses['dislike'][$item['mid']],$conv_responses['dislike'][$item['mid'] . '-l'],'dislike',$item['mid']) : '');
|
||||
}
|
||||
|
||||
$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
|
||||
@@ -267,14 +264,11 @@ class ThreadItem {
|
||||
$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))) {
|
||||
|
||||
$star = array(
|
||||
if((local_channel() && $conv->get_profile_owner() === local_channel()) || (local_channel() && App::$module === 'pubstream')) {
|
||||
$star = [
|
||||
'toggle' => t("Toggle Star Status"),
|
||||
'isstarred' => ((intval($item['item_starred'])) ? true : false),
|
||||
);
|
||||
|
||||
];
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -291,7 +285,7 @@ class ThreadItem {
|
||||
$tagger = [];
|
||||
|
||||
// FIXME - check this permission
|
||||
if($conv->get_profile_owner() == local_channel()) {
|
||||
if(local_channel() && $conv->get_profile_owner() == local_channel()) {
|
||||
/* disable until we agree on how to implemnt this in zot6/activitypub
|
||||
$tagger = array(
|
||||
'tagit' => t("Add Tag"),
|
||||
@@ -299,11 +293,11 @@ class ThreadItem {
|
||||
);
|
||||
*/
|
||||
|
||||
$settings = t('Conversation Tools');
|
||||
$settings = t('Conversation Features');
|
||||
}
|
||||
|
||||
$has_bookmarks = false;
|
||||
if(Apps::system_app_installed(local_channel(), 'Bookmarks') && is_array($item['term'])) {
|
||||
if(Apps::system_app_installed(local_channel(), 'Bookmarks') && isset($item['term']) && is_array($item['term'])) {
|
||||
foreach($item['term'] as $t) {
|
||||
if(($t['ttype'] == TERM_BOOKMARK))
|
||||
$has_bookmarks = true;
|
||||
@@ -314,20 +308,26 @@ class ThreadItem {
|
||||
if(($item['obj_type'] === ACTIVITY_OBJ_EVENT) && $conv->get_profile_owner() == local_channel())
|
||||
$has_event = true;
|
||||
|
||||
$like = [];
|
||||
$dislike = [];
|
||||
$reply_to = [];
|
||||
|
||||
if($this->is_commentable() && $observer) {
|
||||
$like = array( t("I like this \x28toggle\x29"), t("like"));
|
||||
$dislike = array( t("I don't like this \x28toggle\x29"), t("dislike"));
|
||||
$reply_to = array( t("Reply on this comment"), t("reply"), t("Reply to"));
|
||||
}
|
||||
|
||||
$share = [];
|
||||
$embed = [];
|
||||
if ($shareable) {
|
||||
// This actually turns out not to be possible in some protocol stacks without opening up hundreds of new issues.
|
||||
// Will allow it only for uri resolvable sources.
|
||||
if(strpos($item['mid'],'http') === 0) {
|
||||
$share = []; //Not yet ready for primetime
|
||||
//Not yet ready for primetime
|
||||
//$share = array( t('Repeat This'), t('repeat'));
|
||||
}
|
||||
$embed = array( t('Share This'), t('share'));
|
||||
$embed = [t('Share This'), t('share')];
|
||||
}
|
||||
|
||||
$dreport = '';
|
||||
@@ -336,11 +336,13 @@ class ThreadItem {
|
||||
if($keep_reports === 0)
|
||||
$keep_reports = 10;
|
||||
|
||||
if((! get_config('system','disable_dreport')) && strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC',"now - $keep_reports days")) > 0) {
|
||||
$dreport_link = '';
|
||||
if((intval($item['item_type']) == ITEM_TYPE_POST) && (! 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');
|
||||
$dreport_link = gen_link_id($item['mid']);
|
||||
}
|
||||
|
||||
$is_new = false;
|
||||
if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0)
|
||||
$is_new = true;
|
||||
|
||||
@@ -367,7 +369,7 @@ class ThreadItem {
|
||||
call_hooks('dropdown_extras',$dropdown_extras_arr);
|
||||
$dropdown_extras = $dropdown_extras_arr['dropdown_extras'];
|
||||
|
||||
$midb64 = 'b64.' . base64url_encode($item['mid']);
|
||||
$midb64 = gen_link_id($item['mid']);
|
||||
$mids = [ $midb64 ];
|
||||
$response_mids = [];
|
||||
foreach($response_verbs as $v) {
|
||||
@@ -384,6 +386,12 @@ class ThreadItem {
|
||||
$pinned_items = ($allowed_type ? get_pconfig($item['uid'], 'pinned', $item['item_type'], []) : []);
|
||||
$pinned = ((!empty($pinned_items) && in_array($midb64, $pinned_items)) ? true : false);
|
||||
|
||||
$contact = [];
|
||||
|
||||
if(App::$contacts && array_key_exists($item['author_xchan'], App::$contacts)) {
|
||||
$contact = App::$contacts[$item['author_xchan']];
|
||||
}
|
||||
|
||||
$tmp_item = array(
|
||||
'template' => $this->get_template(),
|
||||
'mode' => $mode,
|
||||
@@ -401,11 +409,9 @@ class ThreadItem {
|
||||
'mids' => $json_mids,
|
||||
'parent' => $item['parent'],
|
||||
'author_id' => (($item['author']['xchan_addr']) ? $item['author']['xchan_addr'] : $item['author']['xchan_url']),
|
||||
'author_is_group_actor' => (($item['author']['xchan_pubforum']) ? t('Forum') : ''),
|
||||
'isevent' => $isevent,
|
||||
'attend' => $attend,
|
||||
'consensus' => $consensus,
|
||||
'conlabels' => $conlabels,
|
||||
'canvote' => $canvote,
|
||||
'linktitle' => (($item['author']['xchan_addr']) ? $item['author']['xchan_addr'] : $item['author']['xchan_url']),
|
||||
'olinktitle' => (($item['owner']['xchan_addr']) ? $item['owner']['xchan_addr'] : $item['owner']['xchan_url']),
|
||||
'llink' => $item['llink'],
|
||||
@@ -474,7 +480,6 @@ class ThreadItem {
|
||||
'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 : ''),
|
||||
'dropdown_extras' => $dropdown_extras,
|
||||
// end toolbar buttons
|
||||
'unseen_comments' => $unseen_comments,
|
||||
@@ -497,13 +502,15 @@ class ThreadItem {
|
||||
'modal_dismiss' => t('Close'),
|
||||
'showlike' => $showlike,
|
||||
'showdislike' => $showdislike,
|
||||
'comment' => ($item['item_delayed'] ? '' : $this->get_comment_box($indent)),
|
||||
'comment' => ($item['item_delayed'] ? '' : $this->get_comment_box()),
|
||||
'previewing' => ($conv->is_preview() ? true : false ),
|
||||
'preview_lbl' => t('This is an unsaved preview'),
|
||||
'wait' => t('Please wait'),
|
||||
'thread_level' => $thread_level,
|
||||
'settings' => $settings,
|
||||
'thr_parent' => (($item['parent_mid'] != $item['thr_parent']) ? 'b64.' . base64url_encode($item['thr_parent']) : '')
|
||||
'thr_parent' => (($item['parent_mid'] != $item['thr_parent']) ? gen_link_id($item['thr_parent']) : ''),
|
||||
'contact_id' => (($contact) ? $contact['abook_id'] : '')
|
||||
|
||||
);
|
||||
|
||||
$arr = array('item' => $item, 'output' => $tmp_item);
|
||||
@@ -789,7 +796,7 @@ class ThreadItem {
|
||||
* _ The comment box string (empty if no comment box)
|
||||
* _ false on failure
|
||||
*/
|
||||
private function get_comment_box($indent) {
|
||||
private function get_comment_box() {
|
||||
|
||||
if(!$this->is_toplevel() && !get_config('system','thread_allow')) {
|
||||
return '';
|
||||
@@ -835,14 +842,13 @@ class ThreadItem {
|
||||
'$edurl' => t('Insert Link'),
|
||||
'$edvideo' => t('Video'),
|
||||
'$preview' => t('Preview'), // ((feature_enabled($conv->get_profile_owner(),'preview')) ? t('Preview') : ''),
|
||||
'$indent' => $indent,
|
||||
'$can_upload' => (perm_is_allowed($conv->get_profile_owner(),get_observer_hash(),'write_storage') && $conv->is_uploadable()),
|
||||
'$feature_encrypt' => ((feature_enabled($conv->get_profile_owner(),'content_encrypt')) ? true : false),
|
||||
'$encrypt' => t('Encrypt text'),
|
||||
'$cipher' => $conv->get_cipher(),
|
||||
'$sourceapp' => \App::$sourcename,
|
||||
'$observer' => get_observer_hash(),
|
||||
'$anoncomments' => ((($conv->get_mode() === 'channel' || $conv->get_mode() === 'display') && perm_is_allowed($conv->get_profile_owner(),'','post_comments')) ? true : false),
|
||||
'$anoncomments' => ((in_array($conv->get_mode(), ['channel', 'display', 'cards', 'articles']) && perm_is_allowed($conv->get_profile_owner(),'','post_comments')) ? true : false),
|
||||
'$anonname' => [ 'anonname', t('Your full name (required)') ],
|
||||
'$anonmail' => [ 'anonmail', t('Your email address (required)') ],
|
||||
'$anonurl' => [ 'anonurl', t('Your website URL (optional)') ]
|
||||
|
||||
@@ -69,15 +69,15 @@ class ThreadStream {
|
||||
case 'cards':
|
||||
$this->profile_owner = \App::$profile['profile_uid'];
|
||||
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||
$this->reload = $_SESSION['return_url'];
|
||||
//$this->reload = $_SESSION['return_url'];
|
||||
break;
|
||||
case 'articles':
|
||||
$this->profile_owner = \App::$profile['profile_uid'];
|
||||
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||
$this->reload = $_SESSION['return_url'];
|
||||
//$this->reload = $_SESSION['return_url'];
|
||||
break;
|
||||
case 'display':
|
||||
// in this mode we set profile_owner after initialisation (from conversation()) and then
|
||||
// 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');
|
||||
@@ -170,14 +170,14 @@ class ThreadStream {
|
||||
* 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);
|
||||
@@ -194,7 +194,7 @@ class ThreadStream {
|
||||
}
|
||||
if($this->mode === 'pubstream' && (! local_channel())) {
|
||||
$item->set_commentable(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$item->set_conversation($this);
|
||||
|
||||
@@ -53,10 +53,10 @@ class Webfinger {
|
||||
if(strpos($resource,'http') === 0) {
|
||||
$m = parse_url($resource);
|
||||
if($m) {
|
||||
if($m['scheme'] !== 'https') {
|
||||
if(isset($m['scheme']) && $m['scheme'] !== 'https') {
|
||||
return false;
|
||||
}
|
||||
self::$server = $m['host'] . (($m['port']) ? ':' . $m['port'] : '');
|
||||
self::$server = $m['host'] . ((isset($m['port'])) ? ':' . $m['port'] : '');
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
@@ -86,7 +86,7 @@ class Webfinger {
|
||||
/**
|
||||
* @brief fetch a webfinger resource and return a zot6 discovery url if present
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
static function zot_url($resource) {
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ class XConfig {
|
||||
*/
|
||||
static public function Delete($xchan, $family, $key) {
|
||||
|
||||
if(x(\App::$config[$xchan][$family], $key))
|
||||
if(isset(\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'",
|
||||
|
||||
@@ -87,4 +87,4 @@ class ZotURL {
|
||||
return ids_to_array($r,'hubloc_url');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use Zotlabs\Web\HTTPSig;
|
||||
|
||||
class Zotfinger {
|
||||
|
||||
static function exec($resource,$channel = null, $verify = true) {
|
||||
static function exec($resource, $channel = null, $verify = true, $recurse = true) {
|
||||
|
||||
if(! $resource) {
|
||||
return false;
|
||||
@@ -39,6 +39,30 @@ class Zotfinger {
|
||||
|
||||
logger('fetch: ' . print_r($x,true));
|
||||
|
||||
if (in_array(intval($x['return_code']), [ 404, 410 ]) && $recurse) {
|
||||
|
||||
// The resource has been deleted or doesn't exist at this location.
|
||||
// Try to find another nomadic resource for this channel and return that.
|
||||
|
||||
// First, see if there's a hubloc for this site. Fetch that record to
|
||||
// obtain the nomadic identity hash. Then use that to find any additional
|
||||
// nomadic locations.
|
||||
|
||||
$h = Activity::get_actor_hublocs($resource, 'zot6');
|
||||
if ($h) {
|
||||
// mark this location deleted
|
||||
hubloc_delete($h[0]);
|
||||
$hubs = Activity::get_actor_hublocs($h[0]['hubloc_hash']);
|
||||
if ($hubs) {
|
||||
foreach ($hubs as $hub) {
|
||||
if ($hub['hubloc_id_url'] !== $resource && !$hub['hubloc_deleted']) {
|
||||
return self::exec($hub['hubloc_id_url'], $channel, $verify);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($x['success']) {
|
||||
if ($verify) {
|
||||
$result['signature'] = HTTPSig::verify($x, EMPTY_STR, 'zot6');
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use Zotlabs\Lib\Libzotdir;
|
||||
use Zotlabs\Lib\AccessList;
|
||||
|
||||
require_once 'include/acl_selectors.php';
|
||||
require_once 'include/group.php';
|
||||
|
||||
/**
|
||||
* @brief ACL selector json backend.
|
||||
@@ -66,6 +66,11 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
killme();
|
||||
|
||||
$permitted = [];
|
||||
$sql_extra = '';
|
||||
$sql_extra2 = '';
|
||||
$sql_extra3 = '';
|
||||
$sql_extra2_xchan = '';
|
||||
$order_extra2 = '';
|
||||
|
||||
if(in_array($type, [ 'm', 'a', 'c', 'f' ])) {
|
||||
|
||||
@@ -81,7 +86,6 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
|
||||
}
|
||||
|
||||
|
||||
if($search) {
|
||||
$sql_extra = " AND pgrp.gname LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " ";
|
||||
$sql_extra2 = "AND ( xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " OR xchan_addr LIKE " . protect_sprintf( "'%" . dbesc(punify($search)) . ((strpos($search,'@') === false) ? "%@%'" : "%'")) . ") ";
|
||||
@@ -100,10 +104,6 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
$sql_extra3 = "AND ( xchan_addr like " . protect_sprintf( "'%" . dbesc(punify($search)) . "%'" ) . " OR xchan_name like " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " ) ";
|
||||
|
||||
}
|
||||
else {
|
||||
$sql_extra = $sql_extra2 = $sql_extra3 = "";
|
||||
}
|
||||
|
||||
|
||||
$groups = array();
|
||||
$contacts = array();
|
||||
@@ -123,7 +123,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
"name" => t('Profile','acl') . ' ' . $rv['profile_name'],
|
||||
"id" => 'vp' . $rv['id'],
|
||||
"xid" => 'vp.' . $rv['profile_guid'],
|
||||
"uids" => group_get_profile_members_xchan(local_channel(), $rv['id']),
|
||||
"uids" => AccessList::profile_members_xchan(local_channel(), $rv['id']),
|
||||
"link" => ''
|
||||
);
|
||||
}
|
||||
@@ -146,14 +146,14 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
|
||||
if($r) {
|
||||
foreach($r as $g){
|
||||
// logger('acl: group: ' . $g['gname'] . ' members: ' . group_get_members_xchan($g['id']));
|
||||
// logger('acl: group: ' . $g['gname'] . ' members: ' . AccessList::members_xchan(local_channel(), $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']),
|
||||
"uids" => AccessList::members_xchan(local_channel(), $g['id']),
|
||||
"link" => ''
|
||||
);
|
||||
}
|
||||
@@ -222,6 +222,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
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);
|
||||
|
||||
@@ -282,13 +283,12 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
elseif($type == 'm') {
|
||||
|
||||
$r = array();
|
||||
$z = q("SELECT xchan_hash as hash, xchan_name as name, xchan_network as net, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url
|
||||
$z = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_network as net, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url, abook_self
|
||||
FROM abook left join xchan on abook_xchan = xchan_hash
|
||||
WHERE abook_channel = %d
|
||||
and xchan_deleted = 0
|
||||
and xchan_network IN ('zot', 'diaspora', 'friendica-over-diaspora')
|
||||
and not xchan_network IN ('rss', 'anon', 'unknown')
|
||||
$sql_extra3
|
||||
ORDER BY xchan_name ASC ",
|
||||
intval(local_channel())
|
||||
@@ -304,7 +304,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
elseif($type == 'a') {
|
||||
|
||||
$r = q("SELECT abook_id as id, xchan_name as name, xchan_network as net, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url, xchan_addr as attag , abook_their_perms FROM abook left join xchan on abook_xchan = xchan_hash
|
||||
$r = q("SELECT abook_id as id, xchan_name as name, xchan_network as net, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url, xchan_addr as attag, abook_their_perms, abook_self FROM abook left join xchan on abook_xchan = xchan_hash
|
||||
WHERE abook_channel = %d
|
||||
and xchan_deleted = 0
|
||||
$sql_extra3
|
||||
@@ -342,7 +342,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
$x = [];
|
||||
foreach($r as $g) {
|
||||
|
||||
if(in_array($g['net'],['rss','anon','unknown']) && ($type != 'a'))
|
||||
if(isset($g['net']) && in_array($g['net'], ['rss','anon','unknown']) && ($type != 'a'))
|
||||
continue;
|
||||
|
||||
$g['hash'] = urlencode($g['hash']);
|
||||
@@ -371,7 +371,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
);
|
||||
}
|
||||
if($type !== 'f') {
|
||||
if (! array_key_exists($x[$lkey], $contacts) || ($contacts[$x[$lkey]]['net'] !== 'zot6' && ($g['net'] == 'zot6' || $g['net'] == 'zot'))) {
|
||||
if (! array_key_exists($x[$lkey], $contacts) || ($contacts[$x[$lkey]]['net'] !== 'zot6' && $g['net'] == 'zot6')) {
|
||||
$contacts[$x[$lkey]] = array(
|
||||
"type" => "c",
|
||||
"photo" => $g['micro'],
|
||||
@@ -383,7 +383,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
"self" => (intval($g['abook_self']) ? 'abook-self' : ''),
|
||||
"taggable" => '',
|
||||
"label" => '',
|
||||
"net" => $g['net']
|
||||
"net" => $g['net'] ?? ''
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -438,7 +438,6 @@ class Acl extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
if(! $url) {
|
||||
require_once("include/dir_fns.php");
|
||||
$directory = Libzotdir::find_upstream_directory($dirmode);
|
||||
$url = $directory['url'] . '/dirsearch';
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/queue_fn.php');
|
||||
require_once('include/account.php');
|
||||
|
||||
/**
|
||||
|
||||
@@ -77,6 +77,7 @@ class Addons {
|
||||
} catch (\PHPGit\Exception\GitException $e) {
|
||||
json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false));
|
||||
}
|
||||
break;
|
||||
case 'removerepo':
|
||||
if (array_key_exists('repoName', $_REQUEST)) {
|
||||
$repoName = $_REQUEST['repoName'];
|
||||
@@ -111,6 +112,7 @@ class Addons {
|
||||
} else {
|
||||
json_return_and_die(array('message' => 'Error deleting addon repo.', 'success' => false));
|
||||
}
|
||||
break;
|
||||
case 'installrepo':
|
||||
if (array_key_exists('repoURL', $_REQUEST)) {
|
||||
require_once('library/PHPGit.autoload.php'); // Load PHPGit dependencies
|
||||
@@ -172,6 +174,7 @@ class Addons {
|
||||
$repo = $git->probeRepo();
|
||||
json_return_and_die(array('repo' => $repo, 'message' => '', 'success' => true));
|
||||
}
|
||||
break;
|
||||
case 'addrepo':
|
||||
if (array_key_exists('repoURL', $_REQUEST)) {
|
||||
require_once('library/PHPGit.autoload.php'); // Load PHPGit dependencies
|
||||
|
||||
@@ -5,11 +5,11 @@ namespace Zotlabs\Module\Admin;
|
||||
|
||||
|
||||
class Dbsync {
|
||||
|
||||
|
||||
|
||||
function get() {
|
||||
$o = '';
|
||||
|
||||
|
||||
if(argc() > 3 && intval(argv(3)) && argv(2) === 'mark') {
|
||||
// remove the old style config if it exists
|
||||
del_config('database', 'update_r' . intval(argv(3)));
|
||||
@@ -29,7 +29,7 @@ class Dbsync {
|
||||
if(method_exists($c,'verify')) {
|
||||
$retval = $c->verify();
|
||||
if($retval === UPDATE_FAILED) {
|
||||
$o .= sprintf( t('Verification of update %s failed. Check system logs.'), $s);
|
||||
$o .= sprintf( t('Verification of update %s failed. Check system logs.'), $s);
|
||||
}
|
||||
elseif($retval === UPDATE_SUCCESS) {
|
||||
$o .= sprintf( t('Update %s was successfully applied.'), $s);
|
||||
@@ -44,20 +44,8 @@ class Dbsync {
|
||||
}
|
||||
else
|
||||
$o .= sprintf( t('Update function %s could not be found.'), $s);
|
||||
|
||||
|
||||
return $o;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// remove the old style config if it exists
|
||||
del_config('database', 'update_r' . intval(argv(3)));
|
||||
set_config('database', '_' . intval(argv(3)), 'success');
|
||||
if(intval(get_config('system','db_version')) < intval(argv(3)))
|
||||
set_config('system','db_version',intval(argv(3)));
|
||||
info( t('Update has been marked successful') . EOL);
|
||||
goaway(z_root() . '/admin/dbsync');
|
||||
}
|
||||
|
||||
if(argc() > 2 && intval(argv(2))) {
|
||||
@@ -68,7 +56,7 @@ class Dbsync {
|
||||
$c = new $cls();
|
||||
$retval = $c->run();
|
||||
if($retval === UPDATE_FAILED) {
|
||||
$o .= sprintf( t('Executing update procedure %s failed. Check system logs.'), $s);
|
||||
$o .= sprintf( t('Executing update procedure %s failed. Check system logs.'), $s);
|
||||
}
|
||||
elseif($retval === UPDATE_SUCCESS) {
|
||||
$o .= sprintf( t('Update %s was successfully applied.'), $s);
|
||||
@@ -79,10 +67,10 @@ class Dbsync {
|
||||
}
|
||||
else
|
||||
$o .= sprintf( t('Update function %s could not be found.'), $s);
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
$failed = array();
|
||||
$r = q("select * from config where cat = 'database' ");
|
||||
if(count($r)) {
|
||||
@@ -107,7 +95,7 @@ class Dbsync {
|
||||
else {
|
||||
return '<div class="generic-content-wrapper-styled"><h3>' . t('No failed updates.') . '</h3></div>';
|
||||
}
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,52 +2,63 @@
|
||||
|
||||
namespace Zotlabs\Module\Admin;
|
||||
|
||||
|
||||
use Zotlabs\Lib\Queue as LibQueue;
|
||||
|
||||
class Queue {
|
||||
|
||||
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
$o = '';
|
||||
|
||||
$expert = ((array_key_exists('expert',$_REQUEST)) ? intval($_REQUEST['expert']) : 0);
|
||||
|
||||
if($_REQUEST['drophub']) {
|
||||
|
||||
$expert = $_REQUEST['expert'] ?? false;
|
||||
|
||||
if(isset($_REQUEST['drophub'])) {
|
||||
hubloc_mark_as_down($_REQUEST['drophub']);
|
||||
remove_queue_by_posturl($_REQUEST['drophub']);
|
||||
LibQueue::remove_by_posturl($_REQUEST['drophub']);
|
||||
}
|
||||
|
||||
if($_REQUEST['emptyhub']) {
|
||||
remove_queue_by_posturl($_REQUEST['emptyhub']);
|
||||
|
||||
if(isset($_REQUEST['emptyhub'])) {
|
||||
LibQueue::remove_by_posturl($_REQUEST['emptyhub']);
|
||||
}
|
||||
|
||||
$r = q("select count(outq_posturl) as total, max(outq_priority) as priority, outq_posturl from outq
|
||||
|
||||
if(isset($_REQUEST['deliverhub'])) {
|
||||
|
||||
$hubq = q("SELECT * FROM outq WHERE outq_posturl = '%s'",
|
||||
dbesc($_REQUEST['deliverhub'])
|
||||
);
|
||||
|
||||
foreach ($hubq as $q) {
|
||||
LibQueue::deliver($q, true);
|
||||
}
|
||||
}
|
||||
|
||||
$r = dbq("select count(outq_posturl) as total, max(outq_priority) as priority, outq_posturl from outq
|
||||
where outq_delivered = 0 group by outq_posturl order by total desc");
|
||||
|
||||
|
||||
for($x = 0; $x < count($r); $x ++) {
|
||||
$r[$x]['eurl'] = urlencode($r[$x]['outq_posturl']);
|
||||
$r[$x]['connected'] = datetime_convert('UTC',date_default_timezone_get(),$r[$x]['connected'],'Y-m-d');
|
||||
}
|
||||
|
||||
|
||||
$o = replace_macros(get_markup_template('admin_queue.tpl'), array(
|
||||
'$banner' => t('Queue Statistics'),
|
||||
'$numentries' => t('Total Entries'),
|
||||
'$priority' => t('Priority'),
|
||||
'$desturl' => t('Destination URL'),
|
||||
'$nukehub' => t('Mark hub permanently offline'),
|
||||
'$deliverhub' => t('Retry delivery to this hub'),
|
||||
'$empty' => t('Empty queue for this hub'),
|
||||
'$lastconn' => t('Last known contact'),
|
||||
'$hasentries' => ((count($r)) ? true : false),
|
||||
'$entries' => $r,
|
||||
'$expert' => $expert
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ class Site {
|
||||
set_config('system', 'register_duty', $this->register_duty);
|
||||
set_config('system', 'register_duty_jso', $this->joo);
|
||||
} else {
|
||||
notice('ZAR0130E,'.t('Errors') . ': ' . $this->error) . EOL . $this->msgfg;
|
||||
notice('ZAR0130E,' . t('Errors') . ': ' . $this->error . EOL . $this->msgfg . EOL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -339,12 +339,15 @@ class Site {
|
||||
// now invert the logic for the setting.
|
||||
$discover_tab = (1 - $discover_tab);
|
||||
|
||||
$perm_roles = \Zotlabs\Access\PermissionRoles::roles();
|
||||
$default_role = get_config('system','default_permissions_role','social');
|
||||
$perm_roles = \Zotlabs\Access\PermissionRoles::channel_roles();
|
||||
$default_role = get_config('system', 'default_permissions_role', 'personal');
|
||||
|
||||
if (!in_array($default_role, array_keys($perm_roles))) {
|
||||
$default_role = 'personal';
|
||||
}
|
||||
|
||||
$role = array('permissions_role' , t('Default permission role for new accounts'), $default_role, t('This role will be used for the first channel created after registration.'),$perm_roles);
|
||||
|
||||
|
||||
$homelogin = get_config('system','login_on_homepage');
|
||||
$enable_context_help = get_config('system','enable_context_help');
|
||||
|
||||
@@ -480,12 +483,12 @@ class Site {
|
||||
'$invitation_only' => [
|
||||
'invitation_only',
|
||||
t("Require invite code"),
|
||||
$invitation_only
|
||||
get_config('system', 'invitation_only', 0)
|
||||
],
|
||||
'$invitation_also' => [
|
||||
'invitation_also',
|
||||
t("Allow invite code"),
|
||||
$invitation_also
|
||||
get_config('system', 'invitation_also', 0)
|
||||
],
|
||||
'$verify_email' => [
|
||||
'verify_email',
|
||||
|
||||
@@ -44,17 +44,14 @@ class Affinity extends \Zotlabs\Web\Controller {
|
||||
if(! local_channel())
|
||||
return;
|
||||
|
||||
$desc = t('This app presents a slider control in your connection editor and also on your network page. The slider represents your degree of friendship (affinity) with each connection. It allows you to zoom in or out and display conversations from only your closest friends or everybody in your stream.');
|
||||
if(! Apps::system_app_installed(local_channel(),'Affinity Tool')) {
|
||||
if(! Apps::system_app_installed(local_channel(), 'Affinity Tool')) {
|
||||
//Do not display any associated widgets at this point
|
||||
App::$pdl = '';
|
||||
|
||||
$o = '<b>' . t('Affinity Tool App') . ' (' . t('Not Installed') . '):</b><br>';
|
||||
$o .= $desc;
|
||||
return $o;
|
||||
$papp = Apps::get_papp('Affinity Tool');
|
||||
return Apps::app_render($papp, 'module');
|
||||
}
|
||||
|
||||
$text = t('The numbers below represent the minimum and maximum slider default positions for your network/stream page as a percentage.');
|
||||
$text = t('The numbers below represent the minimum and maximum slider default positions for your network/stream page as a percentage.');
|
||||
|
||||
$content = '<div class="section-content-info-wrapper">' . $text . '</div>';
|
||||
|
||||
|
||||
103
Zotlabs/Module/Album.php
Normal file
103
Zotlabs/Module/Album.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Web\Controller;
|
||||
use Zotlabs\Lib\Activity;
|
||||
use Zotlabs\Lib\ActivityStreams;
|
||||
use Zotlabs\Lib\Config;
|
||||
use Zotlabs\Web\HTTPSig;
|
||||
|
||||
require_once('include/security.php');
|
||||
require_once('include/attach.php');
|
||||
require_once('include/photo/photo_driver.php');
|
||||
require_once('include/photos.php');
|
||||
|
||||
|
||||
class Album extends Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
if (ActivityStreams::is_as_request()) {
|
||||
$sigdata = HTTPSig::verify(EMPTY_STR);
|
||||
if ($sigdata['portable_id'] && $sigdata['header_valid']) {
|
||||
$portable_id = $sigdata['portable_id'];
|
||||
if (!check_channelallowed($portable_id)) {
|
||||
http_status_exit(403, 'Permission denied');
|
||||
}
|
||||
if (!check_siteallowed($sigdata['signer'])) {
|
||||
http_status_exit(403, 'Permission denied');
|
||||
}
|
||||
observer_auth($portable_id);
|
||||
}
|
||||
elseif (Config::get('system', 'require_authenticated_fetch', false)) {
|
||||
http_status_exit(403, 'Permission denied');
|
||||
}
|
||||
|
||||
$observer_xchan = get_observer_hash();
|
||||
$allowed = false;
|
||||
|
||||
$bear = Activity::token_from_request();
|
||||
if ($bear) {
|
||||
logger('bear: ' . $bear, LOGGER_DEBUG);
|
||||
}
|
||||
|
||||
$channel = null;
|
||||
|
||||
if (argc() > 1) {
|
||||
$channel = channelx_by_nick(argv(1));
|
||||
}
|
||||
if (!$channel) {
|
||||
http_status_exit(404, 'Not found.');
|
||||
}
|
||||
|
||||
$sql_extra = permissions_sql($channel['channel_id'], $observer_xchan);
|
||||
|
||||
if (argc() > 2) {
|
||||
$folder = argv(2);
|
||||
$r = q("select * from attach where is_dir = 1 and hash = '%s' and uid = %d $sql_extra limit 1",
|
||||
dbesc($folder),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
$allowed = (($r) ? attach_can_view($channel['channel_id'], $observer_xchan, $r[0]['hash'] /*,$bear */) : false);
|
||||
}
|
||||
else {
|
||||
$folder = EMPTY_STR;
|
||||
$allowed = perm_is_allowed($channel['channel_id'], $observer_xchan, 'view_storage');
|
||||
}
|
||||
|
||||
if (!$allowed) {
|
||||
http_status_exit(403, 'Permission denied.');
|
||||
}
|
||||
|
||||
$x = q("select * from attach where folder = '%s' and uid = %d $sql_extra",
|
||||
dbesc($folder),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
$contents = [];
|
||||
|
||||
if ($x) {
|
||||
foreach ($x as $xv) {
|
||||
if (intval($xv['is_dir'])) {
|
||||
continue;
|
||||
}
|
||||
if (!attach_can_view($channel['channel_id'], $observer_xchan, $xv['hash'] /*,$bear*/)) {
|
||||
continue;
|
||||
}
|
||||
if (intval($xv['is_photo'])) {
|
||||
$contents[] = z_root() . '/photo/' . $xv['hash'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$obj = Activity::encode_simple_collection($contents, App::$query_string, 'OrderedCollection', count($contents));
|
||||
as_return_and_die($obj, $channel);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
//require_once('include/apps.php');
|
||||
|
||||
use \Zotlabs\Lib as Zlib;
|
||||
use App;
|
||||
use Zotlabs\Lib\Apps;
|
||||
use Zotlabs\Lib\Libsync;
|
||||
|
||||
class Appman extends \Zotlabs\Web\Controller {
|
||||
|
||||
function post() {
|
||||
|
||||
|
||||
if(! local_channel())
|
||||
return;
|
||||
|
||||
if($_POST['url']) {
|
||||
|
||||
if(isset($_POST['url']) && $_POST['url']) {
|
||||
$arr = array(
|
||||
'uid' => intval($_REQUEST['uid']),
|
||||
'url' => escape_tags($_REQUEST['url']),
|
||||
@@ -32,70 +32,136 @@ class Appman extends \Zotlabs\Web\Controller {
|
||||
'sig' => escape_tags($_REQUEST['sig']),
|
||||
'categories' => escape_tags($_REQUEST['categories'])
|
||||
);
|
||||
|
||||
$_REQUEST['appid'] = Zlib\Apps::app_install(local_channel(),$arr);
|
||||
|
||||
if(Zlib\Apps::app_installed(local_channel(),$arr))
|
||||
|
||||
$_REQUEST['appid'] = Apps::app_install(local_channel(),$arr);
|
||||
|
||||
if(Apps::app_installed(local_channel(),$arr))
|
||||
info( t('App installed.') . EOL);
|
||||
|
||||
goaway(z_root() . '/apps');
|
||||
return; //not reached
|
||||
}
|
||||
|
||||
|
||||
$papp = Zlib\Apps::app_decode($_POST['papp']);
|
||||
|
||||
|
||||
|
||||
$papp = Apps::app_decode($_POST['papp']);
|
||||
|
||||
if(! is_array($papp)) {
|
||||
notice( t('Malformed app.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if($_POST['install']) {
|
||||
Zlib\Apps::app_install(local_channel(),$papp);
|
||||
if(Zlib\Apps::app_installed(local_channel(),$papp))
|
||||
|
||||
if(isset($_POST['install']) && $_POST['install']) {
|
||||
Apps::app_install(local_channel(),$papp);
|
||||
if(Apps::app_installed(local_channel(),$papp))
|
||||
info( t('App installed.') . EOL);
|
||||
}
|
||||
|
||||
if($_POST['delete']) {
|
||||
Zlib\Apps::app_destroy(local_channel(),$papp);
|
||||
|
||||
$sync = q("SELECT * FROM app WHERE app_channel = %d AND app_id = '%s' LIMIT 1",
|
||||
intval(local_channel()),
|
||||
dbesc($papp['guid'])
|
||||
);
|
||||
|
||||
if (!$sync) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (intval($sync[0]['app_system'])) {
|
||||
Libsync::build_sync_packet(local_channel(), ['sysapp' => $sync]);
|
||||
}
|
||||
else {
|
||||
Libsync::build_sync_packet(local_channel(), ['app' => $sync]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if($_POST['edit']) {
|
||||
if(isset($_POST['delete']) && $_POST['delete']) {
|
||||
|
||||
// Fetch the app for sync before it is deleted (if it is deletable))
|
||||
$sync = q("SELECT * FROM app WHERE app_channel = %d AND app_id = '%s' LIMIT 1",
|
||||
intval(local_channel()),
|
||||
dbesc($papp['guid'])
|
||||
);
|
||||
|
||||
if (!$sync) {
|
||||
return;
|
||||
}
|
||||
|
||||
Apps::app_destroy(local_channel(), $papp);
|
||||
|
||||
// Now flag it deleted
|
||||
$sync[0]['app_deleted'] = 1;
|
||||
|
||||
if (intval($sync[0]['app_system'])) {
|
||||
Libsync::build_sync_packet(local_channel(), ['sysapp' => $sync]);
|
||||
}
|
||||
else {
|
||||
Libsync::build_sync_packet(local_channel(), ['app' => $sync]);
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($_POST['edit']) && $_POST['edit']) {
|
||||
return;
|
||||
}
|
||||
|
||||
if($_POST['feature']) {
|
||||
Zlib\Apps::app_feature(local_channel(), $papp, $_POST['feature']);
|
||||
if(isset($_POST['feature']) && $_POST['feature']) {
|
||||
Apps::app_feature(local_channel(), $papp, $_POST['feature']);
|
||||
|
||||
$sync = q("SELECT * FROM app WHERE app_channel = %d AND app_id = '%s' LIMIT 1",
|
||||
intval(local_channel()),
|
||||
dbesc($papp['guid'])
|
||||
);
|
||||
|
||||
if (intval($sync[0]['app_system'])) {
|
||||
Libsync::build_sync_packet(local_channel(), ['sysapp' => $sync]);
|
||||
}
|
||||
else {
|
||||
Libsync::build_sync_packet(local_channel(), ['app' => $sync]);
|
||||
}
|
||||
}
|
||||
|
||||
if($_POST['pin']) {
|
||||
Zlib\Apps::app_feature(local_channel(), $papp, $_POST['pin']);
|
||||
if(isset($_POST['pin']) && $_POST['pin']) {
|
||||
Apps::app_feature(local_channel(), $papp, $_POST['pin']);
|
||||
|
||||
$sync = q("SELECT * FROM app WHERE app_channel = %d AND app_id = '%s' LIMIT 1",
|
||||
intval(local_channel()),
|
||||
dbesc($papp['guid'])
|
||||
);
|
||||
|
||||
if (intval($sync[0]['app_system'])) {
|
||||
Libsync::build_sync_packet(local_channel(), ['sysapp' => $sync]);
|
||||
}
|
||||
else {
|
||||
Libsync::build_sync_packet(local_channel(), ['app' => $sync]);
|
||||
}
|
||||
}
|
||||
|
||||
if($_SESSION['return_url'])
|
||||
if(isset($_POST['aj']) && $_POST['aj']) {
|
||||
killme();
|
||||
}
|
||||
|
||||
if($_SESSION['return_url'])
|
||||
goaway(z_root() . '/' . $_SESSION['return_url']);
|
||||
|
||||
goaway(z_root() . '/apps');
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
|
||||
if(! local_channel()) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = \App::get_channel();
|
||||
$channel = App::get_channel();
|
||||
|
||||
if(argc() > 3) {
|
||||
if(argv(2) === 'moveup') {
|
||||
Zlib\Apps::moveup(local_channel(),argv(1),argv(3));
|
||||
Apps::moveup(local_channel(),argv(1),argv(3));
|
||||
}
|
||||
if(argv(2) === 'movedown') {
|
||||
Zlib\Apps::movedown(local_channel(),argv(1),argv(3));
|
||||
Apps::movedown(local_channel(),argv(1),argv(3));
|
||||
}
|
||||
goaway(z_root() . '/apporder');
|
||||
}
|
||||
@@ -105,7 +171,7 @@ class Appman extends \Zotlabs\Web\Controller {
|
||||
|
||||
$app = null;
|
||||
$embed = null;
|
||||
if($_REQUEST['appid']) {
|
||||
if(isset($_REQUEST['appid']) && $_REQUEST['appid']) {
|
||||
$r = q("select * from app where app_id = '%s' and app_channel = %d limit 1",
|
||||
dbesc($_REQUEST['appid']),
|
||||
dbesc(local_channel())
|
||||
@@ -129,32 +195,30 @@ class Appman extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
$embed = array('embed', t('Embed code'), Zlib\Apps::app_encode($app,true),'', 'onclick="this.select();"');
|
||||
|
||||
$embed = array('embed', t('Embed code'), Apps::app_encode($app,true),'', 'onclick="this.select();"');
|
||||
|
||||
}
|
||||
|
||||
|
||||
return replace_macros(get_markup_template('app_create.tpl'), array(
|
||||
|
||||
'$banner' => (($app) ? t('Edit App') : t('Create App')),
|
||||
'$app' => $app,
|
||||
'$guid' => (($app) ? $app['app_id'] : ''),
|
||||
'$author' => (($app) ? $app['app_author'] : $channel['channel_hash']),
|
||||
'$addr' => (($app) ? $app['app_addr'] : $channel['xchan_addr']),
|
||||
'$name' => array('name', t('Name of app'),(($app) ? $app['app_name'] : ''), t('Required')),
|
||||
'$url' => array('url', t('Location (URL) of app'),(($app) ? $app['app_url'] : ''), t('Required')),
|
||||
'$desc' => array('desc', t('Description'),(($app) ? $app['app_desc'] : ''), ''),
|
||||
'$photo' => array('photo', t('Photo icon URL'),(($app) ? $app['app_photo'] : ''), t('80 x 80 pixels - optional')),
|
||||
'$categories' => array('categories',t('Categories (optional, comma separated list)'),(($app) ? $app['categories'] : ''),''),
|
||||
'$version' => array('version', t('Version ID'),(($app) ? $app['app_version'] : ''), ''),
|
||||
'$price' => array('price', t('Price of app'),(($app) ? $app['app_price'] : ''), ''),
|
||||
'$page' => array('page', t('Location (URL) to purchase app'),(($app) ? $app['app_page'] : ''), ''),
|
||||
'$system' => (($app) ? intval($app['app_system']) : 0),
|
||||
'$plugin' => (($app) ? $app['app_plugin'] : ''),
|
||||
'$requires' => (($app) ? $app['app_requires'] : ''),
|
||||
'$guid' => $app['app_id'] ?? '',
|
||||
'$author' => $app['app_author'] ?? $channel['channel_hash'],
|
||||
'$addr' => $app['app_addr'] ?? $channel['xchan_addr'],
|
||||
'$name' => array('name', t('Name of app'), $app['app_name'] ?? '', t('Required')),
|
||||
'$url' => array('url', t('Location (URL) of app'), $app['app_url'] ?? '', t('Required')),
|
||||
'$desc' => array('desc', t('Description'), $app['app_desc'] ?? '', ''),
|
||||
'$photo' => array('photo', t('Photo icon URL'),$app['app_photo'] ?? '', t('80 x 80 pixels - optional')),
|
||||
'$categories' => array('categories',t('Categories (optional, comma separated list)'), $app['categories'] ?? '',''),
|
||||
'$version' => array('version', t('Version ID'), $app['app_version'] ?? '', ''),
|
||||
'$price' => array('price', t('Price of app'), $app['app_price'] ?? '', ''),
|
||||
'$page' => array('page', t('Location (URL) to purchase app'), $app['app_page'] ?? '', ''),
|
||||
'$system' => $app['app_system'] ?? 0,
|
||||
'$plugin' => $app['app_plugin'] ?? '',
|
||||
'$requires' => $app['app_requires'] ?? '',
|
||||
'$embed' => $embed,
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ class Apps extends \Zotlabs\Web\Controller {
|
||||
function get() {
|
||||
|
||||
nav_set_selected('Apps');
|
||||
|
||||
|
||||
if(argc() == 2 && argv(1) == 'edit')
|
||||
$mode = 'edit';
|
||||
else
|
||||
@@ -18,9 +18,10 @@ class Apps extends \Zotlabs\Web\Controller {
|
||||
$available = ((argc() == 2 && argv(1) === 'available') ? true : false);
|
||||
|
||||
$_SESSION['return_url'] = \App::$query_string;
|
||||
|
||||
$apps = array();
|
||||
|
||||
|
||||
$apps = [];
|
||||
$cat = [];
|
||||
|
||||
if(local_channel()) {
|
||||
Zlib\Apps::import_system_apps();
|
||||
$syslist = array();
|
||||
@@ -37,9 +38,9 @@ class Apps extends \Zotlabs\Web\Controller {
|
||||
$syslist = Zlib\Apps::get_system_apps(true);
|
||||
|
||||
usort($syslist,'Zotlabs\\Lib\\Apps::app_name_compare');
|
||||
|
||||
|
||||
// logger('apps: ' . print_r($syslist,true));
|
||||
|
||||
|
||||
foreach($syslist as $app) {
|
||||
$apps[] = Zlib\Apps::app_render($app,(($available) ? 'install' : $mode));
|
||||
}
|
||||
@@ -53,7 +54,7 @@ class Apps extends \Zotlabs\Web\Controller {
|
||||
'$manage' => (($available) ? '' : t('Manage Apps')),
|
||||
'$create' => (($mode == 'edit') ? t('Create Custom App') : '')
|
||||
));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ class Apschema extends \Zotlabs\Web\Controller {
|
||||
'zot' => z_root() . '/apschema#',
|
||||
'id' => '@id',
|
||||
'type' => '@type',
|
||||
'commentPolicy' => 'as:commentPolicy',
|
||||
'commentPolicy' => 'zot:commentPolicy',
|
||||
'meData' => 'zot:meData',
|
||||
'meDataType' => 'zot:meDataType',
|
||||
'meEncoding' => 'zot:meEncoding',
|
||||
@@ -33,6 +33,9 @@ class Apschema extends \Zotlabs\Web\Controller {
|
||||
'PropertyValue' => 'schema:PropertyValue',
|
||||
'value' => 'schema:value',
|
||||
|
||||
'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers',
|
||||
|
||||
|
||||
'magicEnv' => [
|
||||
'@id' => 'zot:magicEnv',
|
||||
'@type' => '@id'
|
||||
@@ -50,7 +53,7 @@ class Apschema extends \Zotlabs\Web\Controller {
|
||||
'guid' => 'diaspora:guid',
|
||||
|
||||
'Hashtag' => 'as:Hashtag'
|
||||
|
||||
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/channel.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/conversation.php');
|
||||
|
||||
class Article_edit extends \Zotlabs\Web\Controller {
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
// Figure out which post we're editing
|
||||
$post_id = ((argc() > 1) ? intval(argv(1)) : 0);
|
||||
|
||||
if(! $post_id) {
|
||||
notice( t('Item not found') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$itm = q("SELECT * FROM item WHERE id = %d and item_type = %d LIMIT 1",
|
||||
intval($post_id),
|
||||
intval(ITEM_TYPE_ARTICLE)
|
||||
);
|
||||
if($itm) {
|
||||
$item_id = q("select * from iconfig where cat = 'system' and k = 'ARTICLE' and iid = %d limit 1",
|
||||
intval($itm[0]['id'])
|
||||
);
|
||||
if($item_id)
|
||||
$card_title = $item_id[0]['v'];
|
||||
}
|
||||
else {
|
||||
notice( t('Item not found') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$owner = $itm[0]['uid'];
|
||||
$uid = local_channel();
|
||||
|
||||
$observer = \App::get_observer();
|
||||
|
||||
$channel = channelx_by_n($owner);
|
||||
if(! $channel) {
|
||||
notice( t('Channel not found.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
|
||||
|
||||
if(! perm_is_allowed($owner,$ob_hash,'write_pages')) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$is_owner = (($uid && $uid == $owner) ? true : false);
|
||||
|
||||
$o = '';
|
||||
|
||||
|
||||
|
||||
$category = '';
|
||||
$catsenabled = ((feature_enabled($owner,'categories')) ? 'categories' : '');
|
||||
|
||||
if ($catsenabled){
|
||||
$itm = fetch_post_tags($itm);
|
||||
|
||||
$cats = get_terms_oftype($itm[0]['term'], TERM_CATEGORY);
|
||||
|
||||
foreach ($cats as $cat) {
|
||||
if (strlen($category))
|
||||
$category .= ', ';
|
||||
$category .= $cat['term'];
|
||||
}
|
||||
}
|
||||
|
||||
if($itm[0]['attach']) {
|
||||
$j = json_decode($itm[0]['attach'],true);
|
||||
if($j) {
|
||||
foreach($j as $jj) {
|
||||
$itm[0]['body'] .= "\n" . '[attachment]' . basename($jj['href']) . ',' . $jj['revision'] . '[/attachment]' . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$mimetype = $itm[0]['mimetype'];
|
||||
|
||||
$summary = (($itm[0]['summary']) ? '[summary]' . $itm[0]['summary'] . '[/summary]' . "\r\n" : '');
|
||||
$content = $itm[0]['body'];
|
||||
|
||||
$rp = 'articles/' . $channel['channel_address'];
|
||||
|
||||
$x = array(
|
||||
'nickname' => $channel['channel_address'],
|
||||
'bbco_autocomplete'=> 'bbcode',
|
||||
'return_path' => $rp,
|
||||
'webpage' => ITEM_TYPE_ARTICLE,
|
||||
'button' => t('Edit'),
|
||||
'writefiles' => perm_is_allowed($owner, get_observer_hash(), 'write_pages'),
|
||||
'weblink' => t('Insert web link'),
|
||||
'hide_voting' => false,
|
||||
'hide_future' => false,
|
||||
'hide_location' => false,
|
||||
'hide_expire' => false,
|
||||
'showacl' => true,
|
||||
'acl' => populate_acl($itm[0],false,\Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')),
|
||||
'permissions' => $itm[0],
|
||||
'lockstate' => (($itm[0]['allow_cid'] || $itm[0]['allow_gid'] || $itm[0]['deny_cid'] || $itm[0]['deny_gid']) ? 'lock' : 'unlock'),
|
||||
'ptyp' => $itm[0]['type'],
|
||||
'mimeselect' => false,
|
||||
'mimetype' => $itm[0]['mimetype'],
|
||||
'body' => $summary . undo_post_tagging($content),
|
||||
'post_id' => $post_id,
|
||||
'visitor' => true,
|
||||
'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'),
|
||||
'summary' => htmlspecialchars($itm[0]['summary'],ENT_COMPAT,'UTF-8'),
|
||||
'placeholdertitle' => t('Title (optional)'),
|
||||
'pagetitle' => $card_title,
|
||||
'profile_uid' => (intval($channel['channel_id'])),
|
||||
'catsenabled' => $catsenabled,
|
||||
'category' => $category,
|
||||
'bbcode' => (($mimetype == 'text/bbcode') ? true : false)
|
||||
);
|
||||
|
||||
$editor = status_editor($a, $x, false, 'Article_edit');
|
||||
|
||||
$o .= replace_macros(get_markup_template('edpost_head.tpl'), array(
|
||||
'$title' => t('Edit Article'),
|
||||
'$delete' => ((($itm[0]['author_xchan'] === $ob_hash) || ($itm[0]['owner_xchan'] === $ob_hash)) ? t('Delete') : false),
|
||||
'$id' => $itm[0]['id'],
|
||||
'$cancel' => t('Cancel'),
|
||||
'$editor' => $editor
|
||||
));
|
||||
|
||||
return $o;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,234 +0,0 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Lib\Apps;
|
||||
use Zotlabs\Web\Controller;
|
||||
use Zotlabs\Lib\PermissionDescription;
|
||||
|
||||
require_once('include/channel.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/opengraph.php');
|
||||
|
||||
|
||||
class Articles extends Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
if(argc() > 1)
|
||||
$which = argv(1);
|
||||
|
||||
if(! $which) {
|
||||
if(local_channel()) {
|
||||
$channel = App::get_channel();
|
||||
if($channel && $channel['channel_address'])
|
||||
$which = $channel['channel_address'];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
profile_load($which);
|
||||
|
||||
}
|
||||
|
||||
function get($update = 0, $load = false) {
|
||||
|
||||
if(observer_prohibited(true)) {
|
||||
return login();
|
||||
}
|
||||
|
||||
if(! App::$profile) {
|
||||
notice( t('Requested profile is not available.') . EOL );
|
||||
App::$error = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
if(! Apps::system_app_installed(App::$profile_uid, 'Articles')) {
|
||||
//Do not display any associated widgets at this point
|
||||
App::$pdl = '';
|
||||
|
||||
$o = '<b>' . t('Articles App') . ' (' . t('Not Installed') . '):</b><br>';
|
||||
$o .= t('Create interactive articles');
|
||||
return $o;
|
||||
}
|
||||
|
||||
nav_set_selected('Articles');
|
||||
|
||||
head_add_link([
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/json+oembed',
|
||||
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . App::$query_string),
|
||||
'title' => 'oembed'
|
||||
]);
|
||||
|
||||
|
||||
$category = (($_REQUEST['cat']) ? escape_tags(trim($_REQUEST['cat'])) : '');
|
||||
|
||||
if($category) {
|
||||
$sql_extra2 .= protect_sprintf(term_item_parent_query(App::$profile['profile_uid'],'item', $category, TERM_CATEGORY));
|
||||
}
|
||||
|
||||
$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']) : '');
|
||||
|
||||
$which = argv(1);
|
||||
|
||||
$selected_card = ((argc() > 2) ? argv(2) : '');
|
||||
|
||||
$_SESSION['return_url'] = App::$query_string;
|
||||
|
||||
$uid = local_channel();
|
||||
$owner = App::$profile_uid;
|
||||
$observer = App::get_observer();
|
||||
|
||||
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
|
||||
|
||||
if(! perm_is_allowed($owner,$ob_hash,'view_pages')) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$is_owner = ($uid && $uid == $owner);
|
||||
|
||||
$channel = channelx_by_n($owner);
|
||||
|
||||
if($channel) {
|
||||
$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 = [ 'allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '' ];
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(perm_is_allowed($owner,$ob_hash,'write_pages')) {
|
||||
|
||||
$x = [
|
||||
'webpage' => ITEM_TYPE_ARTICLE,
|
||||
'is_owner' => true,
|
||||
'content_label' => t('Add Article'),
|
||||
'button' => t('Save'),
|
||||
'nickname' => $channel['channel_address'],
|
||||
'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid']
|
||||
|| $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
|
||||
'acl' => (($is_owner) ? populate_acl($channel_acl, false,
|
||||
PermissionDescription::fromGlobalPermission('view_pages')) : ''),
|
||||
'permissions' => $channel_acl,
|
||||
'showacl' => (($is_owner) ? true : false),
|
||||
'visitor' => true,
|
||||
'hide_location' => false,
|
||||
'hide_voting' => false,
|
||||
'profile_uid' => intval($owner),
|
||||
'mimetype' => 'text/bbcode',
|
||||
'mimeselect' => false,
|
||||
'layoutselect' => false,
|
||||
'expanded' => false,
|
||||
'novoting' => false,
|
||||
'catsenabled' => feature_enabled($owner,'categories'),
|
||||
'bbco_autocomplete' => 'bbcode',
|
||||
'bbcode' => true
|
||||
];
|
||||
|
||||
if($_REQUEST['title'])
|
||||
$x['title'] = $_REQUEST['title'];
|
||||
if($_REQUEST['body'])
|
||||
$x['body'] = $_REQUEST['body'];
|
||||
$editor = status_editor($a,$x,false,'Articles');
|
||||
|
||||
}
|
||||
else {
|
||||
$editor = '';
|
||||
}
|
||||
|
||||
$itemspage = get_pconfig(local_channel(),'system','itemspage');
|
||||
App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10));
|
||||
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start']));
|
||||
|
||||
|
||||
$sql_extra = item_permissions_sql($owner);
|
||||
$sql_item = '';
|
||||
|
||||
if($selected_card) {
|
||||
$r = q("select * from iconfig where iconfig.cat = 'system' and iconfig.k = 'ARTICLE' and iconfig.v = '%s' limit 1",
|
||||
dbesc($selected_card)
|
||||
);
|
||||
if($r) {
|
||||
$sql_item = "and item.id = " . intval($r[0]['iid']) . " ";
|
||||
}
|
||||
}
|
||||
if($datequery) {
|
||||
$sql_extra2 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery))));
|
||||
$order = 'post';
|
||||
}
|
||||
if($datequery2) {
|
||||
$sql_extra2 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2))));
|
||||
}
|
||||
|
||||
if($datequery || $datequery2) {
|
||||
$sql_extra2 .= " and item.item_thread_top != 0 ";
|
||||
}
|
||||
|
||||
$r = q("select * from item
|
||||
where item.uid = %d and item_type = %d
|
||||
$sql_extra $sql_extra2 $sql_item order by item.created desc $pager_sql",
|
||||
intval($owner),
|
||||
intval(ITEM_TYPE_ARTICLE)
|
||||
);
|
||||
|
||||
$item_normal = " and item.item_hidden = 0 and item.item_type in (0,7) and item.item_deleted = 0
|
||||
and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0
|
||||
and item.item_blocked = 0 ";
|
||||
|
||||
if($r) {
|
||||
|
||||
$pager_total = count($r);
|
||||
|
||||
$parents_str = ids_to_querystr($r,'id');
|
||||
|
||||
$r = q("SELECT item.*, item.id AS item_id
|
||||
FROM item
|
||||
WHERE item.uid = %d $item_normal
|
||||
AND item.parent IN ( %s )
|
||||
$sql_extra $sql_extra2 ",
|
||||
intval(App::$profile['profile_uid']),
|
||||
dbesc($parents_str)
|
||||
);
|
||||
if($r) {
|
||||
xchan_query($r);
|
||||
$items = fetch_post_tags($r, true);
|
||||
$items = conv_sort($items,'updated');
|
||||
}
|
||||
else
|
||||
$items = [];
|
||||
}
|
||||
|
||||
// Add Opengraph markup
|
||||
opengraph_add_meta((! empty($items) ? $r[0] : []), $channel);
|
||||
|
||||
$mode = 'articles';
|
||||
|
||||
if(get_pconfig(local_channel(),'system','articles_list_mode') && (! $selected_card))
|
||||
$page_mode = 'pager_list';
|
||||
else
|
||||
$page_mode = 'traditional';
|
||||
|
||||
$content = conversation($items,$mode,false,$page_mode);
|
||||
|
||||
$o = replace_macros(get_markup_template('cards.tpl'), [
|
||||
'$title' => t('Articles'),
|
||||
'$editor' => $editor,
|
||||
'$content' => $content,
|
||||
'$pager' => alt_pager($pager_total)
|
||||
]);
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +1,38 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/zot.php');
|
||||
|
||||
|
||||
class Authtest extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
|
||||
|
||||
|
||||
$auth_success = false;
|
||||
$o .= '<h3>Magic-Auth Diagnostic</h3>';
|
||||
|
||||
|
||||
if(! local_channel()) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
$o .= '<form action="authtest" method="get">';
|
||||
$o .= 'Target URL: <input type="text" style="width: 250px;" name="dest" value="' . $_GET['dest'] .'" />';
|
||||
$o .= '<input type="submit" name="submit" value="Submit" /></form>';
|
||||
|
||||
$o .= '<input type="submit" name="submit" value="Submit" /></form>';
|
||||
|
||||
$o .= '<br /><br />';
|
||||
|
||||
|
||||
if(x($_GET,'dest')) {
|
||||
if(strpos($_GET['dest'],'@')) {
|
||||
$_GET['dest'] = $_REQUEST['dest'] = 'https://' . substr($_GET['dest'],strpos($_GET['dest'],'@')+1) . '/channel/' . substr($_GET['dest'],0,strpos($_GET['dest'],'@'));
|
||||
}
|
||||
|
||||
|
||||
$_REQUEST['test'] = 1;
|
||||
$mod = new Magic();
|
||||
$x = $mod->init($a);
|
||||
|
||||
$o .= 'Local Setup returns: ' . print_r($x,true);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if($x['url']) {
|
||||
$z = z_fetch_url($x['url'] . '&test=1');
|
||||
if($z['success']) {
|
||||
@@ -50,12 +47,12 @@ class Authtest extends \Zotlabs\Web\Controller {
|
||||
$o .= 'fetch url failure.' . print_r($z,true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(! $auth_success)
|
||||
$o .= 'Authentication Failed!' . EOL;
|
||||
}
|
||||
|
||||
|
||||
return str_replace("\n",'<br />',$o);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -9,43 +9,43 @@ require_once('include/acl_selectors.php');
|
||||
class Blocks extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
|
||||
if(argc() > 1 && argv(1) === 'sys' && is_site_admin()) {
|
||||
$sys = get_sys_channel();
|
||||
if($sys && intval($sys['channel_id'])) {
|
||||
\App::$is_sys = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(argc() > 1)
|
||||
$which = argv(1);
|
||||
else
|
||||
return;
|
||||
|
||||
|
||||
profile_load($which);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
|
||||
if(! \App::$profile) {
|
||||
notice( t('Requested profile is not available.') . EOL );
|
||||
\App::$error = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$which = argv(1);
|
||||
|
||||
|
||||
$_SESSION['return_url'] = \App::$query_string;
|
||||
|
||||
|
||||
$uid = local_channel();
|
||||
$owner = 0;
|
||||
$channel = null;
|
||||
$observer = \App::get_observer();
|
||||
|
||||
|
||||
$channel = \App::get_channel();
|
||||
|
||||
|
||||
if(\App::$is_sys && is_site_admin()) {
|
||||
$sys = get_sys_channel();
|
||||
if($sys && intval($sys['channel_id'])) {
|
||||
@@ -54,7 +54,7 @@ class Blocks extends \Zotlabs\Web\Controller {
|
||||
$observer = $sys;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(! $owner) {
|
||||
// Figure out who the page owner is.
|
||||
$r = q("select channel_id from channel where channel_address = '%s'",
|
||||
@@ -64,24 +64,24 @@ class Blocks extends \Zotlabs\Web\Controller {
|
||||
$owner = intval($r[0]['channel_id']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
|
||||
|
||||
|
||||
$perms = get_all_perms($owner,$ob_hash);
|
||||
|
||||
|
||||
if(! $perms['write_pages']) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Block design features from visitors
|
||||
|
||||
|
||||
// Block design features from visitors
|
||||
|
||||
if((! $uid) || ($uid != $owner)) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$mimetype = (($_REQUEST['mimetype']) ? $_REQUEST['mimetype'] : get_pconfig($owner,'system','page_mimetype'));
|
||||
|
||||
$mimetype = ((isset($_REQUEST['mimetype']) && $_REQUEST['mimetype']) ? $_REQUEST['mimetype'] : get_pconfig($owner,'system','page_mimetype'));
|
||||
|
||||
$x = array(
|
||||
'webpage' => ITEM_TYPE_BLOCK,
|
||||
@@ -101,27 +101,25 @@ class Blocks extends \Zotlabs\Web\Controller {
|
||||
'bbco_autocomplete' => 'bbcode',
|
||||
'bbcode' => true
|
||||
);
|
||||
|
||||
if($_REQUEST['title'])
|
||||
$x['title'] = $_REQUEST['title'];
|
||||
if($_REQUEST['body'])
|
||||
$x['body'] = $_REQUEST['body'];
|
||||
if($_REQUEST['pagetitle'])
|
||||
$x['pagetitle'] = $_REQUEST['pagetitle'];
|
||||
|
||||
$editor = status_editor($a,$x,false,'Blocks');
|
||||
|
||||
|
||||
$r = q("select iconfig.iid, iconfig.k, iconfig.v, mid, title, body, mimetype, created, edited from iconfig
|
||||
$x['title'] = $_REQUEST['title'] ?? '';
|
||||
$x['body'] = $_REQUEST['body'] ?? '';
|
||||
$x['pagetitle'] = $_REQUEST['pagetitle'] ?? '';
|
||||
|
||||
$a = '';
|
||||
$editor = status_editor($a,$x,false,'Blocks');
|
||||
|
||||
|
||||
$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'
|
||||
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)
|
||||
);
|
||||
|
||||
|
||||
$pages = null;
|
||||
|
||||
|
||||
if($r) {
|
||||
$pages = array();
|
||||
foreach($r as $rr) {
|
||||
@@ -143,13 +141,13 @@ class Blocks extends \Zotlabs\Web\Controller {
|
||||
'edited' => $rr['edited'],
|
||||
'bb_element' => '[element]' . base64url_encode(json_encode($element_arr)) . '[/element]'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Build the base URL for edit links
|
||||
$url = z_root() . '/editblock/' . $which;
|
||||
|
||||
$o .= replace_macros(get_markup_template('blocklist.tpl'), array(
|
||||
$url = z_root() . '/editblock/' . $which;
|
||||
|
||||
$o = replace_macros(get_markup_template('blocklist.tpl'), array(
|
||||
'$baseurl' => $url,
|
||||
'$title' => t('Blocks'),
|
||||
'$name' => t('Block Name'),
|
||||
@@ -166,8 +164,8 @@ class Blocks extends \Zotlabs\Web\Controller {
|
||||
'$view' => t('View'),
|
||||
'$preview' => '1',
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -18,31 +18,31 @@ class Bookmarks extends \Zotlabs\Web\Controller {
|
||||
|
||||
$item_id = (isset($_REQUEST['item']) ? $_REQUEST['item'] : false);
|
||||
$burl = (isset($_REQUEST['burl']) ? trim($_REQUEST['burl']) : '');
|
||||
|
||||
|
||||
if(! $item_id)
|
||||
return;
|
||||
|
||||
|
||||
$u = \App::get_channel();
|
||||
|
||||
|
||||
$item_normal = item_normal();
|
||||
|
||||
|
||||
$i = q("select * from item where id = %d and uid = %d $item_normal limit 1",
|
||||
intval($item_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
|
||||
if(! $i)
|
||||
return;
|
||||
|
||||
|
||||
$i = fetch_post_tags($i);
|
||||
|
||||
|
||||
$item = $i[0];
|
||||
|
||||
|
||||
$terms = (x($item, 'term') ? get_terms_oftype($item['term'],TERM_BOOKMARK) : false);
|
||||
|
||||
|
||||
if($terms) {
|
||||
require_once('include/bookmarks.php');
|
||||
|
||||
|
||||
$s = q("select * from xchan where xchan_hash = '%s' limit 1",
|
||||
dbesc($item['author_xchan'])
|
||||
);
|
||||
@@ -58,13 +58,13 @@ class Bookmarks extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
else
|
||||
bookmark_add($u,$s[0],$t,$item['item_private']);
|
||||
|
||||
|
||||
info( t('Bookmark added') . EOL);
|
||||
}
|
||||
}
|
||||
killme();
|
||||
}
|
||||
|
||||
|
||||
function get() {
|
||||
if(! local_channel()) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
@@ -74,49 +74,47 @@ class Bookmarks extends \Zotlabs\Web\Controller {
|
||||
if(! Apps::system_app_installed(local_channel(), 'Bookmarks')) {
|
||||
//Do not display any associated widgets at this point
|
||||
App::$pdl = '';
|
||||
|
||||
$o = '<b>' . t('Bookmarks App') . ' (' . t('Not Installed') . '):</b><br>';
|
||||
$o .= t('Bookmark links from posts and manage them');
|
||||
return $o;
|
||||
$papp = Apps::get_papp('Bookmarks');
|
||||
return Apps::app_render($papp, 'module');
|
||||
}
|
||||
|
||||
|
||||
require_once('include/menu.php');
|
||||
require_once('include/conversation.php');
|
||||
|
||||
|
||||
$channel = \App::get_channel();
|
||||
|
||||
|
||||
$o = '';
|
||||
|
||||
|
||||
$o .= '<div class="generic-content-wrapper-styled">';
|
||||
|
||||
$o .= '<h3>' . t('My Bookmarks') . '</h3>';
|
||||
|
||||
|
||||
$o .= '<h3>' . t('Bookmarks') . '</h3>';
|
||||
|
||||
$x = menu_list(local_channel(),'',MENU_BOOKMARK);
|
||||
|
||||
|
||||
if($x) {
|
||||
foreach($x as $xx) {
|
||||
$y = menu_fetch($xx['menu_name'],local_channel(),get_observer_hash());
|
||||
$o .= menu_render($y,'',true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$o .= '<h3>' . t('My Connections Bookmarks') . '</h3>';
|
||||
|
||||
|
||||
|
||||
|
||||
$x = menu_list(local_channel(),'',MENU_SYSTEM|MENU_BOOKMARK);
|
||||
|
||||
|
||||
if($x) {
|
||||
foreach($x as $xx) {
|
||||
$y = menu_fetch($xx['menu_name'],local_channel(),get_observer_hash());
|
||||
$o .= menu_render($y,'',true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$o .= '</div>';
|
||||
|
||||
|
||||
return $o;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ class Cal extends Controller {
|
||||
|
||||
head_set_icon(App::$data['channel']['xchan_photo_s']);
|
||||
|
||||
App::$page['htmlhead'] .= "<script> var profile_uid = " . ((App::$data['channel']) ? App::$data['channel']['channel_id'] : 0) . "; </script>" ;
|
||||
App::$page['htmlhead'] = "<script> var profile_uid = " . ((App::$data['channel']) ? App::$data['channel']['channel_id'] : 0) . "; </script>" ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/channel.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/conversation.php');
|
||||
|
||||
class Card_edit extends \Zotlabs\Web\Controller {
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
// Figure out which post we're editing
|
||||
$post_id = ((argc() > 1) ? intval(argv(1)) : 0);
|
||||
|
||||
if(! $post_id) {
|
||||
notice( t('Item not found') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$itm = q("SELECT * FROM item WHERE id = %d and item_type = %d LIMIT 1",
|
||||
intval($post_id),
|
||||
intval(ITEM_TYPE_CARD)
|
||||
);
|
||||
if($itm) {
|
||||
$item_id = q("select * from iconfig where cat = 'system' and k = 'CARD' and iid = %d limit 1",
|
||||
intval($itm[0]['id'])
|
||||
);
|
||||
if($item_id)
|
||||
$card_title = $item_id[0]['v'];
|
||||
}
|
||||
else {
|
||||
notice( t('Item not found') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$owner = $itm[0]['uid'];
|
||||
$uid = local_channel();
|
||||
|
||||
$observer = \App::get_observer();
|
||||
|
||||
$channel = channelx_by_n($owner);
|
||||
if(! $channel) {
|
||||
notice( t('Channel not found.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
|
||||
|
||||
if(! perm_is_allowed($owner,$ob_hash,'write_pages')) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$is_owner = (($uid && $uid == $owner) ? true : false);
|
||||
|
||||
$o = '';
|
||||
|
||||
|
||||
|
||||
$category = '';
|
||||
$catsenabled = ((feature_enabled($owner,'categories')) ? 'categories' : '');
|
||||
|
||||
if ($catsenabled){
|
||||
$itm = fetch_post_tags($itm);
|
||||
|
||||
$cats = get_terms_oftype($itm[0]['term'], TERM_CATEGORY);
|
||||
|
||||
foreach ($cats as $cat) {
|
||||
if (strlen($category))
|
||||
$category .= ', ';
|
||||
$category .= $cat['term'];
|
||||
}
|
||||
}
|
||||
|
||||
if($itm[0]['attach']) {
|
||||
$j = json_decode($itm[0]['attach'],true);
|
||||
if($j) {
|
||||
foreach($j as $jj) {
|
||||
$itm[0]['body'] .= "\n" . '[attachment]' . basename($jj['href']) . ',' . $jj['revision'] . '[/attachment]' . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$mimetype = $itm[0]['mimetype'];
|
||||
|
||||
$content = $itm[0]['body'];
|
||||
|
||||
|
||||
|
||||
$rp = 'cards/' . $channel['channel_address'];
|
||||
|
||||
$x = array(
|
||||
'nickname' => $channel['channel_address'],
|
||||
'bbco_autocomplete'=> 'bbcode',
|
||||
'return_path' => $rp,
|
||||
'webpage' => ITEM_TYPE_CARD,
|
||||
'button' => t('Edit'),
|
||||
'writefiles' => perm_is_allowed($owner, get_observer_hash(), 'write_pages'),
|
||||
'weblink' => t('Insert web link'),
|
||||
'hide_voting' => false,
|
||||
'hide_future' => false,
|
||||
'hide_location' => false,
|
||||
'hide_expire' => false,
|
||||
'showacl' => true,
|
||||
'acl' => populate_acl($itm[0],false,\Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')),
|
||||
'permissions' => $itm[0],
|
||||
'lockstate' => (($itm[0]['allow_cid'] || $itm[0]['allow_gid'] || $itm[0]['deny_cid'] || $itm[0]['deny_gid']) ? 'lock' : 'unlock'),
|
||||
'ptyp' => $itm[0]['type'],
|
||||
'mimeselect' => false,
|
||||
'mimetype' => $itm[0]['mimetype'],
|
||||
'body' => undo_post_tagging($content),
|
||||
'post_id' => $post_id,
|
||||
'visitor' => true,
|
||||
'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'),
|
||||
'summary' => htmlspecialchars($itm[0]['summary'],ENT_COMPAT,'UTF-8'),
|
||||
'placeholdertitle' => t('Title (optional)'),
|
||||
'pagetitle' => $card_title,
|
||||
'profile_uid' => (intval($channel['channel_id'])),
|
||||
'catsenabled' => $catsenabled,
|
||||
'category' => $category,
|
||||
'bbcode' => (($mimetype == 'text/bbcode') ? true : false)
|
||||
);
|
||||
|
||||
$editor = status_editor($a, $x, false, 'Card_edit');
|
||||
|
||||
$o .= replace_macros(get_markup_template('edpost_head.tpl'), array(
|
||||
'$title' => t('Edit Card'),
|
||||
'$delete' => ((($itm[0]['author_xchan'] === $ob_hash) || ($itm[0]['owner_xchan'] === $ob_hash)) ? t('Delete') : false),
|
||||
'$id' => $itm[0]['id'],
|
||||
'$cancel' => t('Cancel'),
|
||||
'$editor' => $editor
|
||||
));
|
||||
|
||||
return $o;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Lib\Apps;
|
||||
use Zotlabs\Web\Controller;
|
||||
use Zotlabs\Lib\PermissionDescription;
|
||||
|
||||
require_once('include/channel.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
|
||||
/**
|
||||
* @brief Provides the Cards module.
|
||||
*
|
||||
*/
|
||||
class Cards extends Controller {
|
||||
|
||||
public function init() {
|
||||
|
||||
if(argc() > 1)
|
||||
$which = argv(1);
|
||||
else
|
||||
return;
|
||||
|
||||
profile_load($which);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \\Zotlabs\\Web\\Controller::get()
|
||||
*
|
||||
* @return string Parsed HTML from template 'cards.tpl'
|
||||
*/
|
||||
public function get($update = 0, $load = false) {
|
||||
|
||||
if(observer_prohibited(true)) {
|
||||
return login();
|
||||
}
|
||||
|
||||
if(! App::$profile) {
|
||||
notice( t('Requested profile is not available.') . EOL );
|
||||
App::$error = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
if(! Apps::system_app_installed(App::$profile_uid, 'Cards')) {
|
||||
//Do not display any associated widgets at this point
|
||||
App::$pdl = '';
|
||||
|
||||
$o = '<b>' . t('Cards App') . ' (' . t('Not Installed') . '):</b><br>';
|
||||
$o .= t('Create personal planning cards');
|
||||
return $o;
|
||||
}
|
||||
|
||||
nav_set_selected('Cards');
|
||||
|
||||
head_add_link([
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/json+oembed',
|
||||
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . App::$query_string),
|
||||
'title' => 'oembed'
|
||||
]);
|
||||
|
||||
|
||||
$category = (($_REQUEST['cat']) ? escape_tags(trim($_REQUEST['cat'])) : '');
|
||||
|
||||
if($category) {
|
||||
$sql_extra2 .= protect_sprintf(term_item_parent_query(App::$profile['profile_uid'], 'item', $category, TERM_CATEGORY));
|
||||
}
|
||||
|
||||
|
||||
$which = argv(1);
|
||||
|
||||
$selected_card = ((argc() > 2) ? argv(2) : '');
|
||||
|
||||
$_SESSION['return_url'] = App::$query_string;
|
||||
|
||||
$uid = local_channel();
|
||||
$owner = App::$profile_uid;
|
||||
$observer = App::get_observer();
|
||||
|
||||
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
|
||||
|
||||
if(! perm_is_allowed($owner, $ob_hash, 'view_pages')) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$is_owner = ($uid && $uid == $owner);
|
||||
|
||||
$channel = channelx_by_n($owner);
|
||||
|
||||
if($channel) {
|
||||
$channel_acl = [
|
||||
'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 = [ 'allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '' ];
|
||||
}
|
||||
|
||||
|
||||
if(perm_is_allowed($owner, $ob_hash, 'write_pages')) {
|
||||
|
||||
$x = [
|
||||
'webpage' => ITEM_TYPE_CARD,
|
||||
'is_owner' => true,
|
||||
'content_label' => t('Add Card'),
|
||||
'button' => t('Save'),
|
||||
'nickname' => $channel['channel_address'],
|
||||
'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid']
|
||||
|| $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
|
||||
'acl' => (($is_owner) ? populate_acl($channel_acl, false,
|
||||
PermissionDescription::fromGlobalPermission('view_pages')) : ''),
|
||||
'permissions' => $channel_acl,
|
||||
'showacl' => (($is_owner) ? true : false),
|
||||
'visitor' => true,
|
||||
'hide_location' => false,
|
||||
'hide_voting' => false,
|
||||
'profile_uid' => intval($owner),
|
||||
'mimetype' => 'text/bbcode',
|
||||
'mimeselect' => false,
|
||||
'layoutselect' => false,
|
||||
'expanded' => false,
|
||||
'novoting' => false,
|
||||
'catsenabled' => feature_enabled($owner, 'categories'),
|
||||
'bbco_autocomplete' => 'bbcode',
|
||||
'bbcode' => true
|
||||
];
|
||||
|
||||
if($_REQUEST['title'])
|
||||
$x['title'] = $_REQUEST['title'];
|
||||
if($_REQUEST['body'])
|
||||
$x['body'] = $_REQUEST['body'];
|
||||
|
||||
$editor = status_editor($a, $x, false, 'Cards');
|
||||
}
|
||||
else {
|
||||
$editor = '';
|
||||
}
|
||||
|
||||
|
||||
$itemspage = get_pconfig(local_channel(),'system','itemspage');
|
||||
App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10));
|
||||
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start']));
|
||||
|
||||
|
||||
$sql_extra = item_permissions_sql($owner);
|
||||
$sql_item = '';
|
||||
|
||||
if($selected_card) {
|
||||
$r = q("select * from iconfig where iconfig.cat = 'system' and iconfig.k = 'CARD' and iconfig.v = '%s' limit 1",
|
||||
dbesc($selected_card)
|
||||
);
|
||||
if($r) {
|
||||
$sql_item = "and item.id = " . intval($r[0]['iid']) . " ";
|
||||
}
|
||||
}
|
||||
|
||||
$r = q("select * from item
|
||||
where uid = %d and item_type = %d
|
||||
$sql_extra $sql_item order by item.created desc $pager_sql",
|
||||
intval($owner),
|
||||
intval(ITEM_TYPE_CARD)
|
||||
);
|
||||
|
||||
$item_normal = " and item.item_hidden = 0 and item.item_type in (0,6) and item.item_deleted = 0
|
||||
and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0
|
||||
and item.item_blocked = 0 ";
|
||||
|
||||
$items_result = [];
|
||||
if($r) {
|
||||
|
||||
$pager_total = count($r);
|
||||
|
||||
$parents_str = ids_to_querystr($r, '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 $sql_extra2 ",
|
||||
intval(App::$profile['profile_uid']),
|
||||
dbesc($parents_str)
|
||||
);
|
||||
if($items) {
|
||||
xchan_query($items);
|
||||
$items = fetch_post_tags($items, true);
|
||||
$items_result = conv_sort($items, 'updated');
|
||||
}
|
||||
}
|
||||
|
||||
$mode = 'cards';
|
||||
|
||||
if(get_pconfig(local_channel(),'system','articles_list_mode') && (! $selected_card))
|
||||
$page_mode = 'pager_list';
|
||||
else
|
||||
$page_mode = 'traditional';
|
||||
|
||||
$content = conversation($items_result, $mode, false, $page_mode);
|
||||
|
||||
$o = replace_macros(get_markup_template('cards.tpl'), [
|
||||
'$title' => t('Cards'),
|
||||
'$editor' => $editor,
|
||||
'$content' => $content,
|
||||
'$pager' => alt_pager($pager_total)
|
||||
]);
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -200,7 +200,7 @@ class Cdav extends Controller {
|
||||
$etag = (isset($_SERVER['HTTP_IF_MATCH']) ? $_SERVER['HTTP_IF_MATCH'] : false);
|
||||
|
||||
// delete
|
||||
if($httpmethod === 'DELETE' && $cdavdata['etag'] == $etag) {
|
||||
if($httpmethod === 'DELETE' && $etag && isset($cdavdata['etag']) && $cdavdata['etag'] == $etag) {
|
||||
Libsync::build_sync_packet($channel['channel_id'], [
|
||||
$sync => [
|
||||
'action' => 'delete_card',
|
||||
@@ -210,7 +210,7 @@ class Cdav extends Controller {
|
||||
]);
|
||||
}
|
||||
else {
|
||||
if($etag && $cdavdata['etag'] !== $etag) {
|
||||
if($etag && isset($cdavdata['etag']) && $cdavdata['etag'] !== $etag) {
|
||||
// update
|
||||
Libsync::build_sync_packet($channel['channel_id'], [
|
||||
$sync => [
|
||||
@@ -317,7 +317,7 @@ class Cdav extends Controller {
|
||||
$calendars = $caldavBackend->getCalendarsForUser($principalUri);
|
||||
|
||||
//create new calendar
|
||||
if($_REQUEST['{DAV:}displayname'] && $_REQUEST['create']) {
|
||||
if((isset($_REQUEST['{DAV:}displayname']) && $_REQUEST['{DAV:}displayname']) && (isset($_REQUEST['create']) && $_REQUEST['create'])) {
|
||||
do {
|
||||
$duplicate = false;
|
||||
$calendarUri = random_string(40);
|
||||
@@ -352,7 +352,7 @@ class Cdav extends Controller {
|
||||
}
|
||||
|
||||
//create new calendar object via ajax request
|
||||
if($_REQUEST['submit'] === 'create_event' && $_REQUEST['title'] && $_REQUEST['target'] && $_REQUEST['dtstart']) {
|
||||
if((isset($_REQUEST['submit']) && $_REQUEST['submit'] === 'create_event') && $_REQUEST['title'] && $_REQUEST['target'] && $_REQUEST['dtstart']) {
|
||||
|
||||
$id = explode(':', $_REQUEST['target']);
|
||||
|
||||
@@ -431,7 +431,7 @@ class Cdav extends Controller {
|
||||
}
|
||||
|
||||
//edit calendar name and color
|
||||
if($_REQUEST['{DAV:}displayname'] && $_REQUEST['edit'] && $_REQUEST['id']) {
|
||||
if((isset($_REQUEST['{DAV:}displayname']) && $_REQUEST['{DAV:}displayname']) && $_REQUEST['edit'] && $_REQUEST['id']) {
|
||||
|
||||
$id = explode(':', $_REQUEST['id']);
|
||||
|
||||
@@ -459,7 +459,7 @@ class Cdav extends Controller {
|
||||
}
|
||||
|
||||
//edit calendar object via ajax request
|
||||
if($_REQUEST['submit'] === 'update_event' && $_REQUEST['uri'] && $_REQUEST['title'] && $_REQUEST['target'] && $_REQUEST['dtstart']) {
|
||||
if((isset($_REQUEST['submit']) && $_REQUEST['submit'] === 'update_event') && $_REQUEST['uri'] && $_REQUEST['title'] && $_REQUEST['target'] && $_REQUEST['dtstart']) {
|
||||
|
||||
$id = explode(':', $_REQUEST['target']);
|
||||
|
||||
@@ -873,10 +873,8 @@ class Cdav extends Controller {
|
||||
if((argv(1) === 'addressbook') && (! Apps::system_app_installed(local_channel(), 'CardDAV'))) {
|
||||
//Do not display any associated widgets at this point
|
||||
App::$pdl = '';
|
||||
|
||||
$o = '<b>' . t('CardDAV App') . ' (' . t('Not Installed') . '):</b><br>';
|
||||
$o .= t('CalDAV capable addressbook');
|
||||
return $o;
|
||||
$papp = Apps::get_papp('CardDAV');
|
||||
return Apps::app_render($papp, 'module');
|
||||
}
|
||||
|
||||
App::$profile_uid = local_channel();
|
||||
@@ -916,6 +914,7 @@ class Cdav extends Controller {
|
||||
head_add_js('/library/fullcalendar/packages/timegrid/main.min.js');
|
||||
head_add_js('/library/fullcalendar/packages/list/main.min.js');
|
||||
|
||||
$o = '';
|
||||
$sources = '';
|
||||
$resource_id = '';
|
||||
$resource = null;
|
||||
@@ -923,6 +922,8 @@ class Cdav extends Controller {
|
||||
if(argc() == 3)
|
||||
$resource_id = argv(2);
|
||||
|
||||
$categories = '';
|
||||
|
||||
if($resource_id) {
|
||||
$r = q("SELECT event.*, item.author_xchan, item.owner_xchan, item.plink, item.id as item_id FROM event LEFT JOIN item ON event.event_hash = item.resource_id
|
||||
WHERE event.uid = %d AND event.event_hash = '%s' LIMIT 1",
|
||||
@@ -946,7 +947,6 @@ class Cdav extends Controller {
|
||||
$resource = $r[0];
|
||||
|
||||
$catsenabled = feature_enabled(local_channel(),'categories');
|
||||
$categories = '';
|
||||
if($catsenabled){
|
||||
if($r[0]['term']) {
|
||||
$cats = get_terms_oftype($r[0]['term'], TERM_CATEGORY);
|
||||
@@ -1059,6 +1059,7 @@ class Cdav extends Controller {
|
||||
'$cancel' => t('Cancel'),
|
||||
'$create' => t('Create'),
|
||||
'$recurrence_warning' => t('Sorry! Editing of recurrent events is not yet implemented.'),
|
||||
'$disabled_warning' => t('Could not fetch calendar resource. The selected calendar might be disabled.'),
|
||||
|
||||
'$channel_hash' => $channel['channel_hash'],
|
||||
'$acl' => $acl,
|
||||
|
||||
@@ -31,8 +31,10 @@ class Channel extends Controller {
|
||||
goaway(z_root() . '/search?f=&search=' . $_GET['search']);
|
||||
|
||||
$which = null;
|
||||
if (argc() > 1)
|
||||
if (argc() > 1) {
|
||||
$which = argv(1);
|
||||
}
|
||||
|
||||
if (!$which) {
|
||||
if (local_channel()) {
|
||||
$channel = App::get_channel();
|
||||
@@ -40,20 +42,21 @@ class Channel extends Controller {
|
||||
$which = $channel['channel_address'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!$which) {
|
||||
notice(t('You must be logged in to see this page.') . EOL);
|
||||
return;
|
||||
http_status_exit(404, 'Not found');
|
||||
}
|
||||
|
||||
$profile = 0;
|
||||
$channel = App::get_channel();
|
||||
|
||||
if ((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
|
||||
$channel = App::get_channel();
|
||||
$which = $channel['channel_address'];
|
||||
$profile = argv(1);
|
||||
}
|
||||
|
||||
$channel = channelx_by_nick($which);
|
||||
$channel = channelx_by_nick($which, true);
|
||||
|
||||
if (!$channel) {
|
||||
http_status_exit(404, 'Not found');
|
||||
}
|
||||
@@ -65,8 +68,8 @@ class Channel extends Controller {
|
||||
$sigdata = HTTPSig::verify(file_get_contents('php://input'), EMPTY_STR, 'zot6');
|
||||
|
||||
if ($sigdata && $sigdata['signer'] && $sigdata['header_valid']) {
|
||||
$data = json_encode(Libzot::zotinfo(['address' => $channel['channel_address'], 'target_url' => $sigdata['signer']]));
|
||||
$s = q("select site_crypto, hubloc_sitekey from site left join hubloc on hubloc_url = site_url where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
|
||||
$data = json_encode(Libzot::zotinfo(['guid_hash' => $channel['channel_hash'], 'target_url' => $sigdata['signer']]));
|
||||
$s = q("select site_crypto, hubloc_sitekey from site left join hubloc on hubloc_url = site_url where hubloc_id_url = '%s' and hubloc_network = 'zot6' order by hubloc_id desc limit 1",
|
||||
dbesc($sigdata['signer'])
|
||||
);
|
||||
|
||||
@@ -83,24 +86,31 @@ class Channel extends Controller {
|
||||
'Digest' => HTTPSig::generate_digest_header($data),
|
||||
'(request-target)' => strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI']
|
||||
];
|
||||
$h = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel));
|
||||
|
||||
$h = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel));
|
||||
HTTPSig::set_headers($h);
|
||||
echo $data;
|
||||
killme();
|
||||
}
|
||||
|
||||
if ($channel['channel_removed']) {
|
||||
http_status_exit(410, 'Gone');
|
||||
}
|
||||
|
||||
if (get_pconfig($channel['channel_id'], 'system', 'index_opt_out')) {
|
||||
App::$meta->set('robots', 'noindex, noarchive');
|
||||
}
|
||||
|
||||
if (ActivityStreams::is_as_request($channel)) {
|
||||
|
||||
// Somebody may attempt an ActivityStreams fetch on one of our message permalinks
|
||||
// Make it do the right thing.
|
||||
|
||||
$mid = ((x($_REQUEST, 'mid')) ? $_REQUEST['mid'] : '');
|
||||
if ($mid && strpos($mid, 'b64.') === 0) {
|
||||
$decoded = @base64url_decode(substr($mid, 4));
|
||||
if ($decoded) {
|
||||
$mid = $decoded;
|
||||
}
|
||||
$mid = ((x($_REQUEST, 'mid')) ? unpack_link_id($_REQUEST['mid']) : '');
|
||||
if ($mid === false) {
|
||||
http_status_exit(404, 'Not found');
|
||||
}
|
||||
|
||||
if ($mid) {
|
||||
$obj = null;
|
||||
if (strpos($mid, z_root() . '/item/') === 0) {
|
||||
@@ -145,15 +155,19 @@ class Channel extends Controller {
|
||||
profile_load($which, $profile);
|
||||
|
||||
// Add Opengraph markup
|
||||
$mid = ((x($_REQUEST, 'mid')) ? $_REQUEST['mid'] : '');
|
||||
if (strpos($mid, 'b64.') === 0)
|
||||
$mid = @base64url_decode(substr($mid, 4));
|
||||
$mid = ((x($_REQUEST, 'mid')) ? unpack_link_id($_REQUEST['mid']) : '');
|
||||
|
||||
if ($mid)
|
||||
if ($mid === false) {
|
||||
notice(t('Malformed message id.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($mid) {
|
||||
$r = q("SELECT * FROM item WHERE mid = '%s' AND uid = %d AND item_private = 0 LIMIT 1",
|
||||
dbesc($mid),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
}
|
||||
|
||||
opengraph_add_meta((isset($r) && count($r) ? $r[0] : []), $channel);
|
||||
}
|
||||
@@ -164,12 +178,11 @@ class Channel extends Controller {
|
||||
|
||||
$category = $datequery = $datequery2 = '';
|
||||
|
||||
$mid = ((x($_REQUEST, 'mid')) ? $_REQUEST['mid'] : '');
|
||||
|
||||
if (strpos($mid, 'b64.') === 0)
|
||||
$decoded = @base64url_decode(substr($mid, 4));
|
||||
if (isset($decoded))
|
||||
$mid = $decoded;
|
||||
$mid = ((x($_REQUEST, 'mid')) ? unpack_link_id($_REQUEST['mid']) : '');
|
||||
if ($mid === false) {
|
||||
notice(t('Malformed message id.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$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']) : '');
|
||||
@@ -213,7 +226,7 @@ class Channel extends Controller {
|
||||
|
||||
if (!$update) {
|
||||
|
||||
nav_set_selected('Channel Home');
|
||||
nav_set_selected('Channel');
|
||||
|
||||
// search terms header
|
||||
if ($search) {
|
||||
@@ -256,6 +269,7 @@ class Channel extends Controller {
|
||||
'reset' => t('Reset form')
|
||||
];
|
||||
|
||||
$a = '';
|
||||
$o .= status_editor($a, $x, false, 'Channel');
|
||||
}
|
||||
|
||||
@@ -282,7 +296,7 @@ class Channel extends Controller {
|
||||
$abook_uids = " and abook.abook_channel = " . intval(App::$profile['profile_uid']) . " ";
|
||||
|
||||
$simple_update = '';
|
||||
if ($update && $_SESSION['loadtime'])
|
||||
if ($update && isset($_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 ($search) {
|
||||
@@ -420,8 +434,8 @@ class Channel extends Controller {
|
||||
|
||||
if ((!$update) && (!$load)) {
|
||||
|
||||
if (isset($decoded))
|
||||
$mid = 'b64.' . base64url_encode($mid);
|
||||
//if we got a decoded hash we must encode it again before handing to javascript
|
||||
$mid = gen_link_id($mid);
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -30,7 +30,7 @@ class Channel_calendar extends Controller {
|
||||
|
||||
$xchan = ((x($_POST, 'xchan')) ? dbesc($_POST['xchan']) : '');
|
||||
|
||||
// only allow editing your own events.
|
||||
// only allow editing your own events.
|
||||
if (($xchan) && ($xchan !== get_observer_hash()))
|
||||
return;
|
||||
|
||||
@@ -55,8 +55,8 @@ class Channel_calendar extends Controller {
|
||||
|
||||
// Don't allow the event to finish before it begins.
|
||||
// It won't hurt anything, but somebody will file a bug report
|
||||
// and we'll waste a bunch of time responding to it. Time that
|
||||
// could've been spent doing something else.
|
||||
// and we'll waste a bunch of time responding to it. Time that
|
||||
// could've been spent doing something else.
|
||||
|
||||
if (strcmp($finish, $start) < 0) {
|
||||
notice(t('Event can not end before it has started.') . EOL);
|
||||
@@ -319,12 +319,12 @@ class Channel_calendar extends Controller {
|
||||
// fixed an issue with "nofinish" events not showing up in the calendar.
|
||||
// There's still an issue if the finish date crosses the end of month.
|
||||
// Noting this for now - it will need to be fixed here and in Friendica.
|
||||
// Ultimately the finish date shouldn't be involved in the query.
|
||||
// Ultimately the finish date shouldn't be involved in the query.
|
||||
|
||||
$r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan, item.id as item_id
|
||||
from event left join item on event.event_hash = item.resource_id
|
||||
where item.resource_type = 'event' and event.uid = %d and event.uid = item.uid $ignored
|
||||
AND (( event.adjust = 0 AND ( event.dtend >= '%s' or event.nofinish = 1 ) AND event.dtstart <= '%s' )
|
||||
from event left join item on event.event_hash = item.resource_id
|
||||
where item.resource_type = 'event' and event.uid = %d and event.uid = item.uid $ignored
|
||||
AND (( event.adjust = 0 AND ( event.dtend >= '%s' or event.nofinish = 1 ) AND event.dtstart <= '%s' )
|
||||
OR ( event.adjust = 1 AND ( event.dtend >= '%s' or event.nofinish = 1 ) AND event.dtstart <= '%s' )) ",
|
||||
intval(local_channel()),
|
||||
dbesc($start),
|
||||
@@ -357,7 +357,7 @@ class Channel_calendar extends Controller {
|
||||
$catsenabled = feature_enabled(local_channel(), 'categories');
|
||||
$categories = '';
|
||||
if ($catsenabled) {
|
||||
if ($rr['term']) {
|
||||
if (isset($rr['term']) && $rr['term']) {
|
||||
$cats = get_terms_oftype($rr['term'], TERM_CATEGORY);
|
||||
foreach ($cats as $cat) {
|
||||
if (strlen($categories))
|
||||
@@ -449,7 +449,7 @@ class Channel_calendar extends Controller {
|
||||
}
|
||||
|
||||
// The site admin can delete any post/item on the site.
|
||||
// If the item originated on this site+channel the deletion will propagate downstream.
|
||||
// If the item originated on this site+channel the deletion will propagate downstream.
|
||||
// Otherwise just the local copy is removed.
|
||||
|
||||
if (is_site_admin()) {
|
||||
|
||||
@@ -10,53 +10,53 @@ use Zotlabs\Lib\Zotfinger;
|
||||
class Chanview extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
|
||||
$observer = App::get_observer();
|
||||
$xchan = null;
|
||||
|
||||
|
||||
$r = null;
|
||||
|
||||
if($_REQUEST['hash']) {
|
||||
$r = q("select * from xchan where xchan_hash = '%s'",
|
||||
|
||||
if(isset($_REQUEST['hash']) && $_REQUEST['hash']) {
|
||||
$r = q("select * from xchan where xchan_hash = '%s' and xchan_deleted = 0",
|
||||
dbesc($_REQUEST['hash'])
|
||||
);
|
||||
}
|
||||
if($_REQUEST['address']) {
|
||||
$r = q("select * from xchan where xchan_addr = '%s'",
|
||||
if(isset($_REQUEST['address']) && $_REQUEST['address']) {
|
||||
$r = q("select * from xchan where xchan_addr = '%s' and xchan_deleted = 0",
|
||||
dbesc(punify($_REQUEST['address']))
|
||||
);
|
||||
}
|
||||
elseif(local_channel() && intval($_REQUEST['cid'])) {
|
||||
$r = q("SELECT abook.*, xchan.*
|
||||
elseif(local_channel() && isset($_REQUEST['cid']) && $_REQUEST['cid']) {
|
||||
$r = q("SELECT abook.*, xchan.*
|
||||
FROM abook left join xchan on abook_xchan = xchan_hash
|
||||
WHERE abook_channel = %d and abook_id = %d",
|
||||
WHERE abook_channel = %d and abook_id = %d and xchan_deleted = 0",
|
||||
intval(local_channel()),
|
||||
intval($_REQUEST['cid'])
|
||||
);
|
||||
}
|
||||
elseif($_REQUEST['url']) {
|
||||
|
||||
}
|
||||
elseif(isset($_REQUEST['url']) && $_REQUEST['url']) {
|
||||
|
||||
// if somebody re-installed they will have more than one xchan, use the most recent name date as this is
|
||||
// the most useful consistently ascending table item we have.
|
||||
|
||||
$r = q("select * from xchan where xchan_url = '%s' order by xchan_name_date desc",
|
||||
// the most useful consistently ascending table item we have.
|
||||
|
||||
$r = q("select * from xchan where xchan_url = '%s' and xchan_deleted = 0 order by xchan_name_date desc",
|
||||
dbesc($_REQUEST['url'])
|
||||
);
|
||||
}
|
||||
if($r) {
|
||||
App::$poi = Libzot::zot_record_preferred($r, 'xchan_network');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Here, let's see if we have an xchan. If we don't, how we proceed is determined by what
|
||||
// info we do have. If it's a URL, we can offer to visit it directly. If it's a webbie or
|
||||
// address, we can and should try to import it. If it's just a hash, we can't continue, but we
|
||||
// info we do have. If it's a URL, we can offer to visit it directly. If it's a webbie or
|
||||
// address, we can and should try to import it. If it's just a hash, we can't continue, but we
|
||||
// probably wouldn't have a hash if we don't already have an xchan for this channel.
|
||||
|
||||
|
||||
if(! App::$poi) {
|
||||
logger('mod_chanview: fallback');
|
||||
|
||||
if($_REQUEST['address']) {
|
||||
if(isset($_REQUEST['address']) && $_REQUEST['address']) {
|
||||
$href = Webfinger::zot_url(punify($_REQUEST['address']));
|
||||
if($href) {
|
||||
$_REQUEST['url'] = $href;
|
||||
@@ -65,13 +65,13 @@ class Chanview extends \Zotlabs\Web\Controller {
|
||||
|
||||
$r = null;
|
||||
|
||||
if($_REQUEST['url']) {
|
||||
if(isset($_REQUEST['url']) && $_REQUEST['url']) {
|
||||
|
||||
$zf = Zotfinger::exec($_REQUEST['url'], null);
|
||||
|
||||
if(array_path_exists('signature/signer',$zf) && $zf['signature']['signer'] === $_REQUEST['url'] && intval($zf['signature']['header_valid'])) {
|
||||
Libzot::import_xchan($zf['data']);
|
||||
$r = q("select * from xchan where xchan_url = '%s'",
|
||||
$r = q("select * from xchan where xchan_url = '%s' and xchan_deleted = 0",
|
||||
dbesc($_REQUEST['url'])
|
||||
);
|
||||
if($r) {
|
||||
@@ -80,7 +80,7 @@ class Chanview extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
if(! $r) {
|
||||
if(discover_by_webbie($_REQUEST['url'])) {
|
||||
$r = q("select * from xchan where xchan_url = '%s'",
|
||||
$r = q("select * from xchan where xchan_url = '%s' and xchan_deleted = 0",
|
||||
dbesc($_REQUEST['url'])
|
||||
);
|
||||
if($r) {
|
||||
@@ -90,7 +90,7 @@ class Chanview extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(! App::$poi) {
|
||||
notice( t('Channel not found.') . EOL);
|
||||
return;
|
||||
@@ -98,9 +98,9 @@ class Chanview extends \Zotlabs\Web\Controller {
|
||||
|
||||
$is_zot = false;
|
||||
$connected = false;
|
||||
|
||||
|
||||
$url = App::$poi['xchan_url'];
|
||||
if(in_array(App::$poi['xchan_network'], ['zot', 'zot6'])) {
|
||||
if(App::$poi['xchan_network'] === 'zot6') {
|
||||
$is_zot = true;
|
||||
}
|
||||
if(local_channel()) {
|
||||
@@ -111,29 +111,29 @@ class Chanview extends \Zotlabs\Web\Controller {
|
||||
if($c)
|
||||
$connected = true;
|
||||
}
|
||||
|
||||
// We will load the chanview template if it's a foreign network,
|
||||
|
||||
// We will load the chanview template if it's a foreign network,
|
||||
// just so that we can provide a connect button along with a profile
|
||||
// photo. Chances are we can't load the remote profile into an iframe
|
||||
// because of cross-domain security headers. So provide a link to
|
||||
// the remote profile.
|
||||
// the remote profile.
|
||||
// If we are already connected, just go to the profile.
|
||||
// Zot channels will usually have a connect link.
|
||||
|
||||
|
||||
if($is_zot || $connected) {
|
||||
if($is_zot && $observer) {
|
||||
$url = zid($url);
|
||||
}
|
||||
goaway($url);
|
||||
}
|
||||
else {
|
||||
else {
|
||||
$o = replace_macros(get_markup_template('chanview.tpl'),array(
|
||||
'$url' => $url,
|
||||
'$full' => t('toggle full screen mode')
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ require_once('include/bookmarks.php');
|
||||
class Chat extends Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
|
||||
$which = null;
|
||||
if(argc() > 1)
|
||||
$which = argv(1);
|
||||
@@ -29,79 +29,77 @@ class Chat extends Controller {
|
||||
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);
|
||||
$profile = argv(1);
|
||||
}
|
||||
|
||||
|
||||
// Run profile_load() here to make sure the theme is set before
|
||||
// we start loading content
|
||||
|
||||
|
||||
profile_load($which,$profile);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function post() {
|
||||
|
||||
|
||||
if($_POST['room_name'])
|
||||
$room = strip_tags(trim($_POST['room_name']));
|
||||
|
||||
$room = strip_tags(trim($_POST['room_name']));
|
||||
|
||||
if((! $room) || (! local_channel()))
|
||||
return;
|
||||
|
||||
|
||||
$channel = App::get_channel();
|
||||
|
||||
|
||||
|
||||
|
||||
if($_POST['action'] === 'drop') {
|
||||
logger('delete chatroom');
|
||||
Chatroom::destroy($channel,array('cr_name' => $room));
|
||||
goaway(z_root() . '/chat/' . $channel['channel_address']);
|
||||
}
|
||||
|
||||
|
||||
$acl = new AccessList($channel);
|
||||
$acl->set_from_array($_REQUEST);
|
||||
|
||||
|
||||
$arr = $acl->get();
|
||||
$arr['name'] = $room;
|
||||
$arr['expire'] = intval($_POST['chat_expire']);
|
||||
if(intval($arr['expire']) < 0)
|
||||
$arr['expire'] = 0;
|
||||
|
||||
|
||||
Chatroom::create($channel,$arr);
|
||||
|
||||
|
||||
$x = q("select * from chatroom where cr_name = '%s' and cr_uid = %d limit 1",
|
||||
dbesc($room),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
|
||||
Libsync::build_sync_packet(0, array('chatroom' => $x));
|
||||
|
||||
|
||||
if($x)
|
||||
goaway(z_root() . '/chat/' . $channel['channel_address'] . '/' . $x[0]['cr_id']);
|
||||
|
||||
|
||||
// that failed. Try again perhaps?
|
||||
|
||||
|
||||
goaway(z_root() . '/chat/' . $channel['channel_address'] . '/new');
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
if(! Apps::system_app_installed(App::$profile_uid, 'Chatrooms')) {
|
||||
//Do not display any associated widgets at this point
|
||||
App::$pdl = '';
|
||||
|
||||
$o = '<b>' . t('Chatrooms App') . ' (' . t('Not Installed') . '):</b><br>';
|
||||
$o .= t('Access Controlled Chatrooms');
|
||||
return $o;
|
||||
$papp = Apps::get_papp('Chatrooms');
|
||||
return Apps::app_render($papp, 'module');
|
||||
}
|
||||
|
||||
|
||||
if(local_channel()) {
|
||||
$channel = App::get_channel();
|
||||
nav_set_selected('Chatrooms');
|
||||
@@ -113,24 +111,24 @@ class Chat extends Controller {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(! perm_is_allowed(App::$profile['profile_uid'],$observer,'chat')) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if((argc() > 3) && intval(argv(2)) && (argv(3) === 'leave')) {
|
||||
Chatroom::leave($observer,argv(2),$_SERVER['REMOTE_ADDR']);
|
||||
goaway(z_root() . '/channel/' . argv(1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if((argc() > 3) && intval(argv(2)) && (argv(3) === 'status')) {
|
||||
$ret = array('success' => false);
|
||||
$room_id = intval(argv(2));
|
||||
if(! $room_id || ! $observer)
|
||||
return;
|
||||
|
||||
|
||||
$r = q("select * from chatroom where cr_id = %d limit 1",
|
||||
intval($room_id)
|
||||
);
|
||||
@@ -139,7 +137,7 @@ class Chat extends Controller {
|
||||
}
|
||||
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'])
|
||||
@@ -155,9 +153,9 @@ class Chat extends Controller {
|
||||
$ret['chatroom'] = $r[0]['cr_name'];
|
||||
$ret['inroom'] = $y[0]['total'];
|
||||
}
|
||||
|
||||
|
||||
// figure out how to present a timestamp of the last activity, since we don't know the observer's timezone.
|
||||
|
||||
|
||||
$z = q("select created from chat where chat_room = %d order by created desc limit 1",
|
||||
intval($room_id)
|
||||
);
|
||||
@@ -166,40 +164,41 @@ class Chat extends Controller {
|
||||
}
|
||||
json_return_and_die($ret);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if(argc() > 2 && intval(argv(2))) {
|
||||
|
||||
|
||||
$room_id = intval(argv(2));
|
||||
$bookmark_link = get_bookmark_link($ob);
|
||||
|
||||
|
||||
$x = 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",
|
||||
|
||||
$x = q("select * from chatroom where cr_id = %d and cr_uid = %d limit 1",
|
||||
intval($room_id),
|
||||
intval(App::$profile['profile_uid'])
|
||||
);
|
||||
|
||||
|
||||
if($x) {
|
||||
$acl = new AccessList(false);
|
||||
$acl->set($x[0]);
|
||||
|
||||
|
||||
$private = $acl->is_private();
|
||||
$room_name = $x[0]['cr_name'];
|
||||
if($bookmark_link)
|
||||
$bookmark_link .= '&url=' . z_root() . '/chat/' . argv(1) . '/' . argv(2) . '&title=' . urlencode($x[0]['cr_name']) . (($private) ? '&private=1' : '') . '&ischat=1';
|
||||
$bookmark_link .= '&url=' . z_root() . '/chat/' . argv(1) . '/' . argv(2) . '&title=' . urlencode($x[0]['cr_name']) . (($private) ? '&private=1' : '') . '&ischat=1';
|
||||
}
|
||||
else {
|
||||
notice( t('Room not found') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$cipher = get_pconfig(local_channel(),'system','default_cipher');
|
||||
if(! $cipher)
|
||||
$cipher = 'AES-128-CCM';
|
||||
|
||||
|
||||
|
||||
|
||||
$o = replace_macros(get_markup_template('chat.tpl'),array(
|
||||
'$is_owner' => ((local_channel() && local_channel() == $x[0]['cr_uid']) ? true : false),
|
||||
'$room_name' => $room_name,
|
||||
@@ -223,7 +222,7 @@ class Chat extends Controller {
|
||||
}
|
||||
|
||||
require_once('include/conversation.php');
|
||||
|
||||
|
||||
$o = '';
|
||||
|
||||
$acl = new AccessList($channel);
|
||||
@@ -246,12 +245,12 @@ class Chat extends Controller {
|
||||
'$deny_gid' => acl2json($channel_acl['deny_gid']),
|
||||
'$lockstate' => $lockstate,
|
||||
'$submit' => t('Submit')
|
||||
|
||||
|
||||
));
|
||||
}
|
||||
|
||||
$rooms = Chatroom::roomlist(App::$profile['profile_uid']);
|
||||
|
||||
|
||||
$o .= replace_macros(get_markup_template('chatrooms.tpl'), array(
|
||||
'$header' => sprintf( t('%1$s\'s Chatrooms'), App::$profile['fullname']),
|
||||
'$name' => t('Name'),
|
||||
@@ -259,15 +258,15 @@ class Chat extends Controller {
|
||||
'$nickname' => App::$profile['channel_address'],
|
||||
'$rooms' => $rooms,
|
||||
'$norooms' => t('No chatrooms available'),
|
||||
'$newroom' => t('Create New'),
|
||||
'$newroom' => t('Add Room'),
|
||||
'$is_owner' => ((local_channel() && local_channel() == App::$profile['profile_uid']) ? 1 : 0),
|
||||
'$chatroom_new' => $chatroom_new,
|
||||
'$expire' => t('Expiration'),
|
||||
'$expire_unit' => t('min') //minutes
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/security.php');
|
||||
|
||||
@@ -9,76 +9,76 @@ use \Zotlabs\Lib as Zlib;
|
||||
class Chatsvc extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
|
||||
//logger('chatsvc');
|
||||
|
||||
|
||||
$ret = array('success' => false);
|
||||
|
||||
|
||||
\App::$data['chat']['room_id'] = intval($_REQUEST['room_id']);
|
||||
$x = q("select cr_uid from chatroom where cr_id = %d and cr_id != 0 limit 1",
|
||||
intval(\App::$data['chat']['room_id'])
|
||||
);
|
||||
if(! $x)
|
||||
json_return_and_die($ret);
|
||||
|
||||
|
||||
\App::$data['chat']['uid'] = $x[0]['cr_uid'];
|
||||
|
||||
|
||||
if(! perm_is_allowed(\App::$data['chat']['uid'],get_observer_hash(),'chat')) {
|
||||
json_return_and_die($ret);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function post() {
|
||||
|
||||
|
||||
$ret = array('success' => false);
|
||||
|
||||
|
||||
$room_id = \App::$data['chat']['room_id'];
|
||||
$text = escape_tags($_REQUEST['chat_text']);
|
||||
if(! $text)
|
||||
return;
|
||||
|
||||
|
||||
$sql_extra = permissions_sql(\App::$data['chat']['uid']);
|
||||
|
||||
|
||||
$r = q("select * from chatroom where cr_uid = %d and cr_id = %d $sql_extra",
|
||||
intval(\App::$data['chat']['uid']),
|
||||
intval(\App::$data['chat']['room_id'])
|
||||
);
|
||||
if(! $r)
|
||||
json_return_and_die($ret);
|
||||
|
||||
|
||||
$arr = array(
|
||||
'chat_room' => \App::$data['chat']['room_id'],
|
||||
'chat_xchan' => get_observer_hash(),
|
||||
'chat_text' => $text
|
||||
);
|
||||
|
||||
|
||||
call_hooks('chat_post',$arr);
|
||||
|
||||
|
||||
$x = q("insert into chat ( chat_room, chat_xchan, created, chat_text )
|
||||
values( %d, '%s', '%s', '%s' )",
|
||||
intval(\App::$data['chat']['room_id']),
|
||||
dbesc(get_observer_hash()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(str_rot47(base64url_encode($arr['chat_text'])))
|
||||
dbesc(str_rot47(base64url_encode($arr['chat_text'])))
|
||||
);
|
||||
|
||||
|
||||
$ret['success'] = true;
|
||||
json_return_and_die($ret);
|
||||
}
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
$status = strip_tags($_REQUEST['status']);
|
||||
|
||||
$status = ((isset($_REQUEST['status'])) ? strip_tags($_REQUEST['status']) : '');
|
||||
$room_id = intval(\App::$data['chat']['room_id']);
|
||||
$stopped = ((x($_REQUEST,'stopped') && intval($_REQUEST['stopped'])) ? true : false);
|
||||
|
||||
|
||||
if($status && $room_id) {
|
||||
|
||||
|
||||
$x = q("select channel_address from channel where channel_id = %d limit 1",
|
||||
intval(\App::$data['chat']['uid'])
|
||||
);
|
||||
|
||||
);
|
||||
|
||||
$r = q("update chatpresence set cp_status = '%s', cp_last = '%s' where cp_room = %d and cp_xchan = '%s' and cp_client = '%s'",
|
||||
dbesc($status),
|
||||
dbesc(datetime_convert()),
|
||||
@@ -86,27 +86,27 @@ class Chatsvc extends \Zotlabs\Web\Controller {
|
||||
dbesc(get_observer_hash()),
|
||||
dbesc($_SERVER['REMOTE_ADDR'])
|
||||
);
|
||||
|
||||
goaway(z_root() . '/chat/' . $x[0]['channel_address'] . '/' . $room_id);
|
||||
|
||||
goaway(z_root() . '/chat/' . $x[0]['channel_address'] . '/' . $room_id);
|
||||
}
|
||||
|
||||
|
||||
if(! $stopped) {
|
||||
|
||||
|
||||
$lastseen = intval($_REQUEST['last']);
|
||||
|
||||
|
||||
$ret = array('success' => false);
|
||||
|
||||
|
||||
$sql_extra = permissions_sql(\App::$data['chat']['uid']);
|
||||
|
||||
|
||||
$r = q("select * from chatroom where cr_uid = %d and cr_id = %d $sql_extra",
|
||||
intval(\App::$data['chat']['uid']),
|
||||
intval(\App::$data['chat']['room_id'])
|
||||
);
|
||||
if(! $r)
|
||||
json_return_and_die($ret);
|
||||
|
||||
|
||||
$inroom = array();
|
||||
|
||||
|
||||
$r = q("select * from chatpresence left join xchan on xchan_hash = cp_xchan where cp_room = %d order by xchan_name",
|
||||
intval(\App::$data['chat']['room_id'])
|
||||
);
|
||||
@@ -120,9 +120,9 @@ class Chatsvc extends \Zotlabs\Web\Controller {
|
||||
$rv['xchan_url'] = z_root();
|
||||
$rv['xchan_hidden'] = 1;
|
||||
$rv['xchan_photo_mimetype'] = 'image/png';
|
||||
$rv['xchan_photo_l'] = z_root() . '/' . get_default_profile_photo(300);
|
||||
$rv['xchan_photo_m'] = z_root() . '/' . get_default_profile_photo(80);
|
||||
$rv['xchan_photo_s'] = z_root() . '/' . get_default_profile_photo(48);
|
||||
$rv['xchan_photo_l'] = z_root() . '/' . get_default_profile_photo(300);
|
||||
$rv['xchan_photo_m'] = z_root() . '/' . get_default_profile_photo(80);
|
||||
$rv['xchan_photo_s'] = z_root() . '/' . get_default_profile_photo(48);
|
||||
|
||||
}
|
||||
|
||||
@@ -137,13 +137,13 @@ class Chatsvc extends \Zotlabs\Web\Controller {
|
||||
$status_class = 'online';
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
$inroom[] = array('img' => zid($rv['xchan_photo_m']), 'img_type' => $rv['xchan_photo_mimetype'],'name' => $rv['xchan_name'], 'status' => $status, 'status_class' => $status_class);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$chats = array();
|
||||
|
||||
|
||||
$r = q("select * from chat left join xchan on chat_xchan = xchan_hash where chat_room = %d and chat_id > %d order by created",
|
||||
intval(\App::$data['chat']['room_id']),
|
||||
intval($lastseen)
|
||||
@@ -152,7 +152,7 @@ class Chatsvc extends \Zotlabs\Web\Controller {
|
||||
foreach($r as $rr) {
|
||||
$chats[] = array(
|
||||
'id' => $rr['chat_id'],
|
||||
'img' => zid($rr['xchan_photo_m']),
|
||||
'img' => zid($rr['xchan_photo_m']),
|
||||
'img_type' => $rr['xchan_photo_mimetype'],
|
||||
'name' => $rr['xchan_name'],
|
||||
'isotime' => datetime_convert('UTC', date_default_timezone_get(), $rr['created'], 'c'),
|
||||
@@ -163,22 +163,22 @@ class Chatsvc extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$r = q("update chatpresence set cp_last = '%s' where cp_room = %d and cp_xchan = '%s' and cp_client = '%s'",
|
||||
dbesc(datetime_convert()),
|
||||
intval(\App::$data['chat']['room_id']),
|
||||
dbesc(get_observer_hash()),
|
||||
dbesc($_SERVER['REMOTE_ADDR'])
|
||||
);
|
||||
|
||||
|
||||
$ret['success'] = true;
|
||||
if(! $stopped) {
|
||||
$ret['inroom'] = $inroom;
|
||||
$ret['chats'] = $chats;
|
||||
}
|
||||
json_return_and_die($ret);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ class Cloud extends Controller {
|
||||
$_SESSION['cloud_sort'] = 'name';
|
||||
}
|
||||
|
||||
$_SESSION['cloud_sort'] = (($_REQUEST['sort']) ? trim(notags($_REQUEST['sort'])) : $_SESSION['cloud_sort']);
|
||||
$_SESSION['cloud_sort'] = ((isset($_REQUEST['sort']) && $_REQUEST['sort']) ? trim(notags($_REQUEST['sort'])) : $_SESSION['cloud_sort']);
|
||||
|
||||
$x = clean_query_string();
|
||||
if($x !== \App::$query_string)
|
||||
|
||||
@@ -6,7 +6,7 @@ class Cloud_tiles extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
if(intval($_SESSION['cloud_tiles']))
|
||||
if(isset($_SESSION['cloud_tiles']) && intval($_SESSION['cloud_tiles']))
|
||||
$_SESSION['cloud_tiles'] = 0;
|
||||
else
|
||||
$_SESSION['cloud_tiles'] = 1;
|
||||
@@ -18,4 +18,4 @@ class Cloud_tiles extends \Zotlabs\Web\Controller {
|
||||
goaway(z_root() . '/' . hex2bin(argv(1)));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,32 +2,32 @@
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Lib\Permcat;
|
||||
|
||||
require_once('include/socgraph.php');
|
||||
require_once('include/selectors.php');
|
||||
require_once('include/group.php');
|
||||
|
||||
class Connections extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
|
||||
if(! local_channel())
|
||||
return;
|
||||
|
||||
App::$profile_uid = local_channel();
|
||||
|
||||
|
||||
$channel = App::get_channel();
|
||||
if($channel)
|
||||
head_set_icon($channel['xchan_photo_s']);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
|
||||
$sort_type = 0;
|
||||
$o = '';
|
||||
|
||||
|
||||
|
||||
|
||||
if(! local_channel()) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return login();
|
||||
@@ -44,13 +44,13 @@ class Connections extends \Zotlabs\Web\Controller {
|
||||
$pending = false;
|
||||
$unconnected = false;
|
||||
$all = false;
|
||||
|
||||
if(! $_REQUEST['aj'])
|
||||
|
||||
if(!(isset($_REQUEST['aj']) && $_REQUEST['aj']))
|
||||
$_SESSION['return_url'] = App::$query_string;
|
||||
|
||||
|
||||
$search_flags = "";
|
||||
$head = '';
|
||||
|
||||
|
||||
if(argc() == 2) {
|
||||
switch(argv(1)) {
|
||||
case 'active':
|
||||
@@ -106,7 +106,7 @@ class Connections extends \Zotlabs\Web\Controller {
|
||||
// $head = t('Unconnected');
|
||||
// $unconnected = true;
|
||||
// break;
|
||||
|
||||
|
||||
case 'all':
|
||||
$head = t('All');
|
||||
break;
|
||||
@@ -115,20 +115,22 @@ class Connections extends \Zotlabs\Web\Controller {
|
||||
$active = true;
|
||||
$head = t('Active');
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
$sql_extra = $search_flags;
|
||||
if(argv(1) === 'pending')
|
||||
$sql_extra .= " and abook_ignored = 0 ";
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
$sql_extra = " and abook_blocked = 0 ";
|
||||
$unblocked = true;
|
||||
}
|
||||
|
||||
switch($_REQUEST['order']) {
|
||||
|
||||
$order = $_REQUEST['order'] ?? '';
|
||||
|
||||
switch($order) {
|
||||
case 'name_desc':
|
||||
$sql_order = 'xchan_name DESC';
|
||||
break;
|
||||
@@ -143,32 +145,32 @@ class Connections extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
$search = ((x($_REQUEST,'search')) ? notags(trim($_REQUEST['search'])) : '');
|
||||
|
||||
|
||||
$tabs = array(
|
||||
/*
|
||||
array(
|
||||
'label' => t('Suggestions'),
|
||||
'url' => z_root() . '/suggest',
|
||||
'url' => z_root() . '/suggest',
|
||||
'sel' => '',
|
||||
'title' => t('Suggest new connections'),
|
||||
),
|
||||
*/
|
||||
|
||||
|
||||
'active' => array(
|
||||
'label' => t('Active Connections'),
|
||||
'url' => z_root() . '/connections/active',
|
||||
'url' => z_root() . '/connections/active',
|
||||
'sel' => ($active) ? 'active' : '',
|
||||
'title' => t('Show active connections'),
|
||||
),
|
||||
|
||||
'pending' => array(
|
||||
'label' => t('New Connections'),
|
||||
'url' => z_root() . '/connections/pending',
|
||||
'url' => z_root() . '/connections/pending',
|
||||
'sel' => ($pending) ? 'active' : '',
|
||||
'title' => t('Show pending (new) connections'),
|
||||
),
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
array(
|
||||
'label' => t('Unblocked'),
|
||||
@@ -177,68 +179,70 @@ class Connections extends \Zotlabs\Web\Controller {
|
||||
'title' => t('Only show unblocked connections'),
|
||||
),
|
||||
*/
|
||||
|
||||
|
||||
'blocked' => array(
|
||||
'label' => t('Blocked'),
|
||||
'url' => z_root() . '/connections/blocked',
|
||||
'sel' => ($blocked) ? 'active' : '',
|
||||
'title' => t('Only show blocked connections'),
|
||||
),
|
||||
|
||||
|
||||
'ignored' => array(
|
||||
'label' => t('Ignored'),
|
||||
'url' => z_root() . '/connections/ignored',
|
||||
'sel' => ($ignored) ? 'active' : '',
|
||||
'title' => t('Only show ignored connections'),
|
||||
),
|
||||
|
||||
|
||||
'archived' => array(
|
||||
'label' => t('Archived/Unreachable'),
|
||||
'url' => z_root() . '/connections/archived',
|
||||
'sel' => ($archived) ? 'active' : '',
|
||||
'title' => t('Only show archived/unreachable connections'),
|
||||
),
|
||||
|
||||
|
||||
'hidden' => array(
|
||||
'label' => t('Hidden'),
|
||||
'url' => z_root() . '/connections/hidden',
|
||||
'sel' => ($hidden) ? 'active' : '',
|
||||
'title' => t('Only show hidden connections'),
|
||||
),
|
||||
|
||||
|
||||
// array(
|
||||
// 'label' => t('Unconnected'),
|
||||
// 'url' => z_root() . '/connections/unconnected',
|
||||
// 'sel' => ($unconnected) ? 'active' : '',
|
||||
// 'title' => t('Only show one-way connections'),
|
||||
// ),
|
||||
|
||||
|
||||
|
||||
'all' => array(
|
||||
'label' => t('All Connections'),
|
||||
'url' => z_root() . '/connections',
|
||||
'url' => z_root() . '/connections',
|
||||
'sel' => ($all) ? 'active' : '',
|
||||
'title' => t('Show all connections'),
|
||||
),
|
||||
|
||||
|
||||
);
|
||||
|
||||
|
||||
//$tab_tpl = get_markup_template('common_tabs.tpl');
|
||||
//$t = replace_macros($tab_tpl, array('$tabs'=>$tabs));
|
||||
|
||||
|
||||
$searching = false;
|
||||
$search_hdr = '';
|
||||
|
||||
if($search) {
|
||||
$search_hdr = $search;
|
||||
$search_txt = dbesc(protect_sprintf(preg_quote($search)));
|
||||
$searching = true;
|
||||
}
|
||||
$sql_extra .= (($searching) ? protect_sprintf(" AND xchan_name like '%$search_txt%' ") : "");
|
||||
|
||||
if($_REQUEST['gid']) {
|
||||
|
||||
if(isset($_REQUEST['gid']) && $_REQUEST['gid']) {
|
||||
$sql_extra .= " and xchan_hash in ( select xchan from pgrp_member where gid = " . intval($_REQUEST['gid']) . " and uid = " . intval(local_channel()) . " ) ";
|
||||
}
|
||||
|
||||
$r = q("SELECT COUNT(abook.abook_id) AS total FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash
|
||||
|
||||
$r = q("SELECT COUNT(abook.abook_id) AS total FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash
|
||||
where abook_channel = %d and abook_self = 0 and xchan_deleted = 0 and xchan_orphan = 0 $sql_extra ",
|
||||
intval(local_channel())
|
||||
);
|
||||
@@ -246,32 +250,39 @@ class Connections extends \Zotlabs\Web\Controller {
|
||||
App::set_pager_total($r[0]['total']);
|
||||
$total = $r[0]['total'];
|
||||
}
|
||||
|
||||
|
||||
$r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash
|
||||
WHERE abook_channel = %d and abook_self = 0 and xchan_deleted = 0 and xchan_orphan = 0 $sql_extra ORDER BY $sql_order LIMIT %d OFFSET %d ",
|
||||
intval(local_channel()),
|
||||
intval(App::$pager['itemspage']),
|
||||
intval(App::$pager['start'])
|
||||
);
|
||||
|
||||
|
||||
$roles = new Permcat(local_channel());
|
||||
$roles_list = $roles->listing();
|
||||
$roles_dict = [];
|
||||
|
||||
foreach ($roles_list as $role) {
|
||||
$roles_dict[$role['name']] = $role['localname'];
|
||||
}
|
||||
|
||||
$contacts = array();
|
||||
|
||||
|
||||
if($r) {
|
||||
|
||||
vcard_query($r);
|
||||
//vcard_query($r);
|
||||
|
||||
|
||||
foreach($r as $rr) {
|
||||
if($rr['xchan_url']) {
|
||||
|
||||
if(($rr['vcard']) && is_array($rr['vcard']['tels']) && $rr['vcard']['tels'][0]['nr'])
|
||||
if((isset($rr['vcard'])) && is_array($rr['vcard']['tels']) && $rr['vcard']['tels'][0]['nr'])
|
||||
$phone = $rr['vcard']['tels'][0]['nr'];
|
||||
else
|
||||
$phone = '';
|
||||
|
||||
|
||||
$status_str = '';
|
||||
$status = array(
|
||||
((intval($rr['abook_active'])) ? t('Active') : ''),
|
||||
((intval($rr['abook_pending'])) ? t('Pending approval') : ''),
|
||||
((intval($rr['abook_archived'])) ? t('Archived') : ''),
|
||||
((intval($rr['abook_hidden'])) ? t('Hidden') : ''),
|
||||
@@ -306,7 +317,7 @@ class Connections extends \Zotlabs\Web\Controller {
|
||||
$perminfo['connperms'] .= t('Nothing');
|
||||
}
|
||||
|
||||
|
||||
|
||||
foreach($status as $str) {
|
||||
if(!$str)
|
||||
continue;
|
||||
@@ -314,19 +325,16 @@ class Connections extends \Zotlabs\Web\Controller {
|
||||
$status_str .= ', ';
|
||||
}
|
||||
$status_str = rtrim($status_str, ', ');
|
||||
|
||||
|
||||
$contacts[] = array(
|
||||
'img_hover' => sprintf( t('%1$s [%2$s]'),$rr['xchan_name'],$rr['xchan_url']),
|
||||
'edit_hover' => t('Edit connection'),
|
||||
'edit' => t('Edit'),
|
||||
'delete_hover' => t('Delete connection'),
|
||||
'id' => $rr['abook_id'],
|
||||
'thumb' => $rr['xchan_photo_m'],
|
||||
'thumb' => $rr['xchan_photo_m'],
|
||||
'name' => $rr['xchan_name'],
|
||||
'classes' => ((intval($rr['abook_archived']) || intval($rr['abook_not_here'])) ? 'archived' : ''),
|
||||
'link' => z_root() . '/connedit/' . $rr['abook_id'],
|
||||
'deletelink' => z_root() . '/connedit/' . intval($rr['abook_id']) . '/drop',
|
||||
'delete' => t('Delete'),
|
||||
'url' => chanlink_hash($rr['xchan_hash']),
|
||||
'webbie_label' => t('Channel address'),
|
||||
'webbie' => $rr['xchan_addr'],
|
||||
@@ -337,6 +345,7 @@ class Connections extends \Zotlabs\Web\Controller {
|
||||
'phone' => $phone,
|
||||
'status_label' => t('Status'),
|
||||
'status' => $status_str,
|
||||
'states' => $status,
|
||||
'connected_label' => t('Connected'),
|
||||
'connected' => datetime_convert('UTC',date_default_timezone_get(),$rr['abook_created'], 'c'),
|
||||
'approve_hover' => t('Approve connection'),
|
||||
@@ -348,15 +357,24 @@ class Connections extends \Zotlabs\Web\Controller {
|
||||
'oneway' => $oneway,
|
||||
'perminfo' => $perminfo,
|
||||
'connect' => (intval($rr['abook_not_here']) ? t('Connect') : ''),
|
||||
'follow' => z_root() . '/follow/?f=&url=' . urlencode($rr['xchan_hash']) . '&interactive=0',
|
||||
'connect_hover' => t('Connect at this location')
|
||||
'follow' => z_root() . '/follow/?f=&url=' . urlencode($rr['xchan_hash']) . '&interactive=1',
|
||||
'connect_hover' => t('Connect at this location'),
|
||||
'role' => $roles_dict[$rr['abook_role']] ?? '',
|
||||
'pending' => intval($rr['abook_pending'])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if($_REQUEST['aj']) {
|
||||
|
||||
$limit = service_class_fetch(local_channel(),'total_channels');
|
||||
if($limit !== false) {
|
||||
$abook_usage_message = sprintf( t("You have %1$.0f of %2$.0f allowed connections."), $total, $limit);
|
||||
}
|
||||
else {
|
||||
$abook_usage_message = '';
|
||||
}
|
||||
|
||||
if(isset($_REQUEST['aj']) && $_REQUEST['aj']) {
|
||||
if($contacts) {
|
||||
$o = replace_macros(get_markup_template('contactsajax.tpl'),array(
|
||||
'$contacts' => $contacts,
|
||||
@@ -371,27 +389,30 @@ class Connections extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
else {
|
||||
$o .= "<script> var page_query = '" . escape_tags(urlencode($_GET['q'])) . "'; var extra_args = '" . extra_query_args() . "' ; </script>";
|
||||
$o .= replace_macros(get_markup_template('connections.tpl'),array(
|
||||
$o .= replace_macros(get_markup_template('connections.tpl'), [
|
||||
'$header' => t('Connections') . (($head) ? ': ' . $head : ''),
|
||||
'$tabs' => $tabs,
|
||||
'$total' => $total,
|
||||
'$search' => $search_hdr,
|
||||
'$label' => t('Search'),
|
||||
'$role_label' => t('Contact role'),
|
||||
'$desc' => t('Search your connections'),
|
||||
'$finding' => (($searching) ? t('Connections search') . ": '" . $search . "'" : ""),
|
||||
'$finding' => (($searching) ? t('Contact search') . ": '" . $search . "'" : ""),
|
||||
'$submit' => t('Find'),
|
||||
'$edit' => t('Edit'),
|
||||
'$approve' => t('Approve'),
|
||||
'$cmd' => App::$cmd,
|
||||
'$contacts' => $contacts,
|
||||
'$paginate' => paginate($a),
|
||||
|
||||
));
|
||||
'$abook_usage_message' => $abook_usage_message,
|
||||
'$group_label' => t('This is a group/forum channel')
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
if(! $contacts)
|
||||
$o .= '<div id="content-complete"></div>';
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
675
Zotlabs/Module/Contactedit.php
Normal file
675
Zotlabs/Module/Contactedit.php
Normal file
@@ -0,0 +1,675 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
/* @file Cobtactedit.php
|
||||
* @brief In this file the connection-editor form is generated and evaluated.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
use App;
|
||||
use Sabre\VObject\Reader;
|
||||
use Zotlabs\Lib\Apps;
|
||||
use Zotlabs\Lib\Libzot;
|
||||
use Zotlabs\Lib\Libsync;
|
||||
use Zotlabs\Daemon\Master;
|
||||
use Zotlabs\Web\Controller;
|
||||
use Zotlabs\Access\Permissions;
|
||||
use Zotlabs\Access\PermissionLimits;
|
||||
use Zotlabs\Web\HTTPHeaders;
|
||||
use Zotlabs\Lib\Permcat;
|
||||
use Zotlabs\Lib\AccessList;
|
||||
|
||||
require_once('include/socgraph.php');
|
||||
require_once('include/selectors.php');
|
||||
require_once('include/group.php');
|
||||
require_once('include/photos.php');
|
||||
|
||||
class Contactedit extends Controller {
|
||||
|
||||
/* @brief Initialize the connection-editor
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
function init() {
|
||||
|
||||
if (!local_channel())
|
||||
return;
|
||||
|
||||
if ((argc() >= 2) && intval(argv(1))) {
|
||||
$r = q("SELECT abook.*, xchan.* FROM abook LEFT JOIN xchan ON abook_xchan = xchan_hash
|
||||
WHERE abook_channel = %d AND abook_id = %d AND abook_self = 0 AND xchan_deleted = 0",
|
||||
intval(local_channel()),
|
||||
intval(argv(1))
|
||||
);
|
||||
if (!$r) {
|
||||
json_return_and_die([
|
||||
'success' => false,
|
||||
'message' => t('Invalid abook_id')
|
||||
]);
|
||||
}
|
||||
|
||||
App::$poi = $r[0];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* @brief Evaluate posted values and set changes
|
||||
*
|
||||
*/
|
||||
|
||||
function post() {
|
||||
|
||||
if (!local_channel())
|
||||
return;
|
||||
|
||||
$contact_id = intval(argv(1));
|
||||
if (!$contact_id)
|
||||
return;
|
||||
|
||||
$channel = App::get_channel();
|
||||
|
||||
$contact = App::$poi;
|
||||
|
||||
if (!$contact) {
|
||||
notice(t('Could not access contact record.') . EOL);
|
||||
killme();
|
||||
}
|
||||
|
||||
call_hooks('contact_edit_post', $_REQUEST);
|
||||
|
||||
if (Apps::system_app_installed(local_channel(), 'Privacy Groups')) {
|
||||
$pgrp_ids = q("SELECT id FROM pgrp WHERE deleted = 0 AND uid = %d",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
foreach($pgrp_ids as $pgrp) {
|
||||
if (array_key_exists('pgrp_id_' . $pgrp['id'], $_REQUEST)) {
|
||||
AccessList::member_add(local_channel(), '', $contact['abook_xchan'], $pgrp['id']);
|
||||
}
|
||||
else {
|
||||
AccessList::member_remove(local_channel(), '', $contact['abook_xchan'], $pgrp['id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$profile_id = ((array_key_exists('profile_assign', $_REQUEST)) ? $_REQUEST['profile_assign'] : $contact['abook_profile']);
|
||||
|
||||
if ($profile_id) {
|
||||
$r = q("SELECT profile_guid FROM profile WHERE profile_guid = '%s' AND uid = %d LIMIT 1",
|
||||
dbesc($profile_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
if (!$r) {
|
||||
notice(t('Could not locate selected profile.') . EOL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$abook_incl = ((array_key_exists('abook_incl', $_REQUEST)) ? escape_tags($_REQUEST['abook_incl']) : $contact['abook_incl']);
|
||||
$abook_excl = ((array_key_exists('abook_excl', $_REQUEST)) ? escape_tags($_REQUEST['abook_excl']) : $contact['abook_excl']);
|
||||
$abook_role = ((array_key_exists('permcat', $_REQUEST)) ? escape_tags($_REQUEST['permcat']) : $contact['abook_role']);
|
||||
|
||||
if (!array_key_exists('closeness', $_REQUEST)) {
|
||||
$_REQUEST['closeness'] = 80;
|
||||
}
|
||||
|
||||
$closeness = intval($_REQUEST['closeness']);
|
||||
|
||||
if ($closeness < 0 || $closeness > 99) {
|
||||
$closeness = 80;
|
||||
}
|
||||
|
||||
$new_friend = ((intval($contact['abook_pending'])) ? true : false);
|
||||
|
||||
\Zotlabs\Lib\Permcat::assign($channel, $abook_role, [$contact['abook_xchan']]);
|
||||
|
||||
$abook_pending = (($new_friend) ? 0 : $contact['abook_pending']);
|
||||
|
||||
$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($closeness),
|
||||
intval($abook_pending),
|
||||
dbesc($abook_incl),
|
||||
dbesc($abook_excl),
|
||||
intval($contact_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
$_REQUEST['success'] = false;
|
||||
|
||||
if ($r) {
|
||||
$_REQUEST['success'] = true;
|
||||
}
|
||||
|
||||
|
||||
if (!intval($contact['abook_self'])) {
|
||||
if ($new_friend) {
|
||||
Master::Summon(['Notifier', 'permission_accept', $contact_id]);
|
||||
}
|
||||
|
||||
Master::Summon([
|
||||
'Notifier',
|
||||
(($new_friend) ? 'permission_create' : 'permission_update'),
|
||||
$contact_id
|
||||
]);
|
||||
}
|
||||
|
||||
if ($new_friend) {
|
||||
$default_group = $channel['channel_default_group'];
|
||||
if ($default_group) {
|
||||
$g = AccessList::by_hash(local_channel(), $default_group);
|
||||
if ($g) {
|
||||
AccessList::member_add(local_channel(), '', $contact['abook_xchan'], $g['id']);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if settings permit ("post new friend activity" is allowed, and
|
||||
// friends in general or this friend in particular aren't hidden)
|
||||
// and send out a new friend activity
|
||||
|
||||
$pr = q("select * from profile where uid = %d and is_default = 1 and hide_friends = 0",
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if (($pr) && (!intval($contact['abook_hidden'])) && (intval(get_pconfig($channel['channel_id'], 'system', 'post_newfriend')))) {
|
||||
$xarr = [];
|
||||
|
||||
$xarr['item_wall'] = 1;
|
||||
$xarr['item_origin'] = 1;
|
||||
$xarr['item_thread_top'] = 1;
|
||||
$xarr['owner_xchan'] = $xarr['author_xchan'] = $channel['channel_hash'];
|
||||
$xarr['allow_cid'] = $channel['channel_allow_cid'];
|
||||
$xarr['allow_gid'] = $channel['channel_allow_gid'];
|
||||
$xarr['deny_cid'] = $channel['channel_deny_cid'];
|
||||
$xarr['deny_gid'] = $channel['channel_deny_gid'];
|
||||
$xarr['item_private'] = (($xarr['allow_cid'] || $xarr['allow_gid'] || $xarr['deny_cid'] || $xarr['deny_gid']) ? 1 : 0);
|
||||
|
||||
$xarr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t('is now connected to') . ' ' . '[zrl=' . $contact['xchan_url'] . ']' . $contact['xchan_name'] . '[/zrl]';
|
||||
|
||||
$xarr['body'] .= "\n\n\n" . '[zrl=' . $contact['xchan_url'] . '][zmg=80x80]' . $contact['xchan_photo_m'] . '[/zmg][/zrl]';
|
||||
|
||||
post_activity_item($xarr);
|
||||
|
||||
}
|
||||
|
||||
// pull in a bit of content if there is any to pull in
|
||||
Master::Summon(['Onepoll', $contact_id]);
|
||||
|
||||
}
|
||||
|
||||
// Refresh the structure in memory with the new data
|
||||
$this->init();
|
||||
|
||||
if ($new_friend) {
|
||||
$arr = ['channel_id' => local_channel(), 'abook' => App::$poi];
|
||||
call_hooks('accept_follow', $arr);
|
||||
}
|
||||
|
||||
$this->contactedit_clone();
|
||||
$this->get();
|
||||
|
||||
killme();
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* @brief Generate content of contact edit page
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
function get() {
|
||||
|
||||
if (!local_channel()) {
|
||||
killme();
|
||||
}
|
||||
|
||||
if (!App::$poi) {
|
||||
killme();
|
||||
}
|
||||
|
||||
|
||||
$channel = App::get_channel();
|
||||
$contact_id = App::$poi['abook_id'];
|
||||
$contact = App::$poi;
|
||||
$section = ((array_key_exists('section', $_REQUEST)) ? $_REQUEST['section'] : 'roles');
|
||||
$sub_section = ((array_key_exists('sub_section', $_REQUEST)) ? $_REQUEST['sub_section'] : '');
|
||||
|
||||
|
||||
if (argc() == 3) {
|
||||
$cmd = argv(2);
|
||||
$ret = $this->do_action($contact, $cmd);
|
||||
$contact = App::$poi;
|
||||
|
||||
$tools_html = replace_macros(get_markup_template("contact_edit_tools.tpl"), [
|
||||
'$tools_label' => t('Contact Tools'),
|
||||
'$tools' => $this->get_tools($contact),
|
||||
]);
|
||||
|
||||
$ret['tools'] = $tools_html;
|
||||
|
||||
json_return_and_die($ret);
|
||||
}
|
||||
|
||||
$groups = [];
|
||||
|
||||
if (Apps::system_app_installed(local_channel(), 'Privacy Groups')) {
|
||||
|
||||
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
$member_of = AccessList::containing(local_channel(), $contact['xchan_hash']);
|
||||
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
$default_group = false;
|
||||
if ($rr['hash'] === $channel['channel_default_group']) {
|
||||
$default_group = true;
|
||||
}
|
||||
|
||||
$groups[] = [
|
||||
'pgrp_id_' . $rr['id'],
|
||||
$rr['gname'],
|
||||
// if it's a new contact preset the default group if we have one
|
||||
(($default_group && $contact['abook_pending']) ? 1 : in_array($rr['id'], $member_of)),
|
||||
'',
|
||||
[t('No'), t('Yes')]
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$slide = '';
|
||||
|
||||
if (Apps::system_app_installed(local_channel(), 'Affinity Tool')) {
|
||||
|
||||
$labels = [
|
||||
t('Me'),
|
||||
t('Family'),
|
||||
t('Friends'),
|
||||
t('Acquaintances'),
|
||||
t('All')
|
||||
];
|
||||
call_hooks('affinity_labels', $labels);
|
||||
$label_str = '';
|
||||
|
||||
if ($labels) {
|
||||
foreach ($labels as $l) {
|
||||
if ($label_str) {
|
||||
$label_str .= ", '|'";
|
||||
$label_str .= ", '" . $l . "'";
|
||||
}
|
||||
else
|
||||
$label_str .= "'" . $l . "'";
|
||||
}
|
||||
}
|
||||
|
||||
$slider_tpl = get_markup_template('contact_slider.tpl');
|
||||
|
||||
$slideval = intval($contact['abook_closeness']);
|
||||
|
||||
$slide = replace_macros($slider_tpl, [
|
||||
'$min' => 1,
|
||||
'$val' => $slideval,
|
||||
'$labels' => $label_str,
|
||||
]);
|
||||
}
|
||||
|
||||
$perms = [];
|
||||
$global_perms = Permissions::Perms();
|
||||
$existing = get_all_perms(local_channel(), $contact['abook_xchan'], false);
|
||||
$unapproved = ['pending', t('Approve this contact'), '', t('Accept contact to allow communication'), [t('No'), ('Yes')]];
|
||||
$multiprofs = ((feature_enabled(local_channel(), 'multi_profiles')) ? true : false);
|
||||
|
||||
$theirs = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'their_perms'",
|
||||
intval(local_channel()),
|
||||
dbesc($contact['abook_xchan'])
|
||||
);
|
||||
|
||||
$their_perms = [];
|
||||
if ($theirs) {
|
||||
foreach ($theirs as $t) {
|
||||
$their_perms[$t['k']] = $t['v'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($global_perms as $k => $v) {
|
||||
$thisperm = $existing[$k];
|
||||
$checkinherited = PermissionLimits::Get(local_channel(), $k);
|
||||
$perms[] = ['perms_' . $k, $v, ((array_key_exists($k, $their_perms)) ? intval($their_perms[$k]) : ''), $thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '0' : '1'), '', $checkinherited];
|
||||
}
|
||||
|
||||
$pcat = new Permcat(local_channel());
|
||||
$pcatlist = $pcat->listing();
|
||||
$default_role = get_pconfig(local_channel(), 'system', 'default_permcat');
|
||||
$current_permcat = (($contact['abook_pending']) ? $default_role : $contact['abook_role']);
|
||||
|
||||
$roles_dict = [];
|
||||
foreach ($pcatlist as $role) {
|
||||
$roles_dict[$role['name']] = $role['localname'];
|
||||
}
|
||||
|
||||
|
||||
if (!$current_permcat) {
|
||||
notice(t('Please select a role for this contact!') . EOL);
|
||||
$permcats[] = '';
|
||||
}
|
||||
|
||||
if ($pcatlist) {
|
||||
foreach ($pcatlist as $pc) {
|
||||
$permcats[$pc['name']] = $pc['localname'];
|
||||
}
|
||||
}
|
||||
|
||||
$locstr = locations_by_netid($contact['xchan_hash']);
|
||||
if (!$locstr) {
|
||||
$locstr = unpunify($contact['xchan_url']);
|
||||
}
|
||||
|
||||
$clone_warn = '';
|
||||
$clonable = in_array($contact['xchan_network'], ['zot6', 'rss']);
|
||||
if (!$clonable) {
|
||||
$clone_warn = '<strong>';
|
||||
$clone_warn .= ((intval($contact['abook_not_here']))
|
||||
? t('This contact is unreachable from this location.')
|
||||
: t('This contact may be unreachable from other channel locations.')
|
||||
);
|
||||
$clone_warn .= '</strong><br>' . t('Location independence is not supported by their network.');
|
||||
}
|
||||
|
||||
$header_card = '<img src="' . $contact['xchan_photo_s'] . '" class="rounded" style="width: 3rem; height: 3rem;"> ' . $contact['xchan_name'];
|
||||
|
||||
$header_html = replace_macros(get_markup_template("contact_edit_header.tpl"), [
|
||||
'$img_src' => $contact['xchan_photo_s'],
|
||||
'$name' => $contact['xchan_name'],
|
||||
'$addr' => (($contact['xchan_addr']) ? $contact['xchan_addr'] : $contact['xchan_url']),
|
||||
'$href' => ((is_matrix_url($contact['xchan_url'])) ? zid($contact['xchan_url']) : $contact['xchan_url']),
|
||||
'$link_label' => t('View profile'),
|
||||
'$is_group' => $contact['xchan_pubforum'],
|
||||
'$group_label' => t('This is a group/forum channel')
|
||||
]);
|
||||
|
||||
$tools_html = replace_macros(get_markup_template("contact_edit_tools.tpl"), [
|
||||
'$tools_label' => t('Contact Tools'),
|
||||
'$tools' => $this->get_tools($contact),
|
||||
]);
|
||||
|
||||
$tpl = get_markup_template("contact_edit.tpl");
|
||||
|
||||
$o = replace_macros($tpl, [
|
||||
'$permcat' => ['permcat', t('Select a role for this contact'), $current_permcat, '', $permcats],
|
||||
'$permcat_new' => t('Contact roles'),
|
||||
'$permcat_value' => bin2hex($current_permcat),
|
||||
// '$addr' => unpunify($contact['xchan_addr']),
|
||||
// '$primeurl' => unpunify($contact['xchan_url']),
|
||||
'$section' => $section,
|
||||
'$sub_section' => $sub_section,
|
||||
'$groups' => $groups,
|
||||
// '$addr_text' => t('This contacts\'s primary address is'),
|
||||
// '$loc_text' => t('Available locations:'),
|
||||
// '$locstr' => $locstr,
|
||||
// '$unclonable' => $clone_warn,
|
||||
'$lbl_slider' => t('Slide to adjust your degree of friendship'),
|
||||
'$connfilter' => feature_enabled(local_channel(), 'connfilter'),
|
||||
'$connfilter_label' => t('Custom Filter'),
|
||||
'$incl' => ['abook_incl', t('Only import posts with this text'), $contact['abook_incl'], t('words one per line or #tags or /patterns/ or lang=xx, leave blank to import all posts')],
|
||||
'$excl' => ['abook_excl', t('Do not import posts with this text'), $contact['abook_excl'], t('words one per line or #tags or /patterns/ or lang=xx, leave blank to import all posts')],
|
||||
'$slide' => $slide,
|
||||
// '$pending_label' => t('Contact Pending Approval'),
|
||||
// '$is_pending' => (intval($contact['abook_pending']) ? 1 : ''),
|
||||
// '$unapproved' => $unapproved,
|
||||
'$submit' => ((intval($contact['abook_pending'])) ? t('Approve contact') : t('Submit')),
|
||||
'$close' => (($contact['abook_closeness']) ? $contact['abook_closeness'] : 80),
|
||||
'$them' => t('Their'),
|
||||
'$me' => t('My'),
|
||||
'$perms' => $perms,
|
||||
// '$lastupdtext' => t('Last update:'),
|
||||
// '$last_update' => relative_date($contact['abook_connected']),
|
||||
'$profile_select' => contact_profile_assign($contact['abook_profile']),
|
||||
'$multiprofs' => $multiprofs,
|
||||
'$contact_id' => $contact['abook_id'],
|
||||
// '$name' => $contact['xchan_name'],
|
||||
'$roles_label' => t('Roles'),
|
||||
'$compare_label' => t('Compare permissions'),
|
||||
'$permission_label' => t('Permission'),
|
||||
'$pgroups_label' => t('Privacy groups'),
|
||||
'$profiles_label' => t('Profiles'),
|
||||
'$affinity_label' => t('Affinity'),
|
||||
'$filter_label' => t('Content filter')
|
||||
]);
|
||||
|
||||
$arr = ['contact' => $contact, 'output' => $o];
|
||||
|
||||
call_hooks('contact_edit', $arr);
|
||||
|
||||
if (is_ajax()) {
|
||||
json_return_and_die([
|
||||
'success' => ((isset($_REQUEST['success'])) ? intval($_REQUEST['success']) : 1),
|
||||
'message' => ((isset($_REQUEST['success'])) ? t('Contact updated') : t('Contact update failed')),
|
||||
'id' => $contact_id,
|
||||
'title' => $header_html,
|
||||
'role' => ((intval($contact['abook_pending'])) ? '' : $roles_dict[$current_permcat]),
|
||||
'body' => $arr['output'],
|
||||
'tools' => $tools_html,
|
||||
'submit' => ((intval($contact['abook_pending'])) ? t('Approve connection') : t('Submit')),
|
||||
'pending' => intval($contact['abook_pending'])
|
||||
]);
|
||||
}
|
||||
|
||||
return $arr['output'];
|
||||
|
||||
}
|
||||
|
||||
function contactedit_clone() {
|
||||
|
||||
if (!App::$poi)
|
||||
return;
|
||||
|
||||
$channel = App::get_channel();
|
||||
|
||||
$clone = App::$poi;
|
||||
|
||||
unset($clone['abook_id']);
|
||||
unset($clone['abook_account']);
|
||||
unset($clone['abook_channel']);
|
||||
|
||||
$abconfig = load_abconfig($channel['channel_id'], $clone['abook_xchan']);
|
||||
if ($abconfig)
|
||||
$clone['abconfig'] = $abconfig;
|
||||
|
||||
Libsync::build_sync_packet(0 /* use the current local_channel */, ['abook' => [$clone]]);
|
||||
}
|
||||
|
||||
function do_action($contact, $cmd) {
|
||||
$ret = [
|
||||
'sucess' => false,
|
||||
'message' => ''
|
||||
];
|
||||
|
||||
if ($cmd === 'resetphoto') {
|
||||
q("update xchan set xchan_photo_date = '2001-01-01 00:00:00' where xchan_hash = '%s'",
|
||||
dbesc($contact['xchan_hash'])
|
||||
);
|
||||
$cmd = 'refresh';
|
||||
}
|
||||
|
||||
if ($cmd === 'refresh') {
|
||||
if ($contact['xchan_network'] === 'zot6') {
|
||||
if (Libzot::refresh($contact, App::get_channel())) {
|
||||
$ret['success'] = true;
|
||||
$ret['message'] = t('Refresh succeeded');
|
||||
}
|
||||
else {
|
||||
$ret['message'] = t('Refresh failed - channel is currently unavailable');
|
||||
}
|
||||
}
|
||||
else {
|
||||
// if you are on a different network we'll force a refresh of the connection basic info
|
||||
Master::Summon(['Notifier', 'permission_update', $contact['abook_id']]);
|
||||
$ret['success'] = true;
|
||||
$ret['message'] = t('Refresh succeeded');
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if ($cmd === 'block') {
|
||||
if (abook_toggle_flag($contact, ABOOK_FLAG_BLOCKED)) {
|
||||
$this->init(); // refresh data
|
||||
|
||||
$this->contactedit_clone();
|
||||
$ret['success'] = true;
|
||||
$ret['message'] = t('Block status updated');
|
||||
}
|
||||
else {
|
||||
$ret['success'] = false;
|
||||
$ret['message'] = t('Block failed');
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if ($cmd === 'ignore') {
|
||||
if (abook_toggle_flag($contact, ABOOK_FLAG_IGNORED)) {
|
||||
$this->init(); // refresh data
|
||||
|
||||
$this->contactedit_clone();
|
||||
$ret['success'] = true;
|
||||
$ret['message'] = t('Ignore status updated');
|
||||
}
|
||||
else {
|
||||
$ret['success'] = false;
|
||||
$ret['message'] = t('Ignore failed');
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if ($cmd === 'archive') {
|
||||
if (abook_toggle_flag($contact, ABOOK_FLAG_ARCHIVED)) {
|
||||
$this->init(); // refresh data
|
||||
|
||||
$this->contactedit_clone();
|
||||
$ret['success'] = true;
|
||||
$ret['message'] = t('Archive status updated');
|
||||
}
|
||||
else {
|
||||
$ret['success'] = false;
|
||||
$ret['message'] = t('Archive failed');
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if ($cmd === 'hide') {
|
||||
if (abook_toggle_flag($contact, ABOOK_FLAG_HIDDEN)) {
|
||||
$this->init(); // refresh data
|
||||
|
||||
$this->contactedit_clone();
|
||||
$ret['success'] = true;
|
||||
$ret['message'] = t('Hide status updated');
|
||||
}
|
||||
else {
|
||||
$ret['success'] = false;
|
||||
$ret['message'] = t('Hide failed');
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// We'll prevent somebody from unapproving an already approved contact.
|
||||
// Though maybe somebody will want this eventually (??)
|
||||
|
||||
//if ($cmd === 'approve') {
|
||||
//if (intval($contact['abook_pending'])) {
|
||||
//if (abook_toggle_flag($contact, ABOOK_FLAG_PENDING)) {
|
||||
//$this->contactedit_clone();
|
||||
//}
|
||||
//else
|
||||
//notice(t('Unable to set address book parameters.') . EOL);
|
||||
//}
|
||||
//goaway(z_root() . '/connedit/' . $contact_id);
|
||||
//}
|
||||
|
||||
|
||||
if ($cmd === 'drop') {
|
||||
|
||||
if (contact_remove(local_channel(), $contact['abook_id'])) {
|
||||
|
||||
Master::Summon(['Notifier', 'purge', local_channel(), $contact['xchan_hash']]);
|
||||
Libsync::build_sync_packet(0 /* use the current local_channel */,
|
||||
['abook' => [
|
||||
[
|
||||
'abook_xchan' => $contact['abook_xchan'],
|
||||
'entry_deleted' => true
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
$ret['success'] = true;
|
||||
$ret['message'] = t('Contact removed');
|
||||
}
|
||||
else {
|
||||
$ret['success'] = false;
|
||||
$ret['message'] = t('Delete failed');
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
function get_tools($contact) {
|
||||
return [
|
||||
|
||||
'refresh' => [
|
||||
'label' => t('Refresh Permissions'),
|
||||
'title' => t('Fetch updated permissions'),
|
||||
],
|
||||
|
||||
'rephoto' => [
|
||||
'label' => t('Refresh Photo'),
|
||||
'title' => t('Fetch updated photo'),
|
||||
],
|
||||
|
||||
|
||||
'block' => [
|
||||
'label' => (intval($contact['abook_blocked']) ? t('Unblock') : t('Block')),
|
||||
'sel' => (intval($contact['abook_blocked']) ? 'active' : ''),
|
||||
'title' => t('Block (or Unblock) all communications with this connection'),
|
||||
'info' => (intval($contact['abook_blocked']) ? t('This connection is blocked!') : ''),
|
||||
],
|
||||
|
||||
'ignore' => [
|
||||
'label' => (intval($contact['abook_ignored']) ? t('Unignore') : t('Ignore')),
|
||||
'sel' => (intval($contact['abook_ignored']) ? 'active' : ''),
|
||||
'title' => t('Ignore (or Unignore) all inbound communications from this connection'),
|
||||
'info' => (intval($contact['abook_ignored']) ? t('This connection is ignored!') : ''),
|
||||
],
|
||||
|
||||
'archive' => [
|
||||
'label' => (intval($contact['abook_archived']) ? t('Unarchive') : t('Archive')),
|
||||
'sel' => (intval($contact['abook_archived']) ? 'active' : ''),
|
||||
'title' => t('Archive (or Unarchive) this connection - mark channel dead but keep content'),
|
||||
'info' => (intval($contact['abook_archived']) ? t('This connection is archived!') : ''),
|
||||
],
|
||||
|
||||
'hide' => [
|
||||
'label' => (intval($contact['abook_hidden']) ? t('Unhide') : t('Hide')),
|
||||
'sel' => (intval($contact['abook_hidden']) ? 'active' : ''),
|
||||
'title' => t('Hide or Unhide this connection from your other connections'),
|
||||
'info' => (intval($contact['abook_hidden']) ? t('This connection is hidden!') : ''),
|
||||
],
|
||||
|
||||
'delete' => [
|
||||
'label' => t('Delete'),
|
||||
'sel' => '',
|
||||
'title' => t('Delete this connection'),
|
||||
],
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/group.php');
|
||||
use Zotlabs\Lib\AccessList;
|
||||
use Zotlabs\Web\Controller;
|
||||
|
||||
|
||||
class Contactgroup extends \Zotlabs\Web\Controller {
|
||||
class Contactgroup extends Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
|
||||
if(! local_channel()) {
|
||||
killme();
|
||||
}
|
||||
|
||||
|
||||
if((argc() > 2) && (intval(argv(1))) && (argv(2))) {
|
||||
$r = q("SELECT abook_xchan from abook where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 limit 1",
|
||||
dbesc(base64url_decode(argv(2))),
|
||||
@@ -20,9 +20,9 @@ class Contactgroup extends \Zotlabs\Web\Controller {
|
||||
if($r)
|
||||
$change = $r[0]['abook_xchan'];
|
||||
}
|
||||
|
||||
|
||||
if((argc() > 1) && (intval(argv(1)))) {
|
||||
|
||||
|
||||
$r = q("SELECT * FROM pgrp WHERE id = %d AND uid = %d AND deleted = 0 LIMIT 1",
|
||||
intval(argv(1)),
|
||||
intval(local_channel())
|
||||
@@ -30,25 +30,25 @@ class Contactgroup extends \Zotlabs\Web\Controller {
|
||||
if(! $r) {
|
||||
killme();
|
||||
}
|
||||
|
||||
|
||||
$group = $r[0];
|
||||
$members = group_get_members($group['id']);
|
||||
$members = AccessList::members(local_channel(), $group['id']);
|
||||
$preselected = array();
|
||||
if(count($members)) {
|
||||
foreach($members as $member)
|
||||
$preselected[] = $member['xchan_hash'];
|
||||
}
|
||||
|
||||
|
||||
if($change) {
|
||||
if(in_array($change,$preselected)) {
|
||||
group_rmv_member(local_channel(),$group['gname'],$change);
|
||||
AccessList::member_remove(local_channel(),$group['gname'],$change);
|
||||
}
|
||||
else {
|
||||
group_add_member(local_channel(),$group['gname'],$change);
|
||||
AccessList::member_add(local_channel(),$group['gname'],$change);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
killme();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ namespace Zotlabs\Module;
|
||||
|
||||
use Zotlabs\Lib\Libsync;
|
||||
|
||||
/*
|
||||
/*
|
||||
@file cover_photo.php
|
||||
@brief Module-file with functions for handling of cover-photos
|
||||
|
||||
@@ -29,43 +29,43 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
if(! local_channel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$channel = \App::get_channel();
|
||||
profile_load($channel['channel_address']);
|
||||
profile_load($channel['channel_address']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Evaluate posted values
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
function post() {
|
||||
|
||||
|
||||
if(! local_channel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$channel = \App::get_channel();
|
||||
|
||||
|
||||
check_form_security_token_redirectOnErr('/cover_photo', 'cover_photo');
|
||||
|
||||
// Remove cover photo
|
||||
if(isset($_POST['remove'])) {
|
||||
|
||||
|
||||
$r = q("SELECT resource_id FROM photo WHERE photo_usage = %d AND uid = %d LIMIT 1",
|
||||
intval(PHOTO_COVER),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
|
||||
if($r) {
|
||||
q("update photo set photo_usage = %d where photo_usage = %d and uid = %d",
|
||||
intval(PHOTO_NORMAL),
|
||||
intval(PHOTO_COVER),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
|
||||
$sync = attach_export_data($channel,$r[0]['resource_id']);
|
||||
if($sync)
|
||||
Libsync::build_sync_packet($channel['channel_id'],array('file' => array($sync)));
|
||||
@@ -76,47 +76,47 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
|
||||
goaway(z_root() . '/cover_photo');
|
||||
}
|
||||
|
||||
|
||||
if((array_key_exists('cropfinal',$_POST)) && ($_POST['cropfinal'] == 1)) {
|
||||
|
||||
|
||||
// phase 2 - we have finished cropping
|
||||
|
||||
|
||||
if(argc() != 2) {
|
||||
notice( t('Image uploaded but image cropping failed.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$image_id = argv(1);
|
||||
|
||||
|
||||
if(substr($image_id,-2,1) == '-') {
|
||||
$scale = substr($image_id,-1,1);
|
||||
$image_id = substr($image_id,0,-2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
$srcX = intval($_POST['xstart']);
|
||||
$srcY = intval($_POST['ystart']);
|
||||
$srcW = intval($_POST['xfinal']) - $srcX;
|
||||
$srcH = intval($_POST['yfinal']) - $srcY;
|
||||
|
||||
|
||||
$r = q("select gender from profile where uid = %d and is_default = 1 limit 1",
|
||||
intval(local_channel())
|
||||
);
|
||||
if($r) {
|
||||
$profile = $r[0];
|
||||
}
|
||||
|
||||
|
||||
$r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale = 0 LIMIT 1",
|
||||
dbesc($image_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
|
||||
if($r) {
|
||||
|
||||
$max_thumb = intval(get_config('system','max_thumbnail',1600));
|
||||
$iscaled = false;
|
||||
if(intval($r[0]['height']) > $max_thumb || intval($r[0]['width']) > $max_thumb) {
|
||||
if(intval($r[0]['height']) > $max_thumb || intval($r[0]['width']) > $max_thumb) {
|
||||
$imagick_path = get_config('system','imagick_convert_path');
|
||||
if($imagick_path && @file_exists($imagick_path) && intval($r[0]['os_storage'])) {
|
||||
|
||||
@@ -150,63 +150,63 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
|
||||
$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
|
||||
|
||||
// We are scaling and cropping the relative pixel locations to the original photo instead of the
|
||||
// scaled photo we operated on.
|
||||
|
||||
|
||||
// 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 imgscale = 3",
|
||||
dbesc($image_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
$scaled_width = $g[0]['width'];
|
||||
$scaled_height = $g[0]['height'];
|
||||
|
||||
|
||||
if((! $scaled_width) || (! $scaled_height)) {
|
||||
logger('potential divide by zero scaling cover photo');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// unset all other cover photos
|
||||
|
||||
|
||||
q("update photo set photo_usage = %d where photo_usage = %d and uid = %d",
|
||||
intval(PHOTO_NORMAL),
|
||||
intval(PHOTO_COVER),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
|
||||
$orig_srcx = ( $base_image['width'] / $scaled_width ) * $srcX;
|
||||
$orig_srcy = ( $base_image['height'] / $scaled_height ) * $srcY;
|
||||
$orig_srcw = ( $srcW / $scaled_width ) * $base_image['width'];
|
||||
$orig_srch = ( $srcH / $scaled_height ) * $base_image['height'];
|
||||
|
||||
|
||||
$im->cropImageRect(1200,435,$orig_srcx, $orig_srcy, $orig_srcw, $orig_srch);
|
||||
|
||||
|
||||
$aid = get_account_id();
|
||||
|
||||
$p = [
|
||||
'aid' => $aid,
|
||||
'uid' => local_channel(),
|
||||
|
||||
$p = [
|
||||
'aid' => $aid,
|
||||
'uid' => local_channel(),
|
||||
'resource_id' => $base_image['resource_id'],
|
||||
'filename' => $base_image['filename'],
|
||||
'filename' => $base_image['filename'],
|
||||
'album' => t('Cover Photos'),
|
||||
'os_path' => $base_image['os_path'],
|
||||
'display_path' => $base_image['display_path'],
|
||||
'photo_usage' => PHOTO_COVER
|
||||
];
|
||||
|
||||
|
||||
$r1 = $im->storeThumbnail($p, PHOTO_RES_COVER_1200);
|
||||
|
||||
|
||||
$im->doScaleImage(850,310);
|
||||
$r2 = $im->storeThumbnail($p, PHOTO_RES_COVER_850);
|
||||
|
||||
|
||||
$im->doScaleImage(425,160);
|
||||
$r3 = $im->storeThumbnail($p, PHOTO_RES_COVER_425);
|
||||
|
||||
|
||||
if($r1 === false || $r2 === false || $r3 === false) {
|
||||
// if one failed, delete them all so we can start over.
|
||||
notice( t('Image resize failed.') . EOL );
|
||||
@@ -214,7 +214,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
dbesc($base_image['resource_id']),
|
||||
local_channel()
|
||||
);
|
||||
|
||||
|
||||
$x = q("SELECT content FROM photo WHERE resource_id = '%s' AND uid = %d AND os_storage = 1 AND imgscale >= 7",
|
||||
dbesc($base_image['resource_id']),
|
||||
local_channel()
|
||||
@@ -229,7 +229,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
$this->send_cover_photo_activity($channel,$base_image,$profile);
|
||||
|
||||
|
||||
$sync = attach_export_data($channel,$base_image['resource_id']);
|
||||
if($sync)
|
||||
Libsync::build_sync_packet($channel['channel_id'],array('file' => array($sync)));
|
||||
@@ -240,33 +240,33 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
else
|
||||
notice( t('Unable to process image') . EOL);
|
||||
}
|
||||
|
||||
|
||||
goaway(z_root() . '/channel/' . $channel['channel_address']);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
$hash = photo_new_resource();
|
||||
$smallest = 0;
|
||||
|
||||
|
||||
require_once('include/attach.php');
|
||||
|
||||
|
||||
$res = attach_store(\App::get_channel(), get_observer_hash(), '', array('album' => t('Cover Photos'), 'hash' => $hash, 'nosync' => true));
|
||||
|
||||
|
||||
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 imgscale = 0",
|
||||
dbesc($hash),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
|
||||
if(! $i) {
|
||||
notice( t('Image upload failed.') . EOL );
|
||||
return;
|
||||
}
|
||||
$os_storage = false;
|
||||
|
||||
|
||||
foreach($i as $ii) {
|
||||
$smallest = intval($ii['imgscale']);
|
||||
$os_storage = intval($ii['os_storage']);
|
||||
@@ -274,91 +274,91 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
$filetype = $ii['mimetype'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$imagedata = (($os_storage) ? @file_get_contents(dbunescbin($imagedata)) : dbunescbin($imagedata));
|
||||
$ph = photo_factory($imagedata, $filetype);
|
||||
|
||||
|
||||
if(! $ph->is_valid()) {
|
||||
notice( t('Unable to process image.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
return $this->cover_photo_crop_ui_head($a, $ph, $hash, $smallest);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function send_cover_photo_activity($channel,$photo,$profile) {
|
||||
|
||||
|
||||
$arr = array();
|
||||
$arr['item_thread_top'] = 1;
|
||||
$arr['item_origin'] = 1;
|
||||
$arr['item_wall'] = 1;
|
||||
|
||||
|
||||
if($profile && stripos($profile['gender'],t('female')) !== false)
|
||||
$t = t('%1$s updated her %2$s');
|
||||
elseif($profile && stripos($profile['gender'],t('male')) !== false)
|
||||
$t = t('%1$s updated his %2$s');
|
||||
else
|
||||
$t = t('%1$s updated their %2$s');
|
||||
|
||||
|
||||
$ptext = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo['resource_id'] . ']' . t('cover photo') . '[/zrl]';
|
||||
|
||||
$ltext = '[zrl=' . z_root() . '/profile/' . $channel['channel_address'] . ']' . '[zmg]' . z_root() . '/photo/' . $photo['resource_id'] . '-8[/zmg][/zrl]';
|
||||
|
||||
|
||||
$ltext = '[zrl=' . z_root() . '/profile/' . $channel['channel_address'] . ']' . '[zmg]' . z_root() . '/photo/' . $photo['resource_id'] . '-8[/zmg][/zrl]';
|
||||
|
||||
$arr['body'] = sprintf($t,$channel['channel_name'],$ptext) . "\n\n" . $ltext;
|
||||
|
||||
|
||||
$acl = new \Zotlabs\Access\AccessList($channel);
|
||||
$x = $acl->get();
|
||||
$arr['allow_cid'] = $x['allow_cid'];
|
||||
|
||||
|
||||
$arr['allow_gid'] = $x['allow_gid'];
|
||||
$arr['deny_cid'] = $x['deny_cid'];
|
||||
$arr['deny_gid'] = $x['deny_gid'];
|
||||
|
||||
|
||||
$arr['uid'] = $channel['channel_id'];
|
||||
$arr['aid'] = $channel['channel_account_id'];
|
||||
|
||||
|
||||
$arr['owner_xchan'] = $channel['channel_hash'];
|
||||
$arr['author_xchan'] = $channel['channel_hash'];
|
||||
|
||||
|
||||
post_activity_item($arr);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Generate content of profile-photo view
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
|
||||
if(! local_channel()) {
|
||||
notice( t('Permission denied.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$channel = \App::get_channel();
|
||||
|
||||
|
||||
$newuser = false;
|
||||
|
||||
|
||||
if(argc() == 2 && argv(1) === 'new')
|
||||
$newuser = true;
|
||||
|
||||
|
||||
if(argv(1) === 'use') {
|
||||
if (argc() < 3) {
|
||||
notice( t('Permission denied.') . EOL );
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
// check_form_security_token_redirectOnErr('/cover_photo', 'cover_photo');
|
||||
|
||||
|
||||
$resource_id = argv(2);
|
||||
|
||||
|
||||
$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)
|
||||
@@ -372,22 +372,22 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
if($rr['imgscale'] == 7)
|
||||
$havescale = true;
|
||||
}
|
||||
|
||||
|
||||
$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())
|
||||
|
||||
|
||||
);
|
||||
if(! $r) {
|
||||
notice( t('Photo not available.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(intval($r[0]['os_storage']))
|
||||
$data = @file_get_contents(dbunescbin($r[0]['content']));
|
||||
else
|
||||
$data = dbunescbin($r[0]['content']);
|
||||
|
||||
$data = dbunescbin($r[0]['content']);
|
||||
|
||||
$ph = photo_factory($data, $r[0]['mimetype']);
|
||||
$smallest = 0;
|
||||
if($ph->is_valid()) {
|
||||
@@ -396,7 +396,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
dbesc($r[0]['resource_id']),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
|
||||
if($i) {
|
||||
$hash = $i[0]['resource_id'];
|
||||
foreach($i as $ii) {
|
||||
@@ -404,15 +404,15 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->cover_photo_crop_ui_head($a, $ph, $hash, $smallest);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if(! x(\App::$data,'imagecrop')) {
|
||||
|
||||
|
||||
$tpl = get_markup_template('cover_photo.tpl');
|
||||
|
||||
|
||||
$o .= replace_macros($tpl,array(
|
||||
'$user' => \App::$channel['channel_address'],
|
||||
'$info' => t('Your cover photo may be visible to anybody on the internet'),
|
||||
@@ -422,7 +422,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
'$title' => t('Change Cover Photo'),
|
||||
'$submit' => t('Upload'),
|
||||
'$remove' => t('Remove'),
|
||||
'$profiles' => $profiles,
|
||||
'$profiles' => false,
|
||||
'$embedPhotos' => t('Use a photo from your albums'),
|
||||
'$embedPhotosModalTitle' => t('Use a photo from your albums'),
|
||||
'$embedPhotosModalCancel' => t('Cancel'),
|
||||
@@ -434,13 +434,13 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
'$modalerrorlink' => t('Error getting photo link'),
|
||||
'$modalerroralbum' => t('Error getting album'),
|
||||
'$form_security_token' => get_form_security_token("cover_photo"),
|
||||
/// @FIXME - yuk
|
||||
/// @FIXME - yuk
|
||||
'$select' => t('Select existing photo'),
|
||||
|
||||
));
|
||||
|
||||
|
||||
call_hooks('cover_photo_content_end', $o);
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
else {
|
||||
@@ -459,10 +459,8 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
));
|
||||
return $o;
|
||||
}
|
||||
|
||||
return; // NOTREACHED
|
||||
}
|
||||
|
||||
|
||||
/* @brief Generate the UI for photo-cropping
|
||||
*
|
||||
* @param $a Current application
|
||||
@@ -470,30 +468,30 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
function cover_photo_crop_ui_head(&$a, $ph, $hash, $smallest){
|
||||
|
||||
|
||||
$max_length = get_config('system','max_image_length');
|
||||
if(! $max_length)
|
||||
$max_length = MAX_IMAGE_LENGTH;
|
||||
if($max_length > 0)
|
||||
$ph->scaleImage($max_length);
|
||||
|
||||
|
||||
$width = $ph->getWidth();
|
||||
$height = $ph->getHeight();
|
||||
|
||||
|
||||
if($width < 300 || $height < 300) {
|
||||
$ph->scaleImageUp(240);
|
||||
$width = $ph->getWidth();
|
||||
$height = $ph->getHeight();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
\App::$data['imagecrop'] = $hash;
|
||||
\App::$data['imagecrop_resolution'] = $smallest;
|
||||
\App::$page['htmlhead'] .= replace_macros(get_markup_template("crophead.tpl"), array());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ use Zotlabs\Lib\Libsync;
|
||||
|
||||
require_once('include/socgraph.php');
|
||||
require_once('include/selectors.php');
|
||||
require_once('include/group.php');
|
||||
require_once('include/photos.php');
|
||||
|
||||
class Defperms extends Controller {
|
||||
@@ -19,13 +18,13 @@ class Defperms extends Controller {
|
||||
*/
|
||||
|
||||
function init() {
|
||||
|
||||
|
||||
if(! local_channel())
|
||||
return;
|
||||
|
||||
if(! Apps::system_app_installed(local_channel(), 'Default Permissions'))
|
||||
return;
|
||||
|
||||
//if(! Apps::system_app_installed(local_channel(), 'Default Permissions'))
|
||||
// return;
|
||||
|
||||
$r = q("SELECT abook.*, xchan.*
|
||||
FROM abook left join xchan on abook_xchan = xchan_hash
|
||||
WHERE abook_self = 1 and abook_channel = %d LIMIT 1",
|
||||
@@ -37,39 +36,39 @@ class Defperms extends Controller {
|
||||
|
||||
$channel = App::get_channel();
|
||||
if($channel)
|
||||
head_set_icon($channel['xchan_photo_s']);
|
||||
head_set_icon($channel['xchan_photo_s']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* @brief Evaluate posted values and set changes
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
function post() {
|
||||
|
||||
|
||||
if(! local_channel())
|
||||
return;
|
||||
|
||||
if(! Apps::system_app_installed(local_channel(), 'Default Permissions'))
|
||||
return;
|
||||
|
||||
//if(! Apps::system_app_installed(local_channel(), 'Default Permissions'))
|
||||
// return;
|
||||
|
||||
$contact_id = intval(argv(1));
|
||||
if(! $contact_id)
|
||||
return;
|
||||
|
||||
|
||||
$channel = App::get_channel();
|
||||
|
||||
|
||||
$orig_record = q("SELECT * FROM abook WHERE abook_id = %d AND abook_channel = %d LIMIT 1",
|
||||
intval($contact_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
|
||||
if(! $orig_record) {
|
||||
notice( t('Could not access contact record.') . EOL);
|
||||
goaway(z_root() . '/connections');
|
||||
return; // NOTREACHED
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(intval($orig_record[0]['abook_self'])) {
|
||||
$autoperms = intval($_POST['autoperms']);
|
||||
@@ -79,8 +78,8 @@ class Defperms extends Controller {
|
||||
$autoperms = null;
|
||||
$is_self = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
$all_perms = \Zotlabs\Access\Permissions::Perms();
|
||||
|
||||
if($all_perms) {
|
||||
@@ -105,15 +104,15 @@ class Defperms extends Controller {
|
||||
}
|
||||
}
|
||||
|
||||
if(! is_null($autoperms))
|
||||
if(! is_null($autoperms))
|
||||
set_pconfig($channel['channel_id'],'system','autoperms',$autoperms);
|
||||
|
||||
|
||||
|
||||
|
||||
notice( t('Settings updated.') . EOL);
|
||||
|
||||
|
||||
|
||||
// Refresh the structure in memory with the new data
|
||||
|
||||
|
||||
$r = q("SELECT abook.*, xchan.*
|
||||
FROM abook left join xchan on abook_xchan = xchan_hash
|
||||
WHERE abook_channel = %d and abook_id = %d LIMIT 1",
|
||||
@@ -123,28 +122,28 @@ class Defperms extends Controller {
|
||||
if($r) {
|
||||
App::$poi = $r[0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
$this->defperms_clone($a);
|
||||
|
||||
|
||||
goaway(z_root() . '/defperms');
|
||||
|
||||
|
||||
return;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* @brief Clone connection
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
function defperms_clone(&$a) {
|
||||
|
||||
|
||||
if(! App::$poi)
|
||||
return;
|
||||
|
||||
|
||||
$channel = App::get_channel();
|
||||
|
||||
|
||||
$r = q("SELECT abook.*, xchan.*
|
||||
FROM abook left join xchan on abook_xchan = xchan_hash
|
||||
WHERE abook_channel = %d and abook_id = %d LIMIT 1",
|
||||
@@ -154,49 +153,47 @@ class Defperms extends Controller {
|
||||
if($r) {
|
||||
App::$poi = array_shift($r);
|
||||
}
|
||||
|
||||
|
||||
$clone = App::$poi;
|
||||
|
||||
|
||||
unset($clone['abook_id']);
|
||||
unset($clone['abook_account']);
|
||||
unset($clone['abook_channel']);
|
||||
|
||||
|
||||
$abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']);
|
||||
if($abconfig)
|
||||
$clone['abconfig'] = $abconfig;
|
||||
|
||||
|
||||
Libsync::build_sync_packet(0 /* use the current local_channel */, array('abook' => array($clone)));
|
||||
}
|
||||
|
||||
|
||||
/* @brief Generate content of connection default permissions page
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
|
||||
$sort_type = 0;
|
||||
$o = '';
|
||||
|
||||
|
||||
if(! local_channel()) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return login();
|
||||
}
|
||||
|
||||
if(! Apps::system_app_installed(local_channel(), 'Default Permissions')) {
|
||||
//Do not display any associated widgets at this point
|
||||
App::$pdl = '';
|
||||
//~ if(! Apps::system_app_installed(local_channel(), 'Default Permissions')) {
|
||||
//~ //Do not display any associated widgets at this point
|
||||
//~ App::$pdl = '';
|
||||
//~ $papp = Apps::get_papp('Default Permissions');
|
||||
//~ return Apps::app_render($papp, 'module');
|
||||
//~ }
|
||||
|
||||
$o = '<b>' . t('Default Permissions App') . ' (' . t('Not Installed') . '):</b><br>';
|
||||
$o .= t('Set custom default permissions for new connections');
|
||||
return $o;
|
||||
}
|
||||
|
||||
$section = ((array_key_exists('section',$_REQUEST)) ? $_REQUEST['section'] : '');
|
||||
$channel = App::get_channel();
|
||||
|
||||
|
||||
$yes_no = array(t('No'),t('Yes'));
|
||||
|
||||
|
||||
$connect_perms = \Zotlabs\Access\Permissions::connect_perms(local_channel());
|
||||
|
||||
$o .= "<script>function connectDefaultShare() {
|
||||
@@ -210,28 +207,28 @@ class Defperms extends Controller {
|
||||
}
|
||||
}
|
||||
$o .= " }\n</script>\n";
|
||||
|
||||
|
||||
if(App::$poi) {
|
||||
|
||||
|
||||
$sections = [];
|
||||
|
||||
$self = false;
|
||||
|
||||
|
||||
$tpl = get_markup_template('defperms.tpl');
|
||||
|
||||
|
||||
|
||||
|
||||
$perms = array();
|
||||
$channel = App::get_channel();
|
||||
|
||||
$contact = App::$poi;
|
||||
|
||||
|
||||
$global_perms = \Zotlabs\Access\Permissions::Perms();
|
||||
|
||||
$hidden_perms = [];
|
||||
|
||||
|
||||
foreach($global_perms as $k => $v) {
|
||||
$thisperm = get_abconfig(local_channel(),$contact['abook_xchan'],'my_perms',$k);
|
||||
|
||||
|
||||
$checkinherited = \Zotlabs\Access\PermissionLimits::Get(local_channel(),$k);
|
||||
|
||||
$inherited = (($checkinherited & PERMS_SPECIFIC) ? false : true);
|
||||
@@ -241,7 +238,7 @@ class Defperms extends Controller {
|
||||
$hidden_perms[] = [ 'perms_' . $k, intval($thisperm) ];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$pcat = new \Zotlabs\Lib\Permcat(local_channel());
|
||||
$pcatlist = $pcat->listing();
|
||||
$permcats = [];
|
||||
@@ -261,7 +258,6 @@ class Defperms extends Controller {
|
||||
'$sections' => $sections,
|
||||
'$autolbl' => t('The permissions indicated on this page will be applied to all new connections.'),
|
||||
'$autoapprove' => t('Automatic approval settings'),
|
||||
'$unapproved' => $unapproved,
|
||||
'$inherited' => t('inherited'),
|
||||
'$submit' => t('Submit'),
|
||||
'$me' => t('My Settings'),
|
||||
@@ -272,13 +268,13 @@ class Defperms extends Controller {
|
||||
'$contact_id' => $contact['abook_id'],
|
||||
'$name' => $contact['xchan_name'],
|
||||
]);
|
||||
|
||||
|
||||
$arr = array('contact' => $contact,'output' => $o);
|
||||
|
||||
|
||||
call_hooks('contact_edit', $arr);
|
||||
|
||||
|
||||
return $arr['output'];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ use Zotlabs\Lib\Libzotdir;
|
||||
|
||||
|
||||
require_once('include/socgraph.php');
|
||||
require_once('include/dir_fns.php');
|
||||
require_once('include/bbcode.php');
|
||||
require_once('include/html2plain.php');
|
||||
|
||||
@@ -84,7 +83,7 @@ class Directory extends Controller {
|
||||
$globaldir = Libzotdir::get_directory_setting($observer, 'globaldir');
|
||||
|
||||
// override your personal global search pref if we're doing a navbar search of the directory
|
||||
if(intval($_REQUEST['navsearch']))
|
||||
if(isset($_REQUEST['navsearch']) && intval($_REQUEST['navsearch']))
|
||||
$globaldir = 1;
|
||||
|
||||
$safe_mode = Libzotdir::get_directory_setting($observer, 'safemode');
|
||||
@@ -99,15 +98,18 @@ class Directory extends Controller {
|
||||
else
|
||||
$search = ((x($_GET,'search')) ? notags(trim(rawurldecode($_GET['search']))) : '');
|
||||
|
||||
|
||||
$advanced = '';
|
||||
if(strpos($search,'=') && local_channel() && feature_enabled(local_channel(), 'advanced_dirsearch'))
|
||||
$advanced = $search;
|
||||
|
||||
$keywords = (($_GET['keywords']) ? $_GET['keywords'] : '');
|
||||
$keywords = $_GET['keywords'] ?? '';
|
||||
|
||||
// Suggest channels if no search terms or keywords are given
|
||||
$suggest = (local_channel() && x($_REQUEST,'suggest')) ? $_REQUEST['suggest'] : '';
|
||||
|
||||
$addresses = [];
|
||||
$common = [];
|
||||
|
||||
if($suggest) {
|
||||
|
||||
// the directory options have no effect in suggestion mode
|
||||
@@ -124,8 +126,7 @@ class Directory extends Controller {
|
||||
}
|
||||
|
||||
// Remember in which order the suggestions were
|
||||
$addresses = array();
|
||||
$common = array();
|
||||
|
||||
$index = 0;
|
||||
foreach($r as $rr) {
|
||||
$common[$rr['xchan_addr']] = ((intval($rr['total']) > 0) ? intval($rr['total']) - 1 : 0);
|
||||
@@ -133,7 +134,7 @@ class Directory extends Controller {
|
||||
}
|
||||
|
||||
// Build query to get info about suggested people
|
||||
$advanced = '';
|
||||
|
||||
foreach(array_keys($addresses) as $address) {
|
||||
$advanced .= "address=\"$address\" ";
|
||||
}
|
||||
@@ -148,6 +149,8 @@ class Directory extends Controller {
|
||||
|
||||
$directory_admin = false;
|
||||
|
||||
$url = '';
|
||||
|
||||
if(($dirmode == DIRECTORY_MODE_PRIMARY) || ($dirmode == DIRECTORY_MODE_STANDALONE)) {
|
||||
$url = z_root() . '/dirsearch';
|
||||
if (is_site_admin()) {
|
||||
@@ -229,7 +232,7 @@ class Directory extends Controller {
|
||||
$j = json_decode($x['body'],true);
|
||||
if($j) {
|
||||
|
||||
if($j['results']) {
|
||||
if(isset($j['results']) && $j['results']) {
|
||||
|
||||
$results = $j['results'];
|
||||
if($suggest) {
|
||||
@@ -255,40 +258,33 @@ class Directory extends Controller {
|
||||
$connect_link = '';
|
||||
|
||||
$location = '';
|
||||
if(strlen($rr['locale']))
|
||||
if(isset($rr['locale']))
|
||||
$location .= $rr['locale'];
|
||||
if(strlen($rr['region'])) {
|
||||
if(strlen($rr['locale']))
|
||||
if(isset($rr['region'])) {
|
||||
if($location)
|
||||
$location .= ', ';
|
||||
$location .= $rr['region'];
|
||||
}
|
||||
if(strlen($rr['country'])) {
|
||||
if(strlen($location))
|
||||
if(isset($rr['country'])) {
|
||||
if($location)
|
||||
$location .= ', ';
|
||||
$location .= $rr['country'];
|
||||
}
|
||||
|
||||
$age = '';
|
||||
if(strlen($rr['birthday'])) {
|
||||
if(isset($rr['birthday'])) {
|
||||
if(($years = age($rr['birthday'],'UTC','')) > 0)
|
||||
$age = $years;
|
||||
}
|
||||
|
||||
$page_type = '';
|
||||
|
||||
$rating_enabled = get_config('system','rating_enabled');
|
||||
|
||||
if($rr['total_ratings'] && $rating_enabled)
|
||||
$total_ratings = sprintf( tt("%d rating", "%d ratings", $rr['total_ratings']), $rr['total_ratings']);
|
||||
else
|
||||
$total_ratings = '';
|
||||
|
||||
$profile = $rr;
|
||||
|
||||
if ((x($profile,'locale') == 1)
|
||||
|| (x($profile,'region') == 1)
|
||||
|| (x($profile,'postcode') == 1)
|
||||
|| (x($profile,'country') == 1))
|
||||
// if ((x($profile,'locale') == 1)
|
||||
// || (x($profile,'region') == 1)
|
||||
// || (x($profile,'postcode') == 1)
|
||||
// || (x($profile,'country') == 1))
|
||||
|
||||
$gender = ((x($profile,'gender') == 1) ? t('Gender: ') . $profile['gender']: False);
|
||||
|
||||
@@ -313,7 +309,7 @@ class Directory extends Controller {
|
||||
$keywords = str_replace(',',' ', $keywords);
|
||||
$keywords = str_replace(' ',' ', $keywords);
|
||||
$karr = explode(' ', $keywords);
|
||||
|
||||
$marr = [];
|
||||
if($karr) {
|
||||
if(local_channel()) {
|
||||
$r = q("select keywords from profile where uid = %d and is_default = 1 limit 1",
|
||||
@@ -353,9 +349,6 @@ class Directory extends Controller {
|
||||
'location' => $location,
|
||||
'location_label' => t('Location:'),
|
||||
'gender' => $gender,
|
||||
'total_ratings' => $total_ratings,
|
||||
'viewrate' => true,
|
||||
'canrate' => (($rating_enabled && local_channel()) ? true : false),
|
||||
'pdesc' => $pdesc,
|
||||
'pdesc_label' => t('Description:'),
|
||||
'censor' => (($directory_admin) ? 'dircensor/' . $rr['hash'] : ''),
|
||||
@@ -375,9 +368,9 @@ class Directory extends Controller {
|
||||
'keywords' => $out,
|
||||
'ignlink' => $suggest ? z_root() . '/directory?ignore=' . $rr['hash'] : '',
|
||||
'ignore_label' => t('Don\'t suggest'),
|
||||
'common_friends' => (($common[$rr['address']]) ? intval($common[$rr['address']]) : ''),
|
||||
'common_friends' => $common[$rr['address']] ?? '',
|
||||
'common_label' => t('Common connections (estimated):'),
|
||||
'common_count' => intval($common[$rr['address']]),
|
||||
'common_count' => $common[$rr['address']] ?? '',
|
||||
'safe' => $safe_mode
|
||||
);
|
||||
|
||||
@@ -403,14 +396,15 @@ class Directory extends Controller {
|
||||
|
||||
ksort($entries); // Sort array by key so that foreach-constructs work as expected
|
||||
|
||||
if($j['keywords']) {
|
||||
if(isset($j['keywords']) && $j['keywords']) {
|
||||
App::$data['directory_keywords'] = $j['keywords'];
|
||||
}
|
||||
|
||||
logger('mod_directory: entries: ' . print_r($entries,true), LOGGER_DATA);
|
||||
|
||||
$aj = $_REQUEST['aj'] ?? '';
|
||||
|
||||
if($_REQUEST['aj']) {
|
||||
if($aj) {
|
||||
if($entries) {
|
||||
$o = replace_macros(get_markup_template('directajax.tpl'),array(
|
||||
'$entries' => $entries
|
||||
@@ -450,12 +444,12 @@ class Directory extends Controller {
|
||||
|
||||
}
|
||||
else {
|
||||
if($_REQUEST['aj']) {
|
||||
if(isset($_REQUEST['aj']) && $_REQUEST['aj']) {
|
||||
$o = '<div id="content-complete"></div>';
|
||||
echo $o;
|
||||
killme();
|
||||
}
|
||||
if(App::$pager['page'] == 1 && $j['records'] == 0 && strpos($search,'@')) {
|
||||
if(App::$pager['page'] == 1 && (isset($j['records']) && $j['records'] == 0) && strpos($search,'@')) {
|
||||
goaway(z_root() . '/chanview/?f=&address=' . $search);
|
||||
}
|
||||
info( t("No entries (some entries may be hidden).") . EOL);
|
||||
|
||||
@@ -4,52 +4,48 @@ namespace Zotlabs\Module;
|
||||
use App;
|
||||
use Zotlabs\Web\Controller;
|
||||
|
||||
require_once('include/dir_fns.php');
|
||||
|
||||
|
||||
|
||||
class Dirsearch extends Controller {
|
||||
|
||||
function init() {
|
||||
App::set_pager_itemspage(30);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
|
||||
$ret = array('success' => false);
|
||||
|
||||
|
||||
// logger('request: ' . print_r($_REQUEST,true));
|
||||
|
||||
|
||||
|
||||
|
||||
$dirmode = intval(get_config('system','directory_mode'));
|
||||
|
||||
|
||||
if($dirmode == DIRECTORY_MODE_NORMAL) {
|
||||
$ret['message'] = t('This site is not a directory server');
|
||||
json_return_and_die($ret);
|
||||
}
|
||||
|
||||
|
||||
$access_token = $_REQUEST['t'];
|
||||
|
||||
$access_token = $_REQUEST['t'] ?? '';
|
||||
|
||||
$token = get_config('system','realm_token');
|
||||
if($token && $access_token != $token) {
|
||||
$ret['message'] = t('This directory server requires an access token');
|
||||
json_return_and_die($ret);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if(argc() > 1 && argv(1) === 'sites') {
|
||||
$ret = $this->list_public_sites();
|
||||
json_return_and_die($ret);
|
||||
}
|
||||
|
||||
|
||||
$sql_extra = '';
|
||||
|
||||
|
||||
|
||||
|
||||
$tables = array('name','address','locale','region','postcode','country','gender','marital','sexual','keywords');
|
||||
|
||||
if($_REQUEST['query']) {
|
||||
|
||||
if(isset($_REQUEST['query']) && $_REQUEST['query']) {
|
||||
$advanced = $this->dir_parse_query($_REQUEST['query']);
|
||||
if($advanced) {
|
||||
foreach($advanced as $adv) {
|
||||
@@ -64,34 +60,35 @@ class Dirsearch extends Controller {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$hash = ((x($_REQUEST['hash'])) ? $_REQUEST['hash'] : '');
|
||||
|
||||
$name = ((x($_REQUEST,'name')) ? $_REQUEST['name'] : '');
|
||||
$hub = ((x($_REQUEST,'hub')) ? $_REQUEST['hub'] : '');
|
||||
$address = ((x($_REQUEST,'address')) ? $_REQUEST['address'] : '');
|
||||
$locale = ((x($_REQUEST,'locale')) ? $_REQUEST['locale'] : '');
|
||||
$region = ((x($_REQUEST,'region')) ? $_REQUEST['region'] : '');
|
||||
$postcode = ((x($_REQUEST,'postcode')) ? $_REQUEST['postcode'] : '');
|
||||
$country = ((x($_REQUEST,'country')) ? $_REQUEST['country'] : '');
|
||||
$gender = ((x($_REQUEST,'gender')) ? $_REQUEST['gender'] : '');
|
||||
$marital = ((x($_REQUEST,'marital')) ? $_REQUEST['marital'] : '');
|
||||
$sexual = ((x($_REQUEST,'sexual')) ? $_REQUEST['sexual'] : '');
|
||||
$keywords = ((x($_REQUEST,'keywords')) ? $_REQUEST['keywords'] : '');
|
||||
$agege = ((x($_REQUEST,'agege')) ? intval($_REQUEST['agege']) : 0 );
|
||||
$agele = ((x($_REQUEST,'agele')) ? intval($_REQUEST['agele']) : 0 );
|
||||
$kw = ((x($_REQUEST,'kw')) ? intval($_REQUEST['kw']) : 0 );
|
||||
|
||||
$hash = $_REQUEST['hash'] ?? '';
|
||||
|
||||
$name = $_REQUEST['name'] ?? '';
|
||||
$hub = $_REQUEST['hub'] ?? '';
|
||||
$address = $_REQUEST['address'] ?? '';
|
||||
$locale = $_REQUEST['locale'] ?? '';
|
||||
$region = $_REQUEST['region'] ?? '';
|
||||
$postcode = $_REQUEST['postcode'] ?? '';
|
||||
$country = $_REQUEST['country'] ?? '';
|
||||
$gender = $_REQUEST['gender'] ?? '';
|
||||
$marital = $_REQUEST['marital'] ?? '';
|
||||
$sexual = $_REQUEST['sexual'] ?? '';
|
||||
$keywords = $_REQUEST['keywords'] ?? '';
|
||||
$agege = $_REQUEST['agege'] ?? 0;
|
||||
$agele = $_REQUEST['agele'] ?? 0;
|
||||
$kw = $_REQUEST['kw'] ?? 0;
|
||||
|
||||
$forums = ((array_key_exists('pubforums',$_REQUEST)) ? intval($_REQUEST['pubforums']) : 0);
|
||||
|
||||
|
||||
if(get_config('system','disable_directory_keywords'))
|
||||
$kw = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
// by default use a safe search
|
||||
$safe = ((x($_REQUEST,'safe'))); // ? intval($_REQUEST['safe']) : 1 );
|
||||
if ($safe === false)
|
||||
$safe = 1;
|
||||
|
||||
|
||||
if(array_key_exists('sync',$_REQUEST)) {
|
||||
if($_REQUEST['sync'])
|
||||
$sync = datetime_convert('UTC','UTC',$_REQUEST['sync']);
|
||||
@@ -100,7 +97,7 @@ class Dirsearch extends Controller {
|
||||
}
|
||||
else
|
||||
$sync = false;
|
||||
|
||||
|
||||
if(($dirmode == DIRECTORY_MODE_STANDALONE) && (! $hub)) {
|
||||
$hub = \App::get_hostname();
|
||||
}
|
||||
@@ -109,13 +106,13 @@ class Dirsearch extends Controller {
|
||||
$hub_query = " and xchan_hash in (select hubloc_hash from hubloc where hubloc_host = '" . protect_sprintf(dbesc($hub)) . "') ";
|
||||
else
|
||||
$hub_query = '';
|
||||
|
||||
|
||||
$sort_order = ((x($_REQUEST,'order')) ? $_REQUEST['order'] : '');
|
||||
|
||||
|
||||
$joiner = ' OR ';
|
||||
if($_REQUEST['and'])
|
||||
if(isset($_REQUEST['and']) && $_REQUEST['and'])
|
||||
$joiner = ' AND ';
|
||||
|
||||
|
||||
if($name)
|
||||
$sql_extra .= $this->dir_query_build($joiner,'xchan_name',$name);
|
||||
if($address)
|
||||
@@ -136,58 +133,58 @@ class Dirsearch extends Controller {
|
||||
$sql_extra .= $this->dir_query_build($joiner,'xprof_sexual',$sexual);
|
||||
if($keywords)
|
||||
$sql_extra .= $this->dir_query_build($joiner,'xprof_keywords',$keywords);
|
||||
|
||||
|
||||
// we only support an age range currently. You must set both agege
|
||||
// (greater than or equal) and agele (less than or equal)
|
||||
|
||||
|
||||
|
||||
// we only support an age range currently. You must set both agege
|
||||
// (greater than or equal) and agele (less than or equal)
|
||||
|
||||
if($agele && $agege) {
|
||||
$sql_extra .= " $joiner ( xprof_age <= " . intval($agele) . " ";
|
||||
$sql_extra .= " AND xprof_age >= " . intval($agege) . ") ";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if($hash) {
|
||||
$sql_extra = " AND xchan_hash like '" . dbesc($hash) . protect_sprintf('%') . "' ";
|
||||
}
|
||||
|
||||
|
||||
$perpage = (($_REQUEST['n']) ? $_REQUEST['n'] : 60);
|
||||
$page = (($_REQUEST['p']) ? intval($_REQUEST['p'] - 1) : 0);
|
||||
|
||||
|
||||
$perpage = $_REQUEST['n'] ?? 60;
|
||||
$page = ((isset($_REQUEST['p']) && $_REQUEST['p']) ? intval($_REQUEST['p'] - 1) : 0);
|
||||
$startrec = (($page+1) * $perpage) - $perpage;
|
||||
$limit = (($_REQUEST['limit']) ? intval($_REQUEST['limit']) : 0);
|
||||
$return_total = ((x($_REQUEST,'return_total')) ? intval($_REQUEST['return_total']) : 0);
|
||||
|
||||
$limit = $_REQUEST['limit'] ?? 0;
|
||||
$return_total = $_REQUEST['return_total'] ?? 0;
|
||||
|
||||
// mtime is not currently working
|
||||
|
||||
|
||||
$mtime = ((x($_REQUEST,'mtime')) ? datetime_convert('UTC','UTC',$_REQUEST['mtime']) : '');
|
||||
|
||||
// ok a separate tag table won't work.
|
||||
|
||||
// ok a separate tag table won't work.
|
||||
// merge them into xprof
|
||||
|
||||
|
||||
$ret['success'] = true;
|
||||
|
||||
|
||||
// If &limit=n, return at most n entries
|
||||
// If &return_total=1, we count matching entries and return that as 'total_items' for use in pagination.
|
||||
// By default we return one page (default 80 items maximum) and do not count total entries
|
||||
|
||||
|
||||
$logic = ((strlen($sql_extra)) ? 'false' : 'true');
|
||||
|
||||
|
||||
if($hash)
|
||||
$logic = 'true';
|
||||
|
||||
|
||||
if($dirmode == DIRECTORY_MODE_STANDALONE) {
|
||||
$sql_extra .= " and xchan_addr like '%%" . \App::get_hostname() . "' ";
|
||||
}
|
||||
|
||||
|
||||
$safesql = (($safe > 0) ? " and xchan_censored = 0 and xchan_selfcensored = 0 " : '');
|
||||
if($safe < 0)
|
||||
$safesql = " and ( xchan_censored = 1 OR xchan_selfcensored = 1 ) ";
|
||||
|
||||
|
||||
if($forums)
|
||||
$safesql .= " and xchan_pubforum = " . ((intval($forums)) ? '1 ' : '0 ');
|
||||
|
||||
if($limit)
|
||||
|
||||
if($limit)
|
||||
$qlimit = " LIMIT $limit ";
|
||||
else {
|
||||
$qlimit = " LIMIT " . intval($perpage) . " OFFSET " . intval($startrec);
|
||||
@@ -198,27 +195,27 @@ class Dirsearch extends Controller {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if($sort_order == 'normal') {
|
||||
$order = " order by xchan_name asc ";
|
||||
|
||||
// Start the alphabetic search at 'A'
|
||||
|
||||
// Start the alphabetic search at 'A'
|
||||
// This will make a handful of channels whose names begin with
|
||||
// punctuation un-searchable in this mode
|
||||
|
||||
|
||||
$safesql .= " and ascii(substring(xchan_name FROM 1 FOR 1)) > 64 ";
|
||||
}
|
||||
elseif($sort_order == 'reverse')
|
||||
$order = " order by xchan_name desc ";
|
||||
elseif($sort_order == 'reversedate')
|
||||
$order = " order by xchan_name_date asc ";
|
||||
else
|
||||
else
|
||||
$order = " order by xchan_name_date desc ";
|
||||
|
||||
|
||||
|
||||
|
||||
if($sync) {
|
||||
$spkt = array('transactions' => array());
|
||||
$r = q("select * from updates where ud_date >= '%s' and ud_guid != '' order by ud_date desc",
|
||||
$r = q("select * from updates where ud_date >= '%s' and ud_guid != '' and ud_addr != '' order by ud_date desc",
|
||||
dbesc($sync)
|
||||
);
|
||||
if($r) {
|
||||
@@ -228,7 +225,7 @@ class Dirsearch extends Controller {
|
||||
$flags[] = 'deleted';
|
||||
if($rr['ud_flags'] & UPDATE_FLAGS_FORCED)
|
||||
$flags[] = 'forced';
|
||||
|
||||
|
||||
$spkt['transactions'][] = array(
|
||||
'hash' => $rr['ud_hash'],
|
||||
'address' => $rr['ud_addr'],
|
||||
@@ -238,87 +235,48 @@ class Dirsearch extends Controller {
|
||||
);
|
||||
}
|
||||
}
|
||||
$r = q("select * from xlink where xlink_static = 1 and xlink_updated >= '%s' ",
|
||||
dbesc($sync)
|
||||
);
|
||||
if($r) {
|
||||
$spkt['ratings'] = array();
|
||||
foreach($r as $rr) {
|
||||
$spkt['ratings'][] = array(
|
||||
'type' => 'rating',
|
||||
'encoding' => 'zot',
|
||||
'channel' => $rr['xlink_xchan'],
|
||||
'target' => $rr['xlink_link'],
|
||||
'rating' => intval($rr['xlink_rating']),
|
||||
'rating_text' => $rr['xlink_rating_text'],
|
||||
'signature' => $rr['xlink_sig'],
|
||||
'edited' => $rr['xlink_updated']
|
||||
);
|
||||
}
|
||||
}
|
||||
json_return_and_die($spkt);
|
||||
}
|
||||
else {
|
||||
|
||||
$r = q("SELECT xchan.*, xprof.* from xchan left join xprof on xchan_hash = xprof_hash
|
||||
where ( $logic $sql_extra ) $hub_query and xchan_network = 'zot6' and xchan_system = 0 and xchan_hidden = 0 and xchan_orphan = 0 and xchan_deleted = 0
|
||||
$safesql $order $qlimit "
|
||||
|
||||
$r = q("SELECT
|
||||
xchan.xchan_name as name,
|
||||
xchan.xchan_hash as hash,
|
||||
xchan.xchan_censored as censored,
|
||||
xchan.xchan_selfcensored as selfcensored,
|
||||
xchan.xchan_pubforum as public_forum,
|
||||
xchan.xchan_url as url,
|
||||
xchan.xchan_photo_l as photo_l,
|
||||
xchan.xchan_photo_m as photo,
|
||||
xchan.xchan_addr as address,
|
||||
xprof.xprof_desc as description,
|
||||
xprof.xprof_locale as locale,
|
||||
xprof.xprof_region as region,
|
||||
xprof.xprof_postcode as postcode,
|
||||
xprof.xprof_country as country,
|
||||
xprof.xprof_dob as birthday,
|
||||
xprof.xprof_age as age,
|
||||
xprof.xprof_gender as gender,
|
||||
xprof.xprof_marital as marital,
|
||||
xprof.xprof_sexual as sexual,
|
||||
xprof.xprof_about as about,
|
||||
xprof.xprof_homepage as homepage,
|
||||
xprof.xprof_hometown as hometown,
|
||||
xprof.xprof_keywords as keywords
|
||||
from xchan left join xprof on xchan_hash = xprof_hash left join hubloc on hubloc_hash = xchan_hash
|
||||
where hubloc_primary = 1 and hubloc_updated > %s - INTERVAL %s and ( $logic $sql_extra ) $hub_query and xchan_network = 'zot6' and xchan_system = 0 and xchan_hidden = 0 and xchan_orphan = 0 and xchan_deleted = 0
|
||||
$safesql $order $qlimit",
|
||||
db_utcnow(),
|
||||
db_quoteinterval('30 DAY')
|
||||
);
|
||||
|
||||
|
||||
|
||||
$ret['page'] = $page + 1;
|
||||
$ret['records'] = count($r);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if($r) {
|
||||
|
||||
$entries = array();
|
||||
|
||||
foreach($r as $rr) {
|
||||
|
||||
$entry = array();
|
||||
|
||||
$pc = q("select count(xlink_rating) as total_ratings from xlink where xlink_link = '%s' and xlink_rating != 0 and xlink_static = 1 group by xlink_rating",
|
||||
dbesc($rr['xchan_hash'])
|
||||
);
|
||||
|
||||
if($pc)
|
||||
$entry['total_ratings'] = intval($pc[0]['total_ratings']);
|
||||
else
|
||||
$entry['total_ratings'] = 0;
|
||||
|
||||
$entry['name'] = $rr['xchan_name'];
|
||||
$entry['hash'] = $rr['xchan_hash'];
|
||||
$entry['censored'] = $rr['xchan_censored'];
|
||||
$entry['selfcensored'] = $rr['xchan_selfcensored'];
|
||||
$entry['public_forum'] = (intval($rr['xchan_pubforum']) ? true : false);
|
||||
$entry['url'] = $rr['xchan_url'];
|
||||
$entry['photo_l'] = $rr['xchan_photo_l'];
|
||||
$entry['photo'] = $rr['xchan_photo_m'];
|
||||
$entry['address'] = $rr['xchan_addr'];
|
||||
$entry['description'] = $rr['xprof_desc'];
|
||||
$entry['locale'] = $rr['xprof_locale'];
|
||||
$entry['region'] = $rr['xprof_region'];
|
||||
$entry['postcode'] = $rr['xprof_postcode'];
|
||||
$entry['country'] = $rr['xprof_country'];
|
||||
$entry['birthday'] = $rr['xprof_dob'];
|
||||
$entry['age'] = $rr['xprof_age'];
|
||||
$entry['gender'] = $rr['xprof_gender'];
|
||||
$entry['marital'] = $rr['xprof_marital'];
|
||||
$entry['sexual'] = $rr['xprof_sexual'];
|
||||
$entry['about'] = $rr['xprof_about'];
|
||||
$entry['homepage'] = $rr['xprof_homepage'];
|
||||
$entry['hometown'] = $rr['xprof_hometown'];
|
||||
$entry['keywords'] = $rr['xprof_keywords'];
|
||||
|
||||
$entries[] = $entry;
|
||||
|
||||
}
|
||||
|
||||
$ret['results'] = $entries;
|
||||
$ret['results'] = $r;
|
||||
$ret['page'] = $page + 1;
|
||||
$ret['records'] = count($r);
|
||||
|
||||
if($kw) {
|
||||
$k = dir_tagadelic($kw, $hub);
|
||||
if($k) {
|
||||
@@ -328,30 +286,30 @@ class Dirsearch extends Controller {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
json_return_and_die($ret);
|
||||
}
|
||||
|
||||
|
||||
function dir_query_build($joiner,$field,$s) {
|
||||
$ret = '';
|
||||
if(trim($s))
|
||||
$ret .= dbesc($joiner) . " " . dbesc($field) . " like '" . protect_sprintf( '%' . dbesc($s) . '%' ) . "' ";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
function dir_flag_build($joiner,$field,$bit,$s) {
|
||||
return dbesc($joiner) . " ( " . dbesc($field) . " & " . intval($bit) . " ) " . ((intval($s)) ? '>' : '=' ) . " 0 ";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function dir_parse_query($s) {
|
||||
|
||||
|
||||
$ret = array();
|
||||
$curr = array();
|
||||
$all = explode(' ',$s);
|
||||
$quoted_string = false;
|
||||
|
||||
|
||||
if($all) {
|
||||
foreach($all as $q) {
|
||||
if($quoted_string === false) {
|
||||
@@ -382,7 +340,7 @@ class Dirsearch extends Controller {
|
||||
$ret[] = $curr;
|
||||
$curr = array();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$ret[] = $curr;
|
||||
$curr = array();
|
||||
@@ -405,15 +363,15 @@ class Dirsearch extends Controller {
|
||||
logger('dir_parse_query:' . print_r($ret,true),LOGGER_DATA);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function list_public_sites() {
|
||||
|
||||
|
||||
$rand = db_getfunc('rand');
|
||||
$realm = get_directory_realm();
|
||||
if($realm == DIRECTORY_REALM) {
|
||||
@@ -428,16 +386,16 @@ class Dirsearch extends Controller {
|
||||
intval(SITE_TYPE_ZOT)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$ret = array('success' => false);
|
||||
|
||||
|
||||
if($r) {
|
||||
$ret['success'] = true;
|
||||
$ret['sites'] = array();
|
||||
$insecure = array();
|
||||
|
||||
|
||||
foreach($r as $rr) {
|
||||
|
||||
|
||||
if($rr['site_access'] == ACCESS_FREE)
|
||||
$access = 'free';
|
||||
elseif($rr['site_access'] == ACCESS_PAID)
|
||||
@@ -446,14 +404,14 @@ class Dirsearch extends Controller {
|
||||
$access = 'tiered';
|
||||
else
|
||||
$access = 'private';
|
||||
|
||||
|
||||
if($rr['site_register'] == REGISTER_OPEN)
|
||||
$register = 'open';
|
||||
elseif($rr['site_register'] == REGISTER_APPROVE)
|
||||
$register = 'approve';
|
||||
else
|
||||
$register = 'closed';
|
||||
|
||||
|
||||
if(strpos($rr['site_url'],'https://') !== false)
|
||||
$ret['sites'][] = array('url' => $rr['site_url'], 'access' => $access, 'register' => $register, 'sellpage' => $rr['site_sellpage'], 'location' => $rr['site_location'], 'project' => $rr['site_project'], 'version' => $rr['site_version']);
|
||||
else
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use App;
|
||||
|
||||
require_once("include/bbcode.php");
|
||||
require_once('include/security.php');
|
||||
require_once('include/conversation.php');
|
||||
@@ -34,20 +36,31 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
if($_REQUEST['mid'])
|
||||
if(isset($_REQUEST['mid']) && $_REQUEST['mid']) {
|
||||
$item_hash = $_REQUEST['mid'];
|
||||
}
|
||||
|
||||
if(! $item_hash) {
|
||||
\App::$error = 404;
|
||||
$item_hash = unpack_link_id($item_hash);
|
||||
|
||||
if ($item_hash === false) {
|
||||
App::$error = 400;
|
||||
notice(t('Malformed message id.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!$item_hash) {
|
||||
App::$error = 404;
|
||||
notice( t('Item not found.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$observer_is_owner = false;
|
||||
|
||||
$o = '';
|
||||
|
||||
if(local_channel() && (! $update)) {
|
||||
|
||||
$channel = \App::get_channel();
|
||||
$channel = App::get_channel();
|
||||
|
||||
$channel_acl = array(
|
||||
'allow_cid' => $channel['channel_allow_cid'],
|
||||
@@ -61,7 +74,7 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
'allow_location' => ((intval(get_pconfig($channel['channel_id'],'system','use_browser_location'))) ? '1' : ''),
|
||||
'default_location' => $channel['channel_location'],
|
||||
'nickname' => $channel['channel_address'],
|
||||
'lockstate' => (($group || $cid || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
|
||||
'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
|
||||
'acl' => populate_acl($channel_acl,true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
|
||||
'permissions' => $channel_acl,
|
||||
'bang' => '',
|
||||
@@ -76,7 +89,8 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
'reset' => t('Reset form')
|
||||
);
|
||||
|
||||
$o = '<div id="jot-popup">';
|
||||
$o .= '<div id="jot-popup">';
|
||||
$a = '';
|
||||
$o .= status_editor($a,$x,false,'Display');
|
||||
$o .= '</div>';
|
||||
}
|
||||
@@ -92,26 +106,25 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
|
||||
$target_item = null;
|
||||
|
||||
if(strpos($item_hash,'b64.') === 0)
|
||||
$decoded = @base64url_decode(substr($item_hash,4));
|
||||
if($decoded)
|
||||
$item_hash = $decoded;
|
||||
|
||||
$r = q("select id, uid, mid, parent, parent_mid, thr_parent, verb, item_type, item_deleted, author_xchan, item_blocked from item where mid = '%s' limit 1",
|
||||
dbesc($item_hash)
|
||||
);
|
||||
|
||||
if($r) {
|
||||
$target_item = $r[0];
|
||||
if (!$r) {
|
||||
notice( t('Item not found.') . EOL);
|
||||
return '';
|
||||
}
|
||||
|
||||
$target_item = $r[0];
|
||||
|
||||
/* not yet ready for prime time
|
||||
$x = q("select * from xchan where xchan_hash = '%s' limit 1",
|
||||
dbesc($target_item['author_xchan'])
|
||||
);
|
||||
if($x) {
|
||||
// not yet ready for prime time
|
||||
// \App::$poi = $x[0];
|
||||
App::$poi = $x[0];
|
||||
}
|
||||
*/
|
||||
|
||||
//if the item is to be moderated redirect to /moderate
|
||||
if($target_item['item_blocked'] == ITEM_MODERATED) {
|
||||
@@ -137,48 +150,8 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
if($target_item['item_type'] == ITEM_TYPE_ARTICLE) {
|
||||
$x = q("select * from channel where channel_id = %d limit 1",
|
||||
intval($target_item['uid'])
|
||||
);
|
||||
$y = q("select * from iconfig left join item on iconfig.iid = item.id
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'ARTICLE' and item.id = %d limit 1",
|
||||
intval($target_item['uid']),
|
||||
intval($target_item['parent'])
|
||||
);
|
||||
if($x && $y) {
|
||||
goaway(z_root() . '/articles/' . $x[0]['channel_address'] . '/' . $y[0]['v']);
|
||||
}
|
||||
else {
|
||||
notice( t('Page not found.') . EOL);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
if($target_item['item_type'] == ITEM_TYPE_CARD) {
|
||||
|
||||
$x = q("select * from channel where channel_id = %d limit 1",
|
||||
intval($target_item['uid'])
|
||||
);
|
||||
|
||||
$y = q("select * from iconfig left join item on iconfig.iid = item.id
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'CARD' and item.id = %d limit 1",
|
||||
intval($target_item['uid']),
|
||||
intval($target_item['parent'])
|
||||
);
|
||||
|
||||
if($x && $y) {
|
||||
goaway(z_root() . '/cards/' . $x[0]['channel_address'] . '/' . $y[0]['v']);
|
||||
}
|
||||
else {
|
||||
notice( t('Page not found.') . EOL);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
if ($target_item['item_type'] == ITEM_TYPE_CUSTOM) {
|
||||
call_hooks('item_custom_display',$target_item);
|
||||
notice( t('Page not found.') . EOL);
|
||||
return '';
|
||||
}
|
||||
call_hooks('item_custom_display', $target_item);
|
||||
|
||||
$simple_update = '';
|
||||
if($update && $_SESSION['loadtime'])
|
||||
@@ -189,17 +162,15 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
// if the target item is not a post (eg a like) we want to address its thread parent
|
||||
|
||||
//$mid = ((($target_item['verb'] == ACTIVITY_LIKE) || ($target_item['verb'] == ACTIVITY_DISLIKE)) ? $target_item['thr_parent'] : $target_item['mid']);
|
||||
$mid = $target_item['mid'];
|
||||
|
||||
// if we got a decoded hash we must encode it again before handing to javascript
|
||||
if($decoded)
|
||||
$mid = 'b64.' . base64url_encode($mid);
|
||||
$mid = gen_link_id($target_item['mid']);
|
||||
|
||||
$o .= '<div id="live-display"></div>' . "\r\n";
|
||||
$o .= "<script> var profile_uid = " . ((intval(local_channel())) ? local_channel() : (-1))
|
||||
. "; var netargs = '?f='; var profile_page = " . \App::$pager['page'] . "; </script>\r\n";
|
||||
. "; var netargs = '?f='; var profile_page = " . App::$pager['page'] . "; </script>\r\n";
|
||||
|
||||
\App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array(
|
||||
App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array(
|
||||
'$baseurl' => z_root(),
|
||||
'$pgtype' => 'display',
|
||||
'$uid' => '0',
|
||||
@@ -215,7 +186,7 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
'$dm' => '0',
|
||||
'$nouveau' => '0',
|
||||
'$wall' => '0',
|
||||
'$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1),
|
||||
'$page' => ((App::$pager['page'] != 1) ? App::$pager['page'] : 1),
|
||||
'$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0),
|
||||
'$search' => '',
|
||||
'$xchan' => '',
|
||||
@@ -233,7 +204,7 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
head_add_link([
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/json+oembed',
|
||||
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string),
|
||||
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . App::$query_string),
|
||||
'title' => 'oembed'
|
||||
]);
|
||||
|
||||
@@ -262,7 +233,7 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
);
|
||||
}
|
||||
|
||||
if(!$r) {
|
||||
if($r === null) {
|
||||
$r = q("SELECT item.id AS item_id FROM item
|
||||
WHERE ((mid = '%s'
|
||||
AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
|
||||
@@ -299,7 +270,7 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
);
|
||||
}
|
||||
|
||||
if(! $r) {
|
||||
if($r === null) {
|
||||
$r = q("SELECT item.id as item_id from item
|
||||
WHERE ((parent_mid = '%s'
|
||||
AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
|
||||
@@ -337,71 +308,71 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
$items = array();
|
||||
}
|
||||
|
||||
|
||||
switch($module_format) {
|
||||
|
||||
case 'html':
|
||||
case 'html':
|
||||
|
||||
if ($update) {
|
||||
$o .= conversation($items, 'display', $update, 'client');
|
||||
}
|
||||
else {
|
||||
$o .= '<noscript>';
|
||||
if($noscript_content) {
|
||||
$o .= conversation($items, 'display', $update, 'traditional');
|
||||
if ($update) {
|
||||
$o .= conversation($items, 'display', $update, 'client');
|
||||
}
|
||||
else {
|
||||
$o .= '<div class="section-content-warning-wrapper">' . t('You must enable javascript for your browser to be able to view this content.') . '</div>';
|
||||
$o .= '<noscript>';
|
||||
if($noscript_content) {
|
||||
$o .= conversation($items, 'display', $update, 'traditional');
|
||||
}
|
||||
else {
|
||||
$o .= '<div class="section-content-warning-wrapper">' . t('You must enable javascript for your browser to be able to view this content.') . '</div>';
|
||||
}
|
||||
$o .= '</noscript>';
|
||||
|
||||
if (isset($items[0]['title'])) {
|
||||
App::$page['title'] = $items[0]['title'] . ' - ' . App::$page['title'];
|
||||
}
|
||||
|
||||
$o .= conversation($items, 'display', $update, 'client');
|
||||
}
|
||||
$o .= '</noscript>';
|
||||
|
||||
\App::$page['title'] = (($items[0]['title']) ? $items[0]['title'] . " - " . \App::$page['title'] : \App::$page['title']);
|
||||
break;
|
||||
|
||||
$o .= conversation($items, 'display', $update, 'client');
|
||||
}
|
||||
case 'atom':
|
||||
|
||||
break;
|
||||
$atom = replace_macros(get_markup_template('atom_feed.tpl'), array(
|
||||
'$version' => xmlify(\Zotlabs\Lib\System::get_project_version()),
|
||||
'$generator' => xmlify(\Zotlabs\Lib\System::get_platform_name()),
|
||||
'$generator_uri' => 'https://hubzilla.org',
|
||||
'$feed_id' => xmlify(App::$cmd),
|
||||
'$feed_title' => xmlify(t('Article')),
|
||||
'$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now', ATOM_TIME)),
|
||||
'$author' => '',
|
||||
'$owner' => '',
|
||||
'$profile_page' => xmlify(z_root() . '/display/' . gen_link_id($target_item['mid'])),
|
||||
));
|
||||
|
||||
case 'atom':
|
||||
$x = [ 'xml' => $atom, 'channel' => $channel, 'observer_hash' => $observer_hash, 'params' => $params ];
|
||||
call_hooks('atom_feed_top',$x);
|
||||
|
||||
$atom = replace_macros(get_markup_template('atom_feed.tpl'), array(
|
||||
'$version' => xmlify(\Zotlabs\Lib\System::get_project_version()),
|
||||
'$generator' => xmlify(\Zotlabs\Lib\System::get_platform_name()),
|
||||
'$generator_uri' => 'https://hubzilla.org',
|
||||
'$feed_id' => xmlify(\App::$cmd),
|
||||
'$feed_title' => xmlify(t('Article')),
|
||||
'$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now', ATOM_TIME)),
|
||||
'$author' => '',
|
||||
'$owner' => '',
|
||||
'$profile_page' => xmlify(z_root() . '/display/' . $target_item['mid']),
|
||||
));
|
||||
$atom = $x['xml'];
|
||||
|
||||
$x = [ 'xml' => $atom, 'channel' => $channel, 'observer_hash' => $observer_hash, 'params' => $params ];
|
||||
call_hooks('atom_feed_top',$x);
|
||||
|
||||
$atom = $x['xml'];
|
||||
|
||||
// a much simpler interface
|
||||
call_hooks('atom_feed', $atom);
|
||||
// a much simpler interface
|
||||
call_hooks('atom_feed', $atom);
|
||||
|
||||
|
||||
if($items) {
|
||||
$type = 'html';
|
||||
foreach($items as $item) {
|
||||
if($item['item_private'])
|
||||
continue;
|
||||
$atom .= atom_entry($item, $type, null, '', true, '', false);
|
||||
if($items) {
|
||||
$type = 'html';
|
||||
foreach($items as $item) {
|
||||
if($item['item_private'])
|
||||
continue;
|
||||
$atom .= atom_entry($item, $type, null, '', true, '', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
call_hooks('atom_feed_end', $atom);
|
||||
call_hooks('atom_feed_end', $atom);
|
||||
|
||||
$atom .= '</feed>' . "\r\n";
|
||||
|
||||
header('Content-type: application/atom+xml');
|
||||
echo $atom;
|
||||
killme();
|
||||
$atom .= '</feed>' . "\r\n";
|
||||
|
||||
header('Content-type: application/atom+xml');
|
||||
echo $atom;
|
||||
killme();
|
||||
}
|
||||
|
||||
$o .= '<div id="content-complete"></div>';
|
||||
|
||||
@@ -5,33 +5,21 @@ namespace Zotlabs\Module;
|
||||
class Dreport extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
|
||||
if(! local_channel()) {
|
||||
notice( t('Permission denied') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$table = 'item';
|
||||
|
||||
$channel = \App::get_channel();
|
||||
|
||||
$mid = ((argc() > 1) ? argv(1) : '');
|
||||
$encoded_mid = '';
|
||||
|
||||
if(strpos($mid,'b64.') === 0) {
|
||||
$encoded_mid = $mid;
|
||||
$mid = @base64url_decode(substr($mid,4));
|
||||
}
|
||||
$table = 'item';
|
||||
$channel = \App::get_channel();
|
||||
$mid = ((argc() > 1) ? unpack_link_id(argv(1)) : '');
|
||||
|
||||
if($mid === 'push') {
|
||||
$table = 'push';
|
||||
$mid = ((argc() > 2) ? argv(2) : '');
|
||||
$mid = ((argc() > 2) ? unpack_link_id(argv(2)) : '');
|
||||
|
||||
if(strpos($mid,'b64.') === 0) {
|
||||
$encoded_mid = $mid;
|
||||
$mid = @base64url_decode(substr($mid,4));
|
||||
}
|
||||
|
||||
if($mid) {
|
||||
if($mid) {
|
||||
$i = q("select id from item where mid = '%s' and uid = %d and ( author_xchan = '%s' or ( owner_xchan = '%s' and item_wall = 1 )) ",
|
||||
dbesc($mid),
|
||||
intval($channel['channel_id']),
|
||||
@@ -43,23 +31,14 @@ class Dreport extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
sleep(3);
|
||||
goaway(z_root() . '/dreport/' . (($encoded_mid) ? $encoded_mid : $mid));
|
||||
goaway(z_root() . '/dreport/' . gen_link_id($mid));
|
||||
}
|
||||
|
||||
if($mid === 'mail') {
|
||||
$table = 'mail';
|
||||
$mid = ((argc() > 2) ? argv(2) : '');
|
||||
if(strpos($mid,'b64.') === 0)
|
||||
$mid = @base64url_decode(substr($mid,4));
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(! $mid) {
|
||||
notice( t('Invalid message') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
switch($table) {
|
||||
case 'item':
|
||||
$i = q("select id from item where mid = '%s' and ( author_xchan = '%s' or ( owner_xchan = '%s' and item_wall = 1 )) ",
|
||||
@@ -68,39 +47,35 @@ class Dreport extends \Zotlabs\Web\Controller {
|
||||
dbesc($channel['channel_hash'])
|
||||
);
|
||||
break;
|
||||
case 'mail':
|
||||
$i = q("select id from mail where mid = '%s' and from_xchan = '%s'",
|
||||
dbesc($mid),
|
||||
dbesc($channel['channel_hash'])
|
||||
);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(! $i) {
|
||||
notice( t('Permission denied') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$r = q("select * from dreport where (dreport_xchan = '%s' or dreport_xchan = '%s') and dreport_mid = '%s'",
|
||||
|
||||
$r = q("select * from dreport where dreport_xchan = '%s' and (dreport_mid = '%s' or dreport_mid = '%s' or dreport_mid = '%s' or dreport_mid = '%s')",
|
||||
dbesc($channel['channel_hash']),
|
||||
dbesc($channel['channel_portable_id']),
|
||||
dbesc($mid)
|
||||
dbesc($mid),
|
||||
dbesc($mid . '#sync'),
|
||||
dbesc(str_replace('/item/', '/activity/', $mid)),
|
||||
dbesc(str_replace('/item/', '/activity/', $mid) . '#sync')
|
||||
);
|
||||
|
||||
|
||||
if(! $r) {
|
||||
notice( t('no results') . EOL);
|
||||
// return;
|
||||
}
|
||||
|
||||
|
||||
for($x = 0; $x < count($r); $x++ ) {
|
||||
|
||||
|
||||
// This has two purposes: 1. make the delivery report strings translateable, and
|
||||
// 2. assign an ordering to item delivery results so we can group them and provide
|
||||
// a readable report with more interesting events listed toward the top and lesser
|
||||
// interesting items towards the bottom
|
||||
|
||||
|
||||
switch($r[$x]['dreport_result']) {
|
||||
case 'channel sync processed':
|
||||
$r[$x]['gravity'] = 0;
|
||||
@@ -121,6 +96,7 @@ class Dreport extends \Zotlabs\Web\Controller {
|
||||
case 'updated':
|
||||
$r[$x]['gravity'] = 5;
|
||||
$r[$x]['dreport_result'] = t('updated');
|
||||
break;
|
||||
case 'update ignored':
|
||||
$r[$x]['gravity'] = 6;
|
||||
$r[$x]['dreport_result'] = t('update ignored');
|
||||
@@ -132,27 +108,18 @@ class Dreport extends \Zotlabs\Web\Controller {
|
||||
case 'recipient not found':
|
||||
$r[$x]['dreport_result'] = t('recipient not found');
|
||||
break;
|
||||
case 'mail recalled':
|
||||
$r[$x]['dreport_result'] = t('mail recalled');
|
||||
break;
|
||||
case 'duplicate mail received':
|
||||
$r[$x]['dreport_result'] = t('duplicate mail received');
|
||||
break;
|
||||
case 'mail delivered':
|
||||
$r[$x]['dreport_result'] = t('mail delivered');
|
||||
break;
|
||||
default:
|
||||
$r[$x]['gravity'] = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
usort($r,'self::dreport_gravity_sort');
|
||||
|
||||
$entries = array();
|
||||
foreach($r as $rr) {
|
||||
$entries[] = [
|
||||
'name' => escape_tags($rr['dreport_name'] ?: $rr['dreport_recip']),
|
||||
$entries[] = [
|
||||
'name' => escape_tags($rr['dreport_name'] ?: $rr['dreport_recip']),
|
||||
'result' => escape_tags($rr['dreport_result']),
|
||||
'time' => escape_tags(datetime_convert('UTC',date_default_timezone_get(),$rr['dreport_time']))
|
||||
];
|
||||
@@ -167,14 +134,14 @@ class Dreport extends \Zotlabs\Web\Controller {
|
||||
'$push' => t('Redeliver'),
|
||||
'$entries' => $entries
|
||||
));
|
||||
|
||||
|
||||
|
||||
|
||||
return $o;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static function dreport_gravity_sort($a,$b) {
|
||||
if($a['gravity'] == $b['gravity']) {
|
||||
if($a['dreport_name'] === $b['dreport_name'])
|
||||
@@ -183,5 +150,5 @@ class Dreport extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
return (($a['gravity'] > $b['gravity']) ? 1 : (-1));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -57,15 +57,17 @@ class Editpost extends \Zotlabs\Web\Controller {
|
||||
$catsenabled = ((feature_enabled($owner_uid,'categories')) ? 'categories' : '');
|
||||
|
||||
if ($catsenabled){
|
||||
$itm = fetch_post_tags($itm);
|
||||
|
||||
$cats = get_terms_oftype($itm[0]['term'], TERM_CATEGORY);
|
||||
|
||||
foreach ($cats as $cat) {
|
||||
if (strlen($category))
|
||||
$category .= ', ';
|
||||
$category .= $cat['term'];
|
||||
}
|
||||
$itm = fetch_post_tags($itm);
|
||||
if (isset($itm[0]['term'])) {
|
||||
$cats = get_terms_oftype($itm[0]['term'], TERM_CATEGORY);
|
||||
if ($cats) {
|
||||
foreach ($cats as $cat) {
|
||||
if (strlen($category))
|
||||
$category .= ', ';
|
||||
$category .= $cat['term'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($itm[0]['attach']) {
|
||||
@@ -104,6 +106,7 @@ class Editpost extends \Zotlabs\Web\Controller {
|
||||
'bbcode' => true
|
||||
);
|
||||
|
||||
$a = '';
|
||||
$editor = status_editor($a, $x, false, 'Editpost');
|
||||
|
||||
$o .= replace_macros(get_markup_template('edpost_head.tpl'), array(
|
||||
|
||||
@@ -1,750 +0,0 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/bbcode.php');
|
||||
require_once('include/datetime.php');
|
||||
require_once('include/event.php');
|
||||
require_once('include/items.php');
|
||||
require_once('include/html2plain.php');
|
||||
|
||||
class Events extends \Zotlabs\Web\Controller {
|
||||
|
||||
function post() {
|
||||
|
||||
// this module is deprecated
|
||||
return;
|
||||
|
||||
logger('post: ' . print_r($_REQUEST,true), LOGGER_DATA);
|
||||
|
||||
if(! local_channel())
|
||||
return;
|
||||
|
||||
if(($_FILES) && array_key_exists('userfile',$_FILES) && intval($_FILES['userfile']['size'])) {
|
||||
$src = $_FILES['userfile']['tmp_name'];
|
||||
if($src) {
|
||||
$result = parse_ical_file($src,local_channel());
|
||||
if($result)
|
||||
info( t('Calendar entries imported.') . EOL);
|
||||
else
|
||||
notice( t('No calendar entries found.') . EOL);
|
||||
@unlink($src);
|
||||
}
|
||||
goaway(z_root() . '/events');
|
||||
}
|
||||
|
||||
|
||||
$event_id = ((x($_POST,'event_id')) ? intval($_POST['event_id']) : 0);
|
||||
$event_hash = ((x($_POST,'event_hash')) ? $_POST['event_hash'] : '');
|
||||
|
||||
$xchan = ((x($_POST,'xchan')) ? dbesc($_POST['xchan']) : '');
|
||||
$uid = local_channel();
|
||||
|
||||
$start_text = escape_tags($_REQUEST['start_text']);
|
||||
$finish_text = escape_tags($_REQUEST['finish_text']);
|
||||
|
||||
$adjust = intval($_POST['adjust']);
|
||||
$nofinish = intval($_POST['nofinish']);
|
||||
|
||||
$timezone = ((x($_POST,'timezone_select')) ? notags(trim($_POST['timezone_select'])) : '');
|
||||
|
||||
$tz = (($timezone) ? $timezone : date_default_timezone_get());
|
||||
|
||||
$categories = escape_tags(trim($_POST['category']));
|
||||
|
||||
// only allow editing your own events.
|
||||
|
||||
if(($xchan) && ($xchan !== get_observer_hash()))
|
||||
return;
|
||||
|
||||
if($start_text) {
|
||||
$start = $start_text;
|
||||
}
|
||||
else {
|
||||
$start = sprintf('%d-%d-%d %d:%d:0',$startyear,$startmonth,$startday,$starthour,$startminute);
|
||||
}
|
||||
|
||||
|
||||
if($finish_text) {
|
||||
$finish = $finish_text;
|
||||
}
|
||||
else {
|
||||
$finish = sprintf('%d-%d-%d %d:%d:0',$finishyear,$finishmonth,$finishday,$finishhour,$finishminute);
|
||||
}
|
||||
|
||||
if($nofinish) {
|
||||
$finish = NULL_DATE;
|
||||
}
|
||||
|
||||
|
||||
if($adjust) {
|
||||
$start = datetime_convert($tz,'UTC',$start);
|
||||
if(! $nofinish)
|
||||
$finish = datetime_convert($tz,'UTC',$finish);
|
||||
}
|
||||
else {
|
||||
$start = datetime_convert('UTC','UTC',$start);
|
||||
if(! $nofinish)
|
||||
$finish = datetime_convert('UTC','UTC',$finish);
|
||||
}
|
||||
|
||||
// Don't allow the event to finish before it begins.
|
||||
// It won't hurt anything, but somebody will file a bug report
|
||||
// and we'll waste a bunch of time responding to it. Time that
|
||||
// could've been spent doing something else.
|
||||
|
||||
|
||||
$summary = escape_tags(trim($_POST['summary']));
|
||||
$desc = escape_tags(trim($_POST['desc']));
|
||||
$location = escape_tags(trim($_POST['location']));
|
||||
$type = escape_tags(trim($_POST['type']));
|
||||
|
||||
require_once('include/text.php');
|
||||
linkify_tags($desc, local_channel());
|
||||
linkify_tags($location, local_channel());
|
||||
|
||||
//$action = ($event_hash == '') ? 'new' : "event/" . $event_hash;
|
||||
|
||||
//fixme: this url gives a wsod if there is a linebreak detected in one of the variables ($desc or $location)
|
||||
//$onerror_url = z_root() . "/events/" . $action . "?summary=$summary&description=$desc&location=$location&start=$start_text&finish=$finish_text&adjust=$adjust&nofinish=$nofinish&type=$type";
|
||||
$onerror_url = z_root() . "/events";
|
||||
|
||||
if(strcmp($finish,$start) < 0 && !$nofinish) {
|
||||
notice( t('Event can not end before it has started.') . EOL);
|
||||
if(intval($_REQUEST['preview'])) {
|
||||
echo( t('Unable to generate preview.'));
|
||||
killme();
|
||||
}
|
||||
goaway($onerror_url);
|
||||
}
|
||||
|
||||
if((! $summary) || (! $start)) {
|
||||
notice( t('Event title and start time are required.') . EOL);
|
||||
if(intval($_REQUEST['preview'])) {
|
||||
echo( t('Unable to generate preview.'));
|
||||
killme();
|
||||
}
|
||||
goaway($onerror_url);
|
||||
}
|
||||
|
||||
// $share = ((intval($_POST['distr'])) ? intval($_POST['distr']) : 0);
|
||||
|
||||
$share = 1;
|
||||
|
||||
$channel = \App::get_channel();
|
||||
|
||||
$acl = new \Zotlabs\Access\AccessList(false);
|
||||
|
||||
if($event_id) {
|
||||
$x = q("select * from event where id = %d and uid = %d limit 1",
|
||||
intval($event_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
if(! $x) {
|
||||
notice( t('Event not found.') . EOL);
|
||||
if(intval($_REQUEST['preview'])) {
|
||||
echo( t('Unable to generate preview.'));
|
||||
killme();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$acl->set($x[0]);
|
||||
|
||||
$created = $x[0]['created'];
|
||||
$edited = datetime_convert();
|
||||
|
||||
if($x[0]['allow_cid'] === '<' . $channel['channel_hash'] . '>'
|
||||
&& $x[0]['allow_gid'] === '' && $x[0]['deny_cid'] === '' && $x[0]['deny_gid'] === '') {
|
||||
$share = false;
|
||||
}
|
||||
else {
|
||||
$share = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$created = $edited = datetime_convert();
|
||||
if($share) {
|
||||
$acl->set_from_array($_POST);
|
||||
}
|
||||
else {
|
||||
$acl->set(array('allow_cid' => '<' . $channel['channel_hash'] . '>', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => ''));
|
||||
}
|
||||
}
|
||||
|
||||
$post_tags = array();
|
||||
$channel = \App::get_channel();
|
||||
$ac = $acl->get();
|
||||
|
||||
if(strlen($categories)) {
|
||||
$cats = explode(',',$categories);
|
||||
foreach($cats as $cat) {
|
||||
$post_tags[] = array(
|
||||
'uid' => $profile_uid,
|
||||
'ttype' => TERM_CATEGORY,
|
||||
'otype' => TERM_OBJ_POST,
|
||||
'term' => trim($cat),
|
||||
'url' => $channel['xchan_url'] . '?f=&cat=' . urlencode(trim($cat))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$datarray = array();
|
||||
$datarray['dtstart'] = $start;
|
||||
$datarray['dtend'] = $finish;
|
||||
$datarray['summary'] = $summary;
|
||||
$datarray['description'] = $desc;
|
||||
$datarray['location'] = $location;
|
||||
$datarray['etype'] = $type;
|
||||
$datarray['adjust'] = $adjust;
|
||||
$datarray['nofinish'] = $nofinish;
|
||||
$datarray['uid'] = local_channel();
|
||||
$datarray['account'] = get_account_id();
|
||||
$datarray['event_xchan'] = $channel['channel_hash'];
|
||||
$datarray['allow_cid'] = $ac['allow_cid'];
|
||||
$datarray['allow_gid'] = $ac['allow_gid'];
|
||||
$datarray['deny_cid'] = $ac['deny_cid'];
|
||||
$datarray['deny_gid'] = $ac['deny_gid'];
|
||||
$datarray['private'] = (($acl->is_private()) ? 1 : 0);
|
||||
$datarray['id'] = $event_id;
|
||||
$datarray['created'] = $created;
|
||||
$datarray['edited'] = $edited;
|
||||
|
||||
if(intval($_REQUEST['preview'])) {
|
||||
$html = format_event_html($datarray);
|
||||
echo $html;
|
||||
killme();
|
||||
}
|
||||
|
||||
$event = event_store_event($datarray);
|
||||
|
||||
if($post_tags)
|
||||
$datarray['term'] = $post_tags;
|
||||
|
||||
$item_id = event_store_item($datarray,$event);
|
||||
|
||||
if($item_id) {
|
||||
$r = q("select * from item where id = %d",
|
||||
intval($item_id)
|
||||
);
|
||||
if($r) {
|
||||
xchan_query($r);
|
||||
$sync_item = fetch_post_tags($r);
|
||||
$z = q("select * from event where event_hash = '%s' and uid = %d limit 1",
|
||||
dbesc($r[0]['resource_id']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if($z) {
|
||||
build_sync_packet($channel['channel_id'],array('event_item' => array(encode_item($sync_item[0],true)),'event' => $z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($share)
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier','event',$item_id));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
// this module is deprecated
|
||||
return;
|
||||
|
||||
if(argc() > 2 && argv(1) == 'ical') {
|
||||
$event_id = argv(2);
|
||||
|
||||
require_once('include/security.php');
|
||||
$sql_extra = permissions_sql(local_channel());
|
||||
|
||||
$r = q("select * from event where event_hash = '%s' $sql_extra limit 1",
|
||||
dbesc($event_id)
|
||||
);
|
||||
if($r) {
|
||||
header('Content-type: text/calendar');
|
||||
header('content-disposition: attachment; filename="' . t('event') . '-' . $event_id . '.ics"' );
|
||||
echo ical_wrapper($r);
|
||||
killme();
|
||||
}
|
||||
else {
|
||||
notice( t('Event not found.') . EOL );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(! local_channel()) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
\App::$profile_uid = local_channel();
|
||||
nav_set_selected('Events');
|
||||
|
||||
|
||||
if((argc() > 2) && (argv(1) === 'ignore') && intval(argv(2))) {
|
||||
$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 dismissed = 0 where id = %d and uid = %d",
|
||||
intval(argv(2)),
|
||||
intval(local_channel())
|
||||
);
|
||||
}
|
||||
|
||||
$first_day = feature_enabled(local_channel(), 'events_cal_first_day');
|
||||
$first_day = (($first_day) ? $first_day : 0);
|
||||
|
||||
$htpl = get_markup_template('event_head.tpl');
|
||||
\App::$page['htmlhead'] .= replace_macros($htpl,array(
|
||||
'$baseurl' => z_root(),
|
||||
'$module_url' => '/events',
|
||||
'$modparams' => 1,
|
||||
'$lang' => \App::$language,
|
||||
'$first_day' => $first_day
|
||||
));
|
||||
|
||||
$o = '';
|
||||
|
||||
$channel = \App::get_channel();
|
||||
|
||||
$mode = 'view';
|
||||
$y = 0;
|
||||
$m = 0;
|
||||
$ignored = ((x($_REQUEST,'ignored')) ? " and dismissed = " . intval($_REQUEST['ignored']) . " " : '');
|
||||
|
||||
|
||||
// logger('args: ' . print_r(\App::$argv,true));
|
||||
|
||||
|
||||
|
||||
if(argc() > 1) {
|
||||
if(argc() > 2 && argv(1) === 'add') {
|
||||
$mode = 'add';
|
||||
$item_id = intval(argv(2));
|
||||
}
|
||||
if(argc() > 2 && argv(1) === 'drop') {
|
||||
$mode = 'drop';
|
||||
$event_id = argv(2);
|
||||
}
|
||||
if(argc() > 2 && intval(argv(1)) && intval(argv(2))) {
|
||||
$mode = 'view';
|
||||
$y = intval(argv(1));
|
||||
$m = intval(argv(2));
|
||||
}
|
||||
if(argc() <= 2) {
|
||||
$mode = 'view';
|
||||
$event_id = argv(1);
|
||||
}
|
||||
}
|
||||
|
||||
if($mode === 'add') {
|
||||
event_addtocal($item_id,local_channel());
|
||||
killme();
|
||||
}
|
||||
|
||||
if($mode == 'view') {
|
||||
|
||||
/* edit/create form */
|
||||
if($event_id) {
|
||||
$r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1",
|
||||
dbesc($event_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
if(count($r))
|
||||
$orig_event = $r[0];
|
||||
}
|
||||
|
||||
$channel = \App::get_channel();
|
||||
|
||||
// Passed parameters overrides anything found in the DB
|
||||
if(!x($orig_event))
|
||||
$orig_event = array();
|
||||
|
||||
// In case of an error the browser is redirected back here, with these parameters filled in with the previous values
|
||||
/*
|
||||
if(x($_REQUEST,'nofinish')) $orig_event['nofinish'] = $_REQUEST['nofinish'];
|
||||
if(x($_REQUEST,'adjust')) $orig_event['adjust'] = $_REQUEST['adjust'];
|
||||
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['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" ' : '');
|
||||
$a_checked = ((x($orig_event) && $orig_event['adjust']) ? ' checked="checked" ' : '');
|
||||
$t_orig = ((x($orig_event)) ? $orig_event['summary'] : '');
|
||||
$d_orig = ((x($orig_event)) ? $orig_event['description'] : '');
|
||||
$l_orig = ((x($orig_event)) ? $orig_event['location'] : '');
|
||||
$eid = ((x($orig_event)) ? $orig_event['id'] : 0);
|
||||
$event_xchan = ((x($orig_event)) ? $orig_event['event_xchan'] : $channel['channel_hash']);
|
||||
$mid = ((x($orig_event)) ? $orig_event['mid'] : '');
|
||||
|
||||
if(! x($orig_event)) {
|
||||
$sh_checked = '';
|
||||
$a_checked = ' checked="checked" ';
|
||||
}
|
||||
else {
|
||||
$sh_checked = ((($orig_event['allow_cid'] === '<' . $channel['channel_hash'] . '>' || (! $orig_event['allow_cid'])) && (! $orig_event['allow_gid']) && (! $orig_event['deny_cid']) && (! $orig_event['deny_gid'])) ? '' : ' checked="checked" ' );
|
||||
}
|
||||
|
||||
if($orig_event['event_xchan'])
|
||||
$sh_checked .= ' disabled="disabled" ';
|
||||
|
||||
$sdt = ((x($orig_event)) ? $orig_event['dtstart'] : 'now');
|
||||
|
||||
$fdt = ((x($orig_event)) ? $orig_event['dtend'] : '+1 hour');
|
||||
|
||||
$tz = date_default_timezone_get();
|
||||
if(x($orig_event))
|
||||
$tz = (($orig_event['adjust']) ? date_default_timezone_get() : 'UTC');
|
||||
|
||||
$syear = datetime_convert('UTC', $tz, $sdt, 'Y');
|
||||
$smonth = datetime_convert('UTC', $tz, $sdt, 'm');
|
||||
$sday = datetime_convert('UTC', $tz, $sdt, 'd');
|
||||
$shour = datetime_convert('UTC', $tz, $sdt, 'H');
|
||||
$sminute = datetime_convert('UTC', $tz, $sdt, 'i');
|
||||
|
||||
$stext = datetime_convert('UTC',$tz,$sdt);
|
||||
$stext = substr($stext,0,14) . "00:00";
|
||||
|
||||
$fyear = datetime_convert('UTC', $tz, $fdt, 'Y');
|
||||
$fmonth = datetime_convert('UTC', $tz, $fdt, 'm');
|
||||
$fday = datetime_convert('UTC', $tz, $fdt, 'd');
|
||||
$fhour = datetime_convert('UTC', $tz, $fdt, 'H');
|
||||
$fminute = datetime_convert('UTC', $tz, $fdt, 'i');
|
||||
|
||||
$ftext = datetime_convert('UTC',$tz,$fdt);
|
||||
$ftext = substr($ftext,0,14) . "00:00";
|
||||
|
||||
$type = ((x($orig_event)) ? $orig_event['etype'] : 'event');
|
||||
|
||||
$f = get_config('system','event_input_format');
|
||||
if(! $f)
|
||||
$f = 'ymd';
|
||||
|
||||
$catsenabled = feature_enabled(local_channel(),'categories');
|
||||
|
||||
$category = '';
|
||||
|
||||
if($catsenabled && x($orig_event)){
|
||||
$itm = q("select * from item where resource_type = 'event' and resource_id = '%s' and uid = %d limit 1",
|
||||
dbesc($orig_event['event_hash']),
|
||||
intval(local_channel())
|
||||
);
|
||||
$itm = fetch_post_tags($itm);
|
||||
if($itm) {
|
||||
$cats = get_terms_oftype($itm[0]['term'], TERM_CATEGORY);
|
||||
foreach ($cats as $cat) {
|
||||
if(strlen($category))
|
||||
$category .= ', ';
|
||||
$category .= $cat['term'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
require_once('include/acl_selectors.php');
|
||||
|
||||
$acl = new \Zotlabs\Access\AccessList($channel);
|
||||
$perm_defaults = $acl->get();
|
||||
|
||||
$permissions = ((x($orig_event)) ? $orig_event : $perm_defaults);
|
||||
|
||||
$tpl = get_markup_template('event_form.tpl');
|
||||
|
||||
$form = replace_macros($tpl,array(
|
||||
'$post' => z_root() . '/events',
|
||||
'$eid' => $eid,
|
||||
'$type' => $type,
|
||||
'$xchan' => $event_xchan,
|
||||
'$mid' => $mid,
|
||||
'$event_hash' => $event_id,
|
||||
'$summary' => array('summary', (($event_id) ? t('Edit event title') : t('Event title')), $t_orig, t('Required'), '*'),
|
||||
'$catsenabled' => $catsenabled,
|
||||
'$placeholdercategory' => t('Categories (comma-separated list)'),
|
||||
'$c_text' => (($event_id) ? t('Edit Category') : t('Category')),
|
||||
'$category' => $category,
|
||||
'$required' => '<span class="required" title="' . t('Required') . '">*</span>',
|
||||
'$s_dsel' => datetimesel($f,new \DateTime(),\DateTime::createFromFormat('Y',$syear+5),\DateTime::createFromFormat('Y-m-d H:i',"$syear-$smonth-$sday $shour:$sminute"), (($event_id) ? t('Edit start date and time') : t('Start date and time')), 'start_text',true,true,'','',true,$first_day),
|
||||
'$n_text' => t('Finish date and time are not known or not relevant'),
|
||||
'$n_checked' => $n_checked,
|
||||
'$f_dsel' => datetimesel($f,new \DateTime(),\DateTime::createFromFormat('Y',$fyear+5),\DateTime::createFromFormat('Y-m-d H:i',"$fyear-$fmonth-$fday $fhour:$fminute"), (($event_id) ? t('Edit finish date and time') : t('Finish date and time')),'finish_text',true,true,'start_text','',false,$first_day),
|
||||
'$nofinish' => array('nofinish', t('Finish date and time are not known or not relevant'), $n_checked, '', array(t('No'),t('Yes')), 'onclick="enableDisableFinishDate();"'),
|
||||
'$adjust' => array('adjust', t('Adjust for viewer timezone'), $a_checked, t('Important for events that happen in a particular place. Not practical for global holidays.'), array(t('No'),t('Yes'))),
|
||||
'$a_text' => t('Adjust for viewer timezone'),
|
||||
'$d_text' => (($event_id) ? t('Edit Description') : t('Description')),
|
||||
'$d_orig' => $d_orig,
|
||||
'$l_text' => (($event_id) ? t('Edit Location') : t('Location')),
|
||||
'$l_orig' => $l_orig,
|
||||
'$t_orig' => $t_orig,
|
||||
'$preview' => t('Preview'),
|
||||
'$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, \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']),
|
||||
'$tz_choose' => feature_enabled(local_channel(),'event_tz_select'),
|
||||
'$timezone' => array('timezone_select' , t('Timezone:'), date_default_timezone_get(), '', get_timezones()),
|
||||
|
||||
'$lockstate' => (($acl->is_private()) ? 'lock' : 'unlock'),
|
||||
|
||||
'$submit' => t('Submit'),
|
||||
'$advanced' => t('Advanced Options')
|
||||
|
||||
));
|
||||
/* end edit/create form */
|
||||
|
||||
$thisyear = datetime_convert('UTC',date_default_timezone_get(),'now','Y');
|
||||
$thismonth = datetime_convert('UTC',date_default_timezone_get(),'now','m');
|
||||
if(! $y)
|
||||
$y = intval($thisyear);
|
||||
if(! $m)
|
||||
$m = intval($thismonth);
|
||||
|
||||
$export = false;
|
||||
if(argc() === 4 && argv(3) === 'export')
|
||||
$export = true;
|
||||
|
||||
// Put some limits on dates. The PHP date functions don't seem to do so well before 1900.
|
||||
// An upper limit was chosen to keep search engines from exploring links millions of years in the future.
|
||||
|
||||
if($y < 1901)
|
||||
$y = 1900;
|
||||
if($y > 2099)
|
||||
$y = 2100;
|
||||
|
||||
$nextyear = $y;
|
||||
$nextmonth = $m + 1;
|
||||
if($nextmonth > 12) {
|
||||
$nextmonth = 1;
|
||||
$nextyear ++;
|
||||
}
|
||||
|
||||
$prevyear = $y;
|
||||
if($m > 1)
|
||||
$prevmonth = $m - 1;
|
||||
else {
|
||||
$prevmonth = 12;
|
||||
$prevyear --;
|
||||
}
|
||||
|
||||
$dim = get_dim($y,$m);
|
||||
$start = sprintf('%d-%d-%d %d:%d:%d',$y,$m,1,0,0,0);
|
||||
$finish = sprintf('%d-%d-%d %d:%d:%d',$y,$m,$dim,23,59,59);
|
||||
|
||||
|
||||
if (argv(1) === 'json'){
|
||||
if (x($_GET,'start')) $start = $_GET['start'];
|
||||
if (x($_GET,'end')) $finish = $_GET['end'];
|
||||
}
|
||||
|
||||
$start = datetime_convert('UTC','UTC',$start);
|
||||
$finish = datetime_convert('UTC','UTC',$finish);
|
||||
|
||||
$adjust_start = datetime_convert('UTC', date_default_timezone_get(), $start);
|
||||
$adjust_finish = datetime_convert('UTC', date_default_timezone_get(), $finish);
|
||||
|
||||
if (x($_GET,'id')){
|
||||
$r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan
|
||||
from event left join item on resource_id = event_hash where resource_type = 'event' and event.uid = %d and event.id = %d limit 1",
|
||||
intval(local_channel()),
|
||||
intval($_GET['id'])
|
||||
);
|
||||
} elseif($export) {
|
||||
$r = q("SELECT * from event where uid = %d
|
||||
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),
|
||||
dbesc($adjust_start),
|
||||
dbesc($adjust_finish)
|
||||
);
|
||||
}
|
||||
else {
|
||||
// fixed an issue with "nofinish" events not showing up in the calendar.
|
||||
// There's still an issue if the finish date crosses the end of month.
|
||||
// Noting this for now - it will need to be fixed here and in Friendica.
|
||||
// Ultimately the finish date shouldn't be involved in the query.
|
||||
|
||||
$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 and event.uid = item.uid $ignored
|
||||
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),
|
||||
dbesc($adjust_start),
|
||||
dbesc($adjust_finish)
|
||||
);
|
||||
}
|
||||
|
||||
$links = array();
|
||||
|
||||
if($r && ! $export) {
|
||||
xchan_query($r);
|
||||
$r = fetch_post_tags($r,true);
|
||||
|
||||
$r = sort_by_date($r);
|
||||
}
|
||||
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$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;
|
||||
}
|
||||
}
|
||||
|
||||
$events=array();
|
||||
|
||||
$last_date = '';
|
||||
$fmt = t('l, F j');
|
||||
|
||||
if($r) {
|
||||
|
||||
foreach($r as $rr) {
|
||||
|
||||
$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['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['dtend'], 'c') : datetime_convert('UTC','UTC',$rr['dtend'],'c'));
|
||||
|
||||
// give a fake end to birthdays so they get crammed into a
|
||||
// single day on the calendar
|
||||
|
||||
if($rr['etype'] === 'birthday')
|
||||
$end = null;
|
||||
}
|
||||
|
||||
|
||||
$is_first = ($d !== $last_date);
|
||||
|
||||
$last_date = $d;
|
||||
|
||||
$edit = ((local_channel() && $rr['author_xchan'] == get_observer_hash()) ? array(z_root().'/events/'.$rr['event_hash'].'?expandform=1',t('Edit event'),'','') : false);
|
||||
|
||||
$drop = array(z_root().'/events/drop/'.$rr['event_hash'],t('Delete event'),'','');
|
||||
|
||||
$title = strip_tags(html_entity_decode(zidify_links(bbcode($rr['summary'])),ENT_QUOTES,'UTF-8'));
|
||||
if(! $title) {
|
||||
list($title, $_trash) = explode("<br",bbcode($rr['desc']),2);
|
||||
$title = strip_tags(html_entity_decode($title,ENT_QUOTES,'UTF-8'));
|
||||
}
|
||||
$html = format_event_html($rr);
|
||||
$rr['desc'] = zidify_links(smilies(bbcode($rr['desc'])));
|
||||
$rr['description'] = htmlentities(html2plain(bbcode($rr['description'])),ENT_COMPAT,'UTF-8',false);
|
||||
$rr['location'] = zidify_links(smilies(bbcode($rr['location'])));
|
||||
$events[] = array(
|
||||
'id'=>$rr['id'],
|
||||
'hash' => $rr['event_hash'],
|
||||
'start'=> $start,
|
||||
'end' => $end,
|
||||
'drop' => $drop,
|
||||
'allDay' => false,
|
||||
'title' => $title,
|
||||
|
||||
'j' => $j,
|
||||
'd' => $d,
|
||||
'edit' => $edit,
|
||||
'is_first'=>$is_first,
|
||||
'item'=>$rr,
|
||||
'html'=>$html,
|
||||
'plink' => array($rr['plink'],t('Link to Source'),'',''),
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if($export) {
|
||||
header('Content-type: text/calendar');
|
||||
header('content-disposition: attachment; filename="' . t('calendar') . '-' . $channel['channel_address'] . '.ics"' );
|
||||
echo ical_wrapper($r);
|
||||
killme();
|
||||
}
|
||||
|
||||
if (\App::$argv[1] === 'json'){
|
||||
echo json_encode($events); killme();
|
||||
}
|
||||
|
||||
// links: array('href', 'text', 'extra css classes', 'title')
|
||||
if (x($_GET,'id')){
|
||||
$tpl = get_markup_template("event.tpl");
|
||||
}
|
||||
else {
|
||||
$tpl = get_markup_template("events-js.tpl");
|
||||
}
|
||||
|
||||
$o = replace_macros($tpl, array(
|
||||
'$baseurl' => z_root(),
|
||||
'$new_event' => array(z_root().'/events',(($event_id) ? t('Edit Event') : t('Create Event')),'',''),
|
||||
'$previus' => array(z_root()."/events/$prevyear/$prevmonth",t('Previous'),'',''),
|
||||
'$next' => array(z_root()."/events/$nextyear/$nextmonth",t('Next'),'',''),
|
||||
'$export' => array(z_root()."/events/$y/$m/export",t('Export'),'',''),
|
||||
'$calendar' => cal($y,$m,$links, ' eventcal'),
|
||||
'$events' => $events,
|
||||
'$view_label' => t('View'),
|
||||
'$month' => t('Month'),
|
||||
'$week' => t('Week'),
|
||||
'$day' => t('Day'),
|
||||
'$prev' => t('Previous'),
|
||||
'$next' => t('Next'),
|
||||
'$today' => t('Today'),
|
||||
'$form' => $form,
|
||||
'$expandform' => ((x($_GET,'expandform')) ? true : false),
|
||||
));
|
||||
|
||||
if (x($_GET,'id')){ echo $o; killme(); }
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
if($mode === 'drop' && $event_id) {
|
||||
$r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1",
|
||||
dbesc($event_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
$sync_event = $r[0];
|
||||
|
||||
if($r) {
|
||||
$r = q("delete from event where event_hash = '%s' and uid = %d",
|
||||
dbesc($event_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
if($r) {
|
||||
$r = q("update item set resource_type = '', resource_id = '' where resource_type = 'event' and resource_id = '%s' and uid = %d",
|
||||
dbesc($event_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
$sync_event['event_deleted'] = 1;
|
||||
build_sync_packet(0,array('event' => array($sync_event)));
|
||||
|
||||
info( t('Event removed') . EOL);
|
||||
}
|
||||
else {
|
||||
notice( t('Failed to remove event' ) . EOL);
|
||||
}
|
||||
goaway(z_root() . '/events');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,7 +3,6 @@ namespace Zotlabs\Module;
|
||||
|
||||
use Zotlabs\Lib\Libzot;
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/crypto.php');
|
||||
|
||||
/* fix missing or damaged hublocs */
|
||||
@@ -59,44 +58,28 @@ class Fhublocs extends \Zotlabs\Web\Controller {
|
||||
|
||||
// Create a verified hub location pointing to this site.
|
||||
|
||||
/*
|
||||
$h = hubloc_store_lowlevel(
|
||||
[
|
||||
'hubloc_guid' => $rr['channel_guid'],
|
||||
'hubloc_guid_sig' => $rr['channel_guid_sig'],
|
||||
'hubloc_hash' => $rr['channel_hash'],
|
||||
'hubloc_addr' => channel_reddress($rr),
|
||||
'hubloc_network' => 'zot',
|
||||
'hubloc_primary' => $primary,
|
||||
'hubloc_url' => z_root(),
|
||||
'hubloc_url_sig' => base64url_encode(Crypto::sign(z_root(),$rr['channel_prvkey'])),
|
||||
'hubloc_host' => \App::get_hostname(),
|
||||
'hubloc_callback' => z_root() . '/post',
|
||||
'hubloc_sitekey' => $sitekey
|
||||
]
|
||||
);
|
||||
*/
|
||||
$h = hubloc_store_lowlevel(
|
||||
[
|
||||
'hubloc_guid' => $rr['channel_guid'],
|
||||
'hubloc_guid_sig' => $rr['channel_guid_sig'],
|
||||
'hubloc_hash' => $rr['channel_hash'],
|
||||
'hubloc_id_url' => channel_url($rr),
|
||||
'hubloc_addr' => channel_reddress($rr),
|
||||
'hubloc_primary' => intval($primary),
|
||||
'hubloc_url' => z_root(),
|
||||
'hubloc_url_sig' => Libzot::sign(z_root(), $rr['channel_prvkey']),
|
||||
'hubloc_site_id' => Libzot::make_xchan_hash(z_root(), $sitekey),
|
||||
'hubloc_host' => \App::get_hostname(),
|
||||
'hubloc_callback' => z_root() . '/zot',
|
||||
'hubloc_sitekey' => $sitekey,
|
||||
'hubloc_network' => 'zot6',
|
||||
'hubloc_updated' => datetime_convert()
|
||||
'hubloc_guid' => $rr['channel_guid'],
|
||||
'hubloc_guid_sig' => $rr['channel_guid_sig'],
|
||||
'hubloc_hash' => $rr['channel_hash'],
|
||||
'hubloc_id_url' => channel_url($rr),
|
||||
'hubloc_addr' => channel_reddress($rr),
|
||||
'hubloc_primary' => intval($primary),
|
||||
'hubloc_url' => z_root(),
|
||||
'hubloc_url_sig' => Libzot::sign(z_root(), $rr['channel_prvkey']),
|
||||
'hubloc_site_id' => Libzot::make_xchan_hash(z_root(), $sitekey),
|
||||
'hubloc_host' => \App::get_hostname(),
|
||||
'hubloc_callback' => z_root() . '/zot',
|
||||
'hubloc_sitekey' => $sitekey,
|
||||
'hubloc_network' => 'zot6',
|
||||
'hubloc_updated' => datetime_convert(),
|
||||
'hubloc_connected' => datetime_convert()
|
||||
]
|
||||
);
|
||||
|
||||
if($h)
|
||||
$o . 'local hubloc created for ' . $rr['channel_name'] . EOL;
|
||||
$o .= 'local hubloc created for ' . $rr['channel_name'] . EOL;
|
||||
else
|
||||
$o .= 'DB update failed for ' . $rr['channel_name'] . EOL;
|
||||
|
||||
|
||||
@@ -30,12 +30,12 @@ class File_upload extends \Zotlabs\Web\Controller {
|
||||
$_REQUEST['group_deny'] = expand_acl($channel['channel_deny_gid']);
|
||||
}
|
||||
|
||||
$_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']);
|
||||
$_REQUEST['allow_cid'] = ((isset($_REQUEST['contact_allow'])) ? perms2str($_REQUEST['contact_allow']) : '');
|
||||
$_REQUEST['allow_gid'] = ((isset($_REQUEST['group_allow'])) ? perms2str($_REQUEST['group_allow']) : '');
|
||||
$_REQUEST['deny_cid'] = ((isset($_REQUEST['contact_deny'])) ? perms2str($_REQUEST['contact_deny']) : '');
|
||||
$_REQUEST['deny_gid'] = ((isset($_REQUEST['group_deny'])) ? perms2str($_REQUEST['group_deny']) : '');
|
||||
|
||||
if($_REQUEST['filename']) {
|
||||
if(isset($_REQUEST['filename']) && $_REQUEST['filename']) {
|
||||
$r = attach_mkdir($channel, get_observer_hash(), $_REQUEST);
|
||||
if($r['success']) {
|
||||
$hash = $r['data']['hash'];
|
||||
@@ -99,6 +99,9 @@ class File_upload extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
if(is_ajax())
|
||||
killme();
|
||||
|
||||
goaway(z_root() . '/' . $_REQUEST['return_url']);
|
||||
|
||||
}
|
||||
|
||||
@@ -72,8 +72,7 @@ class Follow extends Controller {
|
||||
$uid = local_channel();
|
||||
$url = notags(trim(punify($_REQUEST['url'])));
|
||||
$return_url = $_SESSION['return_url'];
|
||||
$confirm = intval($_REQUEST['confirm']);
|
||||
$interactive = (($_REQUEST['interactive']) ? intval($_REQUEST['interactive']) : 1);
|
||||
$interactive = $_REQUEST['interactive'] ?? 1;
|
||||
$channel = App::get_channel();
|
||||
|
||||
$result = Connect::connect($channel,$url);
|
||||
@@ -108,7 +107,7 @@ class Follow extends Controller {
|
||||
}
|
||||
Libsync::build_sync_packet(0, [ 'abook' => [ $clone ] ], true);
|
||||
|
||||
$can_view_stream = their_perms_contains($channel['channel_id'],$clone['abook_xchan'],'view_stream');
|
||||
$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
|
||||
|
||||
@@ -117,7 +116,7 @@ class Follow extends Controller {
|
||||
}
|
||||
|
||||
if ($interactive) {
|
||||
goaway(z_root() . '/connedit/' . $result['abook']['abook_id'] . '?follow=1');
|
||||
goaway(z_root() . '/connections#' . $result['abook']['abook_id']);
|
||||
}
|
||||
else {
|
||||
json_return_and_die([ 'success' => true ]);
|
||||
|
||||
@@ -5,8 +5,7 @@ use App;
|
||||
use Zotlabs\Web\Controller;
|
||||
use Zotlabs\Lib\Apps;
|
||||
use Zotlabs\Lib\Libsync;
|
||||
|
||||
require_once('include/group.php');
|
||||
use Zotlabs\Lib\AccessList;
|
||||
|
||||
class Group extends Controller {
|
||||
|
||||
@@ -26,7 +25,7 @@ class Group extends Controller {
|
||||
}
|
||||
|
||||
function post() {
|
||||
|
||||
|
||||
if(! local_channel()) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
@@ -35,25 +34,26 @@ class Group extends Controller {
|
||||
if(! Apps::system_app_installed(local_channel(), 'Privacy Groups')) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if((argc() == 2) && (argv(1) === 'new')) {
|
||||
check_form_security_token_redirectOnErr('/group/new', 'group_edit');
|
||||
|
||||
|
||||
$name = notags(trim($_POST['groupname']));
|
||||
$public = intval($_POST['public']);
|
||||
$r = group_add(local_channel(),$name,$public);
|
||||
$r = AccessList::add(local_channel(),$name,$public);
|
||||
$group_hash = $r;
|
||||
|
||||
if($r) {
|
||||
info( t('Privacy group created.') . EOL );
|
||||
}
|
||||
else {
|
||||
notice( t('Could not create privacy group.') . EOL );
|
||||
}
|
||||
goaway(z_root() . '/group');
|
||||
|
||||
}
|
||||
|
||||
if((argc() == 2) && (intval(argv(1)))) {
|
||||
check_form_security_token_redirectOnErr('/group', 'group_edit');
|
||||
|
||||
|
||||
$r = q("SELECT * FROM pgrp WHERE id = %d AND uid = %d LIMIT 1",
|
||||
intval(argv(1)),
|
||||
intval(local_channel())
|
||||
@@ -61,14 +61,15 @@ class Group extends Controller {
|
||||
if(! $r) {
|
||||
notice( t('Privacy group not found.') . EOL );
|
||||
goaway(z_root() . '/connections');
|
||||
|
||||
|
||||
}
|
||||
$group = $r[0];
|
||||
$groupname = notags(trim($_POST['groupname']));
|
||||
$group_hash = $group['hash'];
|
||||
$public = intval($_POST['public']);
|
||||
|
||||
|
||||
$hookinfo = [ 'pgrp_extras' => '', 'group'=>$group['id'] ];
|
||||
call_hooks ('privacygroup_extras_post',$hookinfo);
|
||||
call_hooks('privacygroup_extras_post',$hookinfo);
|
||||
|
||||
if((strlen($groupname)) && (($groupname != $group['gname']) || ($public != $group['visible']))) {
|
||||
$r = q("UPDATE pgrp SET gname = '%s', visible = %d WHERE uid = %d AND id = %d",
|
||||
@@ -79,22 +80,30 @@ class Group extends Controller {
|
||||
);
|
||||
if($r)
|
||||
info( t('Privacy group updated.') . EOL );
|
||||
|
||||
|
||||
Libsync::build_sync_packet(local_channel(),null,true);
|
||||
}
|
||||
|
||||
goaway(z_root() . '/group/' . argv(1) . '/' . argv(2));
|
||||
}
|
||||
return;
|
||||
|
||||
$channel = App::get_channel();
|
||||
|
||||
$default_group = ((isset($_POST['set_default_group'])) ? $group_hash : (($channel['channel_default_group'] === $group_hash) ? '' : $channel['channel_default_group']));
|
||||
$default_acl = ((isset($_POST['set_default_acl'])) ? '<' . $group_hash . '>' : (($channel['channel_allow_gid'] === '<' . $group_hash . '>') ? '' : $channel['channel_allow_gid']));
|
||||
|
||||
q("update channel set channel_default_group = '%s', channel_allow_gid = '%s'
|
||||
where channel_id = %d",
|
||||
dbesc($default_group),
|
||||
dbesc($default_acl),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
Libsync::build_sync_packet(local_channel(),null,true);
|
||||
|
||||
goaway(z_root() . '/group/' . argv(1) . ((argv(2)) ? '/' . argv(2) : ''));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
$change = false;
|
||||
|
||||
logger('mod_group: ' . App::$cmd,LOGGER_DEBUG);
|
||||
|
||||
if(! local_channel()) {
|
||||
notice( t('Permission denied') . EOL);
|
||||
return;
|
||||
@@ -103,12 +112,14 @@ class Group extends Controller {
|
||||
if(! Apps::system_app_installed(local_channel(), 'Privacy Groups')) {
|
||||
//Do not display any associated widgets at this point
|
||||
App::$pdl = '';
|
||||
|
||||
$o = '<b>' . t('Privacy Groups App') . ' (' . t('Not Installed') . '):</b><br>';
|
||||
$o .= t('Management of privacy groups');
|
||||
return $o;
|
||||
$papp = Apps::get_papp('Privacy Groups');
|
||||
return Apps::app_render($papp, 'module');
|
||||
}
|
||||
|
||||
logger('mod_group: ' . App::$cmd,LOGGER_DEBUG);
|
||||
|
||||
$change = false;
|
||||
|
||||
// Switch to text mode interface if we have more than 'n' contacts or group members
|
||||
$switchtotext = get_pconfig(local_channel(),'system','groupedit_image_limit');
|
||||
if($switchtotext === false)
|
||||
@@ -119,64 +130,45 @@ class Group extends Controller {
|
||||
|
||||
if((argc() == 1) || ((argc() == 2) && (argv(1) === 'new'))) {
|
||||
|
||||
$new = (((argc() == 2) && (argv(1) === 'new')) ? true : false);
|
||||
|
||||
$groups = q("SELECT id, gname FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
$i = 0;
|
||||
foreach($groups as $group) {
|
||||
$entries[$i]['name'] = $group['gname'];
|
||||
$entries[$i]['id'] = $group['id'];
|
||||
$entries[$i]['count'] = count(group_get_members($group['id']));
|
||||
$i++;
|
||||
}
|
||||
|
||||
$hookinfo = [ 'pgrp_extras' => '', 'group'=>argv(1) ];
|
||||
call_hooks ('privacygroup_extras',$hookinfo);
|
||||
$pgrp_extras = $hookinfo['pgrp_extras'];
|
||||
|
||||
$is_default_acl = ['set_default_acl', t('Post to this group by default'), 0, '', [t('No'), t('Yes')]];
|
||||
$is_default_group = ['set_default_group', t('Add new contacts to this group by default'), 0, '', [t('No'), t('Yes')]];
|
||||
|
||||
|
||||
$tpl = get_markup_template('privacy_groups.tpl');
|
||||
$o = replace_macros($tpl, [
|
||||
'$title' => t('Privacy Groups'),
|
||||
'$add_new_label' => t('Add Group'),
|
||||
'$new' => $new,
|
||||
|
||||
// new group form
|
||||
'$gname' => array('groupname',t('Privacy group name')),
|
||||
'$public' => array('public',t('Members are visible to other channels'), false),
|
||||
'$public' => array('public',t('Members are visible to other channels'), 0, '', [t('No'), t('Yes')]),
|
||||
'$pgrp_extras' => $pgrp_extras,
|
||||
'$form_security_token' => get_form_security_token("group_edit"),
|
||||
'$submit' => t('Submit'),
|
||||
|
||||
// groups list
|
||||
'$title' => t('Privacy Groups'),
|
||||
'$name_label' => t('Name'),
|
||||
'$count_label' => t('Members'),
|
||||
'$entries' => $entries
|
||||
'$is_default_acl' => $is_default_acl,
|
||||
'$is_default_group' => $is_default_group,
|
||||
]);
|
||||
|
||||
return $o;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
$context = array('$submit' => t('Submit'));
|
||||
$tpl = get_markup_template('group_edit.tpl');
|
||||
|
||||
|
||||
if((argc() == 3) && (argv(1) === 'drop')) {
|
||||
check_form_security_token_redirectOnErr('/group', 'group_drop', 't');
|
||||
|
||||
|
||||
if(intval(argv(2))) {
|
||||
$r = q("SELECT gname FROM pgrp WHERE id = %d AND uid = %d LIMIT 1",
|
||||
intval(argv(2)),
|
||||
intval(local_channel())
|
||||
);
|
||||
if($r)
|
||||
$result = group_rmv(local_channel(),$r[0]['gname']);
|
||||
if($r)
|
||||
$result = AccessList::remove(local_channel(),$r[0]['gname']);
|
||||
if($result) {
|
||||
$hookinfo = [ 'pgrp_extras' => '', 'group' => argv(2) ];
|
||||
call_hooks ('privacygroup_extras_drop',$hookinfo);
|
||||
@@ -188,23 +180,23 @@ class Group extends Controller {
|
||||
goaway(z_root() . '/group');
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if((argc() > 2) && intval(argv(1)) && argv(2)) {
|
||||
|
||||
|
||||
check_form_security_token_ForbiddenOnErr('group_member_change', 't');
|
||||
|
||||
|
||||
$r = q("SELECT abook_xchan from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 limit 1",
|
||||
dbesc(base64url_decode(argv(2))),
|
||||
intval(local_channel())
|
||||
);
|
||||
if(count($r))
|
||||
$change = base64url_decode(argv(2));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if((argc() > 1) && (intval(argv(1)))) {
|
||||
|
||||
|
||||
require_once('include/acl_selectors.php');
|
||||
$r = q("SELECT * FROM pgrp WHERE id = %d AND uid = %d AND deleted = 0 LIMIT 1",
|
||||
intval(argv(1)),
|
||||
@@ -215,28 +207,28 @@ class Group extends Controller {
|
||||
goaway(z_root() . '/connections');
|
||||
}
|
||||
$group = $r[0];
|
||||
|
||||
|
||||
$members = group_get_members($group['id']);
|
||||
|
||||
|
||||
|
||||
$members = AccessList::members(local_channel(), $group['id']);
|
||||
|
||||
$preselected = array();
|
||||
if(count($members)) {
|
||||
foreach($members as $member)
|
||||
if(! in_array($member['xchan_hash'],$preselected))
|
||||
$preselected[] = $member['xchan_hash'];
|
||||
}
|
||||
|
||||
|
||||
if($change) {
|
||||
|
||||
|
||||
if(in_array($change,$preselected)) {
|
||||
group_rmv_member(local_channel(),$group['gname'],$change);
|
||||
AccessList::member_remove(local_channel(),$group['gname'],$change);
|
||||
}
|
||||
else {
|
||||
group_add_member(local_channel(),$group['gname'],$change);
|
||||
AccessList::member_add(local_channel(),$group['gname'],$change);
|
||||
}
|
||||
|
||||
$members = group_get_members($group['id']);
|
||||
|
||||
|
||||
$members = AccessList::members(local_channel(), $group['id']);
|
||||
|
||||
$preselected = array();
|
||||
if(count($members)) {
|
||||
foreach($members as $member)
|
||||
@@ -254,25 +246,25 @@ class Group extends Controller {
|
||||
'$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'], ''),
|
||||
'$public' => array('public',t('Members are visible to other channels'), $group['visible'], '', [t('No'), t('Yes')]),
|
||||
'$form_security_token_edit' => get_form_security_token('group_edit'),
|
||||
'$delete' => t('Delete Group'),
|
||||
'$delete' => t('Delete'),
|
||||
'$form_security_token_drop' => get_form_security_token("group_drop"),
|
||||
'$pgrp_extras' => $pgrp_extras,
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(! isset($group))
|
||||
return;
|
||||
|
||||
|
||||
$groupeditor = array(
|
||||
'label_members' => t('Group members'),
|
||||
'members' => array(),
|
||||
'label_contacts' => t('Not in this group'),
|
||||
'contacts' => array(),
|
||||
);
|
||||
|
||||
|
||||
$sec_token = addslashes(get_form_security_token('group_member_change'));
|
||||
$textmode = (($switchtotext && (count($members) > $switchtotext)) ? true : 'card');
|
||||
foreach($members as $member) {
|
||||
@@ -282,13 +274,13 @@ class Group extends Controller {
|
||||
$groupeditor['members'][] = micropro($member,true,'mpgroup', $textmode);
|
||||
}
|
||||
else
|
||||
group_rmv_member(local_channel(),$group['gname'],$member['xchan_hash']);
|
||||
AccessList::member_remove(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",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
|
||||
if(count($r)) {
|
||||
$textmode = (($switchtotext && (count($r) > $switchtotext)) ? true : 'card');
|
||||
foreach($r as $member) {
|
||||
@@ -299,20 +291,26 @@ class Group extends Controller {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$context['$groupeditor'] = $groupeditor;
|
||||
$context['$desc'] = t('Click a channel to toggle membership');
|
||||
$context['$pgrp_extras'] = $pgrp_extras;
|
||||
|
||||
|
||||
$channel = App::get_channel();
|
||||
|
||||
$context['$is_default_acl'] = ['set_default_acl', t('Post to this group by default'), intval($group['hash'] === trim($channel['channel_allow_gid'], '<>')), '', [t('No'), t('Yes')]];
|
||||
$context['$is_default_group'] = ['set_default_group', t('Add new contacts to this group by default'), intval($group['hash'] === $channel['channel_default_group']), '', [t('No'), t('Yes')]];
|
||||
|
||||
|
||||
if($change) {
|
||||
$tpl = get_markup_template('groupeditor.tpl');
|
||||
echo replace_macros($tpl, $context);
|
||||
killme();
|
||||
}
|
||||
|
||||
|
||||
return replace_macros($tpl, $context);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user