mirror of
https://framagit.org/hubzilla/core.git
synced 2026-06-22 09:17:57 -04:00
Compare commits
774 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 | ||
|
|
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 | ||
|
|
481ecee9e8 |
313
.gitlab-ci.yml
313
.gitlab-ci.yml
@@ -1,147 +1,166 @@
|
||||
# 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
|
||||
|
||||
stages:
|
||||
- test
|
||||
- deploy
|
||||
|
||||
|
||||
# Select what we should cache
|
||||
cache:
|
||||
paths:
|
||||
- vendor/
|
||||
- .cache/
|
||||
|
||||
|
||||
# global variables for all jobs, if no job specific variables
|
||||
variables:
|
||||
# Tell composer to use the project workspace .cache folder
|
||||
COMPOSER_CACHE_DIR: "$CI_PROJECT_DIR/.cache/composer"
|
||||
# Ignore a Composer warning
|
||||
COMPOSER_ALLOW_SUPERUSER: 1
|
||||
# Configure MySQL/MariaDB service (https://hub.docker.com/_/mysql/, https://hub.docker.com/_/mariadb/)
|
||||
MYSQL_DATABASE: hello_world_test
|
||||
MYSQL_ROOT_PASSWORD: mysql
|
||||
# Configure PostgreSQL service (https://hub.docker.com/_/postgres/)
|
||||
POSTGRES_DB: ci-db
|
||||
POSTGRES_USER: ci-user
|
||||
POSTGRES_PASSWORD: ci-pass
|
||||
|
||||
|
||||
before_script:
|
||||
# pecl and composer do not work with PHP production restrictions (from Hubzilla Docker image)
|
||||
- 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
|
||||
- docker-php-ext-enable xdebug
|
||||
# Install composer
|
||||
- curl -sS https://getcomposer.org/installer | php
|
||||
# Install dev libraries from composer
|
||||
- php ./composer.phar install --no-progress
|
||||
# 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
|
||||
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();"
|
||||
# Import hubzilla's DB schema
|
||||
- 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
|
||||
|
||||
# hidden job definition with artifacts config template
|
||||
.artifacts_template:
|
||||
artifacts: &artifacts_template
|
||||
expire_in: 1 week
|
||||
# Gitlab should show the results, but has problems parsing PHPUnit's junit file.
|
||||
reports:
|
||||
junit: tests/results/junit.xml
|
||||
# Archive test results (coverage, testdox, junit)
|
||||
name: "$CI_COMMIT_REF_SLUG-$CI_JOB_NAME"
|
||||
paths:
|
||||
- tests/results/
|
||||
|
||||
|
||||
# PHP7.3 with MySQL 5.7
|
||||
php7.3_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"]
|
||||
|
||||
|
||||
# PHP7.3 with MariaDB 10.2
|
||||
php7.3_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
|
||||
|
||||
|
||||
# PHP7.3 with PostgreSQL latest (11)
|
||||
#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
|
||||
|
||||
|
||||
# Generate Doxygen API Documentation and deploy it as GitLab pages
|
||||
pages:
|
||||
stage: deploy
|
||||
cache: {}
|
||||
image: php:7-cli-alpine
|
||||
before_script:
|
||||
- apk update
|
||||
- apk add doxygen ttf-freefont graphviz
|
||||
script:
|
||||
- doxygen util/Doxyfile
|
||||
- mv doc/html/ public/
|
||||
- echo "API documentation should be accessible at https://hubzilla.frama.io/core/ soon"
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
only:
|
||||
# Only generate it on main repo's master branch
|
||||
- master@hubzilla/core
|
||||
# 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: php:8.0
|
||||
|
||||
stages:
|
||||
- test
|
||||
- deploy
|
||||
|
||||
|
||||
# Select what we should cache
|
||||
cache:
|
||||
paths:
|
||||
- vendor/
|
||||
- .cache/
|
||||
|
||||
|
||||
# global variables for all jobs, if no job specific variables
|
||||
variables:
|
||||
# Tell composer to use the project workspace .cache folder
|
||||
COMPOSER_CACHE_DIR: "$CI_PROJECT_DIR/.cache/composer"
|
||||
# Ignore a Composer warning
|
||||
COMPOSER_ALLOW_SUPERUSER: 1
|
||||
# Configure MySQL/MariaDB service (https://hub.docker.com/_/mysql/, https://hub.docker.com/_/mariadb/)
|
||||
MYSQL_DATABASE: hello_world_test
|
||||
MYSQL_ROOT_PASSWORD: mysql
|
||||
# Configure PostgreSQL service (https://hub.docker.com/_/postgres/)
|
||||
POSTGRES_DB: ci-db
|
||||
POSTGRES_USER: ci-user
|
||||
POSTGRES_PASSWORD: ci-pass
|
||||
|
||||
|
||||
before_script:
|
||||
# pecl and composer do not work with PHP production restrictions (from Hubzilla Docker image)
|
||||
- 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
|
||||
- php ./composer.phar install --no-progress
|
||||
# php.ini settings
|
||||
- echo 'xdebug.mode=coverage' >> /usr/local/etc/php/php.ini
|
||||
|
||||
# hidden job definition with template for PHP
|
||||
.job_template_php: &job_definition_php
|
||||
stage: test
|
||||
script:
|
||||
- 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();"
|
||||
# Import hubzilla's DB schema
|
||||
# - 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
|
||||
|
||||
# hidden job definition with artifacts config template
|
||||
.artifacts_template:
|
||||
artifacts: &artifacts_template
|
||||
expire_in: 1 week
|
||||
# Gitlab should show the results, but has problems parsing PHPUnit's junit file.
|
||||
reports:
|
||||
junit: tests/results/junit.xml
|
||||
# Archive test results (coverage, testdox, junit)
|
||||
name: "$CI_COMMIT_REF_SLUG-$CI_JOB_NAME"
|
||||
paths:
|
||||
- tests/results/
|
||||
|
||||
|
||||
# PHP8.0
|
||||
php8.0:
|
||||
<<: *job_definition_php
|
||||
|
||||
# PHP8.0 with MySQL 5.7
|
||||
#php8.0_mysql5.7:
|
||||
# <<: *job_definition_mysql
|
||||
# services:
|
||||
# - mysql:5.7
|
||||
|
||||
|
||||
# PHP8.0 with MySQL 8 (latest)
|
||||
#php8.0_mysql8:
|
||||
# <<: *job_definition_mysql
|
||||
# services:
|
||||
# - name: mysql:8
|
||||
# command: ["--default-authentication-plugin=mysql_native_password"]
|
||||
|
||||
|
||||
# PHP8.0 with MariaDB 10.2
|
||||
#php8.0_mariadb10.2:
|
||||
# <<: *job_definition_mysql
|
||||
# services:
|
||||
# - name: mariadb:10.2
|
||||
# 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 with PostgreSQL latest (11)
|
||||
#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:8-cli-alpine
|
||||
before_script:
|
||||
- apk update
|
||||
- apk add doxygen ttf-freefont graphviz
|
||||
script:
|
||||
- doxygen util/Doxyfile
|
||||
- mv doc/html/ public/
|
||||
- echo "API documentation should be accessible at https://hubzilla.frama.io/core/ soon"
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
only:
|
||||
# Only generate it on main repo's master branch
|
||||
- master@hubzilla/core
|
||||
|
||||
357
CHANGELOG
357
CHANGELOG
@@ -1,3 +1,360 @@
|
||||
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
|
||||
|
||||
19
SBOM.md
19
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.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|5.0.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|
|
||||
|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.1.3.0|MIT|https://github.com/ramsey/collection.git|
|
||||
|ramsey/uuid|4.1.1.0|MIT|https://github.com/ramsey/uuid.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|
|
||||
@@ -25,7 +26,11 @@
|
||||
|simplepie/simplepie|1.5.6.0|BSD-3-Clause|https://github.com/simplepie/simplepie.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|
|
||||
|twbs/bootstrap|4.6.0.0|MIT|https://github.com/twbs/bootstrap.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|
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,9 +67,9 @@ class Permissions {
|
||||
'post_comments' => t('Can comment on or like my posts'),
|
||||
'post_mail' => t('Can send me direct messages'),
|
||||
'post_like' => t('Can like/dislike profiles and profile things'),
|
||||
'tag_deliver' => t('Can forward direct messages to all my channel connections (forum)'),
|
||||
'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'));
|
||||
|
||||
/**
|
||||
@@ -206,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;
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -93,8 +94,8 @@ class Directory {
|
||||
}
|
||||
|
||||
// Now update all the connections
|
||||
if ($pushall)
|
||||
if ($pushall) {
|
||||
Master::Summon(array('Notifier', 'refresh_all', $channel['channel_id']));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Zotlabs\Daemon;
|
||||
use Zotlabs\Lib\Libzot;
|
||||
use Zotlabs\Lib\Activity;
|
||||
use Zotlabs\Lib\Queue;
|
||||
use Zotlabs\Lib\LDSignatures;
|
||||
|
||||
require_once('include/html2plain.php');
|
||||
require_once('include/conversation.php');
|
||||
@@ -78,6 +79,10 @@ class Notifier {
|
||||
static public $encoded_item = null;
|
||||
static public $channel = null;
|
||||
static public $private = false;
|
||||
// $fragment can contain additional info to omit de-duplication in the queueworker.
|
||||
// E.g. if an item is updated many times in a row from different sources (multiple vote updates) the
|
||||
// update source mid or a timestamp or random string can be added.
|
||||
static public $fragment = null;
|
||||
|
||||
static public function run($argc, $argv) {
|
||||
|
||||
@@ -88,14 +93,12 @@ class Notifier {
|
||||
logger('notifier: invoked: ' . print_r($argv, true), LOGGER_DEBUG);
|
||||
|
||||
$cmd = $argv[1];
|
||||
|
||||
$item_id = $argv[2];
|
||||
|
||||
if (!$item_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
self::$deliveries = [];
|
||||
self::$recipients = [];
|
||||
self::$env_recips = [];
|
||||
@@ -104,9 +107,16 @@ class Notifier {
|
||||
self::$encoded_item = null;
|
||||
self::$channel = null;
|
||||
self::$private = false;
|
||||
self::$fragment = null;
|
||||
|
||||
$sys = get_sys_channel();
|
||||
$normal_mode = true;
|
||||
$upstream = false;
|
||||
$uplink = false;
|
||||
$target_item = null;
|
||||
$parent_item = null;
|
||||
$top_level_post = false;
|
||||
$relay_to_owner = false;
|
||||
|
||||
if ($cmd === 'keychange') {
|
||||
self::$channel = channelx_by_n($item_id);
|
||||
@@ -170,7 +180,7 @@ class Notifier {
|
||||
elseif ($cmd === 'refresh_all') {
|
||||
logger('notifier: refresh_all: ' . $item_id);
|
||||
|
||||
self::$channel = channelx_by_n($item_id);
|
||||
self::$channel = channelx_by_n($item_id, true);
|
||||
|
||||
$r = q("select abook_xchan from abook where abook_channel = %d",
|
||||
intval($item_id)
|
||||
@@ -180,6 +190,11 @@ class Notifier {
|
||||
self::$recipients[] = $rr['abook_xchan'];
|
||||
}
|
||||
}
|
||||
|
||||
// In case we deleted the channel, our abook entry has already vanished.
|
||||
// In order to be able to update our clones we need to add ourself here.
|
||||
self::$recipients[] = self::$channel['channel_hash'];
|
||||
|
||||
self::$private = false;
|
||||
self::$packet_type = 'refresh';
|
||||
}
|
||||
@@ -190,14 +205,14 @@ class Notifier {
|
||||
return;
|
||||
}
|
||||
|
||||
self::$channel = channelx_by_n($item_id);
|
||||
self::$channel = channelx_by_n($item_id, true);
|
||||
self::$recipients = [$xchan];
|
||||
self::$private = true;
|
||||
self::$packet_type = 'purge';
|
||||
}
|
||||
elseif ($cmd === 'purge_all') {
|
||||
logger('notifier: purge_all: ' . $item_id);
|
||||
self::$channel = channelx_by_n($item_id);
|
||||
self::$channel = channelx_by_n($item_id, true);
|
||||
self::$recipients = [];
|
||||
self::$private = false;
|
||||
self::$packet_type = 'purge';
|
||||
@@ -218,6 +233,8 @@ class Notifier {
|
||||
|
||||
// Fetch the target item
|
||||
|
||||
self::$fragment = $argv[3] ?? '';
|
||||
|
||||
$r = q("SELECT * FROM item WHERE id = %d AND parent != 0",
|
||||
intval($item_id)
|
||||
);
|
||||
@@ -230,7 +247,7 @@ class Notifier {
|
||||
|
||||
$target_item = $r[0];
|
||||
|
||||
if (in_array($target_item['author']['xchan_network'], ['rss', 'anon'])) {
|
||||
if (in_array($target_item['author']['xchan_network'], ['rss', 'anon', 'token'])) {
|
||||
logger('notifier: target item author is not a fetchable actor', LOGGER_DEBUG);
|
||||
return;
|
||||
}
|
||||
@@ -326,12 +343,14 @@ class Notifier {
|
||||
self::$encoded_item = json_decode($m, true);
|
||||
}
|
||||
else {
|
||||
|
||||
self::$encoded_item = array_merge(['@context' => [
|
||||
ACTIVITYSTREAMS_JSONLD_REV,
|
||||
'https://w3id.org/security/v1',
|
||||
z_root() . ZOT_APSCHEMA_REV
|
||||
]], Activity::encode_activity($target_item)
|
||||
);
|
||||
self::$encoded_item['signature'] = LDSignatures::sign(self::$encoded_item, self::$channel);
|
||||
}
|
||||
|
||||
logger('target_item: ' . print_r($target_item, true), LOGGER_DEBUG);
|
||||
@@ -347,8 +366,6 @@ class Notifier {
|
||||
// the hostname in the message_id and provides a second (fallback) opinion.
|
||||
|
||||
$relay_to_owner = (!$top_level_post && intval($target_item['item_origin']) && comment_local_origin($target_item));
|
||||
$uplink = false;
|
||||
$upstream = false;
|
||||
|
||||
// $cmd === 'relay' indicates the owner is sending it to the original recipients
|
||||
// don't allow the item in the relay command to relay to owner under any circumstances, it will loop
|
||||
@@ -443,7 +460,6 @@ class Notifier {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$narr = [
|
||||
'channel' => self::$channel,
|
||||
'upstream' => $upstream,
|
||||
@@ -485,7 +501,7 @@ class Notifier {
|
||||
// Now we have collected recipients (except for external mentions, FIXME)
|
||||
// Let's reduce this to a set of hubs; checking that the site is not dead.
|
||||
|
||||
$hubs = q("select hubloc.*, site.site_crypto, site.site_flags, site.site_dead from hubloc left join site on site_url = hubloc_url
|
||||
$hubs = dbq("select hubloc.*, site.site_crypto, site.site_flags, site.site_dead from hubloc left join site on site_url = hubloc_url
|
||||
where hubloc_hash in (" . protect_sprintf(implode(',', self::$recipients)) . ")
|
||||
and hubloc_error = 0 and hubloc_deleted = 0"
|
||||
);
|
||||
@@ -526,16 +542,18 @@ class Notifier {
|
||||
*/
|
||||
|
||||
|
||||
$hublist = []; // this provides an easily printable list for the logs
|
||||
$dhubs = []; // delivery hubs where we store our resulting unique array
|
||||
$keys = []; // array of keys to check uniquness for zot hubs
|
||||
$urls = []; // array of urls to check uniqueness of hubs from other networks
|
||||
$hub_env = []; // per-hub envelope so we don't broadcast the entire envelope to all
|
||||
$dead = []; // known dead hubs - report them as undeliverable
|
||||
$hublist = []; // this provides an easily printable list for the logs
|
||||
$dhubs = []; // delivery hubs where we store our resulting unique array
|
||||
$keys = []; // array of keys to check uniquness for zot hubs
|
||||
$urls = []; // array of urls to check uniqueness of hubs from other networks
|
||||
$hub_env = []; // per-hub envelope so we don't broadcast the entire envelope to all
|
||||
$dead_hosts = []; // known dead hubs - report them as undeliverable
|
||||
|
||||
foreach ($hubs as $hub) {
|
||||
if (isset($hub['site_dead']) && intval($hub['site_dead'])) {
|
||||
$dead[] = $hub;
|
||||
if(!in_array($hub['hubloc_host'], $dead_hosts)) {
|
||||
$dead_hosts[] = $hub['hubloc_host'];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -545,7 +563,9 @@ class Notifier {
|
||||
if (!array_key_exists($hub['hubloc_site_id'], $hub_env)) {
|
||||
$hub_env[$hub['hubloc_site_id']] = [];
|
||||
}
|
||||
$hub_env[$hub['hubloc_site_id']][] = $er;
|
||||
if (!in_array($er, $hub_env[$hub['hubloc_site_id']])) {
|
||||
$hub_env[$hub['hubloc_site_id']][] = $er;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -623,9 +643,22 @@ class Notifier {
|
||||
|
||||
// default: zot protocol
|
||||
|
||||
// Prevent zot6 delivery of group comment boosts, which are not required for conversational platforms.
|
||||
// ActivityPub conversational platforms may wish to filter these if they don't want or require them.
|
||||
// We will assume here that if $target_item exists and has a verb that it is an actual item structure
|
||||
// so we won't need to check the existence of the other item fields prior to evaluation.
|
||||
|
||||
// This shouldn't produce false positives on comment boosts that were generated on other platforms
|
||||
// because we won't be delivering them.
|
||||
|
||||
if (isset($target_item['verb']) && $target_item['verb'] === 'Announce' && $target_item['author_xchan'] === $target_item['owner_xchan'] && ! intval($target_item['item_thread_top'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$hash = new_uuid();
|
||||
|
||||
$env = (($hub_env && $hub_env[$hub['hubloc_site_id']]) ? $hub_env[$hub['hubloc_site_id']] : '');
|
||||
$env = $hub_env[$hub['hubloc_site_id']] ?? '';
|
||||
|
||||
if ((self::$private) && (!$env)) {
|
||||
continue;
|
||||
}
|
||||
@@ -662,11 +695,11 @@ class Notifier {
|
||||
|
||||
}
|
||||
|
||||
if ($normal_mode) {
|
||||
if ($normal_mode && is_array($target_item)) {
|
||||
// This wastes a process if there are no delivery hooks configured, so check this before launching the new process
|
||||
$x = q("select * from hook where hook = 'notifier_normal'");
|
||||
if ($x) {
|
||||
Master::Summon(['Deliver_hooks', $target_item['id']]);
|
||||
Master::Summon(['Deliver_hooks', $target_item['id'], self::$fragment]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -674,21 +707,19 @@ class Notifier {
|
||||
do_delivery(self::$deliveries);
|
||||
}
|
||||
|
||||
if ($dead) {
|
||||
foreach ($dead as $deceased) {
|
||||
if (is_array($target_item) && (!$target_item['item_deleted']) && (!get_config('system', 'disable_dreport'))) {
|
||||
q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_name, dreport_result, dreport_time, dreport_xchan, dreport_queue )
|
||||
values ( '%s', '%s','%s','%s','%s','%s','%s','%s' ) ",
|
||||
dbesc($target_item['mid']),
|
||||
dbesc($deceased['hubloc_host']),
|
||||
dbesc($deceased['hubloc_host']),
|
||||
dbesc($deceased['hubloc_host']),
|
||||
dbesc('undeliverable/unresponsive site'),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(self::$channel['channel_hash']),
|
||||
dbesc(new_uuid())
|
||||
);
|
||||
}
|
||||
if ($dead_hosts && is_array($target_item) && (!$target_item['item_deleted']) && (!get_config('system', 'disable_dreport'))) {
|
||||
foreach ($dead_hosts as $deceased_host) {
|
||||
$r = q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_name, dreport_result, dreport_time, dreport_xchan, dreport_queue )
|
||||
values ( '%s', '%s','%s','%s','%s','%s','%s','%s' ) ",
|
||||
dbesc($target_item['mid']),
|
||||
dbesc($deceased_host),
|
||||
dbesc($deceased_host),
|
||||
dbesc($deceased_host),
|
||||
dbesc('undeliverable/unresponsive site'),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(self::$channel['channel_hash']),
|
||||
dbesc(new_uuid())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,18 +46,15 @@ class Onepoll {
|
||||
}
|
||||
|
||||
$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')
|
||||
@@ -135,19 +132,34 @@ class Onepoll {
|
||||
$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);
|
||||
|
||||
@@ -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,20 +308,25 @@ class ActivityStreams {
|
||||
|
||||
function get_actor($property, $base = '', $namespace = '') {
|
||||
$x = $this->get_property_obj($property, $base, $namespace);
|
||||
|
||||
if ($this->is_url($x)) {
|
||||
$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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -343,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'];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -417,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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Lib\Libsync;
|
||||
|
||||
require_once('include/plugin.php');
|
||||
require_once('include/channel.php');
|
||||
@@ -22,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'))
|
||||
@@ -34,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;
|
||||
}
|
||||
@@ -46,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;
|
||||
@@ -67,17 +67,15 @@ 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'
|
||||
]);
|
||||
@@ -161,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']);
|
||||
}
|
||||
@@ -210,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 = [];
|
||||
|
||||
@@ -237,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) {
|
||||
@@ -258,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));
|
||||
@@ -310,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -343,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'),
|
||||
@@ -374,10 +376,10 @@ 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'),
|
||||
'Channel Export' => t('Channel Export')
|
||||
);
|
||||
|
||||
if(array_key_exists('name',$arr)) {
|
||||
@@ -425,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);
|
||||
@@ -520,8 +522,13 @@ 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() . '/';
|
||||
}
|
||||
@@ -594,12 +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),
|
||||
'$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'),
|
||||
@@ -624,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",
|
||||
@@ -635,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]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -670,6 +678,7 @@ class Apps {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -681,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)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -729,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)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1186,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'])
|
||||
@@ -1194,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1284,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) {
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -122,12 +122,15 @@ class Enotify {
|
||||
// e.g. "your post", "David's photo", etc.
|
||||
$possess_desc = t('%s <!item_type!>');
|
||||
|
||||
$parent_mid = '';
|
||||
$parent_item = [];
|
||||
|
||||
// @@TODO: consider using switch instead of those elseif
|
||||
if ($params['type'] == NOTIFY_MAIL) {
|
||||
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);
|
||||
$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']));
|
||||
@@ -135,7 +138,7 @@ class Enotify {
|
||||
$itemlink = $siteurl . '/hq/' . gen_link_id($params['item']['mid']);
|
||||
}
|
||||
|
||||
elseif ($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);
|
||||
@@ -167,7 +170,7 @@ 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
|
||||
@@ -238,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.');
|
||||
@@ -251,20 +254,20 @@ class Enotify {
|
||||
|
||||
}
|
||||
|
||||
elseif ($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
|
||||
@@ -291,22 +294,29 @@ class Enotify {
|
||||
);
|
||||
}
|
||||
|
||||
if (!$p) {
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
|
||||
xchan_query($p);
|
||||
|
||||
//@@FIXME $p can be null (line 285)
|
||||
$item_post_type = item_post_type($p[0]);
|
||||
// $private = $p[0]['item_private'];
|
||||
$parent_id = $p[0]['id'];
|
||||
|
||||
$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]'),
|
||||
$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 {
|
||||
|
||||
|
||||
|
||||
elseif($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,7 +353,7 @@ class Enotify {
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
elseif ($params['type'] === NOTIFY_TAGSELF) {
|
||||
elseif (isset($params['type']) && $params['type'] === NOTIFY_TAGSELF) {
|
||||
|
||||
$p = q("select id from notify where link = '%s' and uid = %d limit 1",
|
||||
dbesc($params['link']),
|
||||
@@ -367,7 +377,7 @@ class Enotify {
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
elseif ($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].') ,
|
||||
@@ -384,7 +394,7 @@ class Enotify {
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
elseif ($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]') ,
|
||||
@@ -397,7 +407,7 @@ class Enotify {
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
elseif ($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.'),
|
||||
@@ -411,7 +421,7 @@ class Enotify {
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
elseif ($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.'),
|
||||
@@ -429,11 +439,11 @@ class Enotify {
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
elseif ($params['type'] === NOTIFY_CONFIRM) {
|
||||
elseif (isset($params['type']) && $params['type'] === NOTIFY_CONFIRM) {
|
||||
// ?
|
||||
}
|
||||
|
||||
elseif ($params['type'] === NOTIFY_SYSTEM) {
|
||||
elseif (isset($params['type']) && $params['type'] === NOTIFY_SYSTEM) {
|
||||
// ?
|
||||
}
|
||||
|
||||
@@ -488,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);
|
||||
|
||||
@@ -504,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,7 +524,7 @@ class Enotify {
|
||||
|
||||
if (!$always_show_in_notices) {
|
||||
if (($params['type'] === NOTIFY_WALL) || ($params['type'] === NOTIFY_MAIL) || ($params['type'] === NOTIFY_INTRO)) {
|
||||
$seen = 1;
|
||||
$datarray['seen'] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -530,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'])
|
||||
@@ -606,8 +616,8 @@ class Enotify {
|
||||
$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'];
|
||||
@@ -674,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'],
|
||||
@@ -696,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'],
|
||||
@@ -808,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 {
|
||||
@@ -824,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');
|
||||
}
|
||||
@@ -845,11 +861,15 @@ 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'])),
|
||||
@@ -858,7 +878,7 @@ class Enotify {
|
||||
//'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'], ['drop_media', true]), 75, true), ENT_QUOTES, 'UTF-8', false),
|
||||
'body' => $body,
|
||||
// these are for the superblock addon
|
||||
'hash' => $item[$who]['xchan_hash'],
|
||||
'uid' => $item['uid'],
|
||||
@@ -902,7 +922,7 @@ class Enotify {
|
||||
static public function format_intros($rr) {
|
||||
|
||||
return [
|
||||
'notify_link' => z_root() . '/connections/ifpending',
|
||||
'notify_link' => z_root() . '/connections#' . $rr['abook_id'],
|
||||
'name' => $rr['xchan_name'],
|
||||
'addr' => $rr['xchan_addr'],
|
||||
'url' => $rr['xchan_url'],
|
||||
|
||||
@@ -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,8 +286,8 @@ class Libsync {
|
||||
if (array_key_exists('chatroom', $arr) && $arr['chatroom'])
|
||||
sync_chatrooms($channel, $arr['chatroom']);
|
||||
|
||||
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']);
|
||||
@@ -264,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']);
|
||||
@@ -382,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)) {
|
||||
@@ -408,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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -681,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) . '>');
|
||||
|
||||
@@ -703,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']);
|
||||
@@ -757,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']),
|
||||
@@ -773,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
|
||||
|
||||
@@ -861,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=';
|
||||
|
||||
@@ -453,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'])) {
|
||||
|
||||
@@ -2,85 +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');
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
@@ -88,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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -110,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 )
|
||||
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;
|
||||
|
||||
@@ -195,14 +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_network = 'zot6' ORDER BY hubloc_id DESC LIMIT 1",
|
||||
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) {
|
||||
|
||||
@@ -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"),
|
||||
@@ -303,7 +297,7 @@ class ThreadItem {
|
||||
}
|
||||
|
||||
$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;
|
||||
|
||||
@@ -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']) ? gen_link_id($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,7 +842,6 @@ 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'),
|
||||
|
||||
@@ -69,12 +69,12 @@ 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
|
||||
|
||||
@@ -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" => ''
|
||||
);
|
||||
}
|
||||
@@ -284,7 +284,7 @@ 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
|
||||
@@ -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']);
|
||||
@@ -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'] ?? ''
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,23 +12,33 @@ class Queue {
|
||||
|
||||
$o = '';
|
||||
|
||||
$expert = ((array_key_exists('expert',$_REQUEST)) ? intval($_REQUEST['expert']) : 0);
|
||||
$expert = $_REQUEST['expert'] ?? false;
|
||||
|
||||
if($_REQUEST['drophub']) {
|
||||
if(isset($_REQUEST['drophub'])) {
|
||||
hubloc_mark_as_down($_REQUEST['drophub']);
|
||||
LibQueue::remove_by_posturl($_REQUEST['drophub']);
|
||||
}
|
||||
|
||||
if($_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(
|
||||
@@ -37,6 +47,7 @@ class Queue {
|
||||
'$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),
|
||||
|
||||
@@ -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');
|
||||
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
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 {
|
||||
|
||||
@@ -13,7 +13,7 @@ class Appman extends \Zotlabs\Web\Controller {
|
||||
if(! local_channel())
|
||||
return;
|
||||
|
||||
if($_POST['url']) {
|
||||
if(isset($_POST['url']) && $_POST['url']) {
|
||||
$arr = array(
|
||||
'uid' => intval($_REQUEST['uid']),
|
||||
'url' => escape_tags($_REQUEST['url']),
|
||||
@@ -33,9 +33,9 @@ class Appman extends \Zotlabs\Web\Controller {
|
||||
'categories' => escape_tags($_REQUEST['categories'])
|
||||
);
|
||||
|
||||
$_REQUEST['appid'] = Zlib\Apps::app_install(local_channel(),$arr);
|
||||
$_REQUEST['appid'] = Apps::app_install(local_channel(),$arr);
|
||||
|
||||
if(Zlib\Apps::app_installed(local_channel(),$arr))
|
||||
if(Apps::app_installed(local_channel(),$arr))
|
||||
info( t('App installed.') . EOL);
|
||||
|
||||
goaway(z_root() . '/apps');
|
||||
@@ -43,36 +43,98 @@ class Appman extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
|
||||
$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);
|
||||
|
||||
$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['delete']) {
|
||||
Zlib\Apps::app_destroy(local_channel(),$papp);
|
||||
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($_POST['edit']) {
|
||||
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($_POST['aj']) {
|
||||
if(isset($_POST['aj']) && $_POST['aj']) {
|
||||
killme();
|
||||
}
|
||||
|
||||
@@ -92,14 +154,14 @@ class Appman extends \Zotlabs\Web\Controller {
|
||||
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');
|
||||
}
|
||||
@@ -109,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())
|
||||
@@ -133,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')
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,8 @@ class Apps extends \Zotlabs\Web\Controller {
|
||||
|
||||
$_SESSION['return_url'] = \App::$query_string;
|
||||
|
||||
$apps = array();
|
||||
$apps = [];
|
||||
$cat = [];
|
||||
|
||||
if(local_channel()) {
|
||||
Zlib\Apps::import_system_apps();
|
||||
|
||||
@@ -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,138 +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'];
|
||||
|
||||
$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' => 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,232 +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 = '';
|
||||
$papp = Apps::get_papp('Articles');
|
||||
return Apps::app_render($papp, 'module');
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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,214 +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 = '';
|
||||
$papp = Apps::get_papp('Cards');
|
||||
return Apps::app_render($papp, 'module');
|
||||
}
|
||||
|
||||
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']);
|
||||
|
||||
@@ -914,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;
|
||||
@@ -921,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",
|
||||
@@ -944,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);
|
||||
|
||||
@@ -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,9 +42,9 @@ 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;
|
||||
@@ -53,14 +55,7 @@ class Channel extends Controller {
|
||||
$profile = argv(1);
|
||||
}
|
||||
|
||||
|
||||
// Do not use channelx_by_nick() here since it will dismiss deleted channels.
|
||||
// We need to provide zotinfo for deleted channels so that directories can pick up the info.
|
||||
$r = q("SELECT * FROM channel left join xchan on channel_hash = xchan_hash WHERE channel_address = '%s' LIMIT 1",
|
||||
dbesc($which)
|
||||
);
|
||||
|
||||
$channel = $r[0];
|
||||
$channel = channelx_by_nick($which, true);
|
||||
|
||||
if (!$channel) {
|
||||
http_status_exit(404, 'Not found');
|
||||
@@ -73,9 +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'])
|
||||
);
|
||||
|
||||
@@ -100,7 +94,11 @@ class Channel extends Controller {
|
||||
}
|
||||
|
||||
if ($channel['channel_removed']) {
|
||||
http_status_exit(404, 'Not found');
|
||||
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)) {
|
||||
@@ -271,6 +269,7 @@ class Channel extends Controller {
|
||||
'reset' => t('Reset form')
|
||||
];
|
||||
|
||||
$a = '';
|
||||
$o .= status_editor($a, $x, false, 'Channel');
|
||||
}
|
||||
|
||||
@@ -297,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) {
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -16,17 +16,17 @@ class Chanview extends \Zotlabs\Web\Controller {
|
||||
|
||||
$r = null;
|
||||
|
||||
if($_REQUEST['hash']) {
|
||||
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']) {
|
||||
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'])) {
|
||||
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 and xchan_deleted = 0",
|
||||
@@ -34,7 +34,7 @@ class Chanview extends \Zotlabs\Web\Controller {
|
||||
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.
|
||||
@@ -56,7 +56,7 @@ class Chanview extends \Zotlabs\Web\Controller {
|
||||
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,7 +65,7 @@ class Chanview extends \Zotlabs\Web\Controller {
|
||||
|
||||
$r = null;
|
||||
|
||||
if($_REQUEST['url']) {
|
||||
if(isset($_REQUEST['url']) && $_REQUEST['url']) {
|
||||
|
||||
$zf = Zotfinger::exec($_REQUEST['url'], null);
|
||||
|
||||
|
||||
@@ -174,7 +174,8 @@ class Chat extends Controller {
|
||||
$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'])
|
||||
);
|
||||
|
||||
@@ -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 {
|
||||
@@ -23,8 +22,8 @@ class Defperms extends Controller {
|
||||
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
|
||||
@@ -50,8 +49,8 @@ class Defperms extends Controller {
|
||||
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)
|
||||
@@ -183,12 +182,12 @@ class Defperms extends Controller {
|
||||
return login();
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
//~ 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');
|
||||
//~ }
|
||||
|
||||
$section = ((array_key_exists('section',$_REQUEST)) ? $_REQUEST['section'] : '');
|
||||
$channel = App::get_channel();
|
||||
@@ -259,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'),
|
||||
|
||||
@@ -83,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');
|
||||
@@ -98,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
|
||||
@@ -123,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);
|
||||
@@ -132,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\" ";
|
||||
}
|
||||
@@ -147,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()) {
|
||||
@@ -228,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) {
|
||||
@@ -254,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);
|
||||
|
||||
@@ -312,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",
|
||||
@@ -352,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'] : ''),
|
||||
@@ -374,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
|
||||
);
|
||||
|
||||
@@ -402,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
|
||||
@@ -449,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);
|
||||
|
||||
@@ -26,7 +26,7 @@ class Dirsearch extends Controller {
|
||||
}
|
||||
|
||||
|
||||
$access_token = $_REQUEST['t'];
|
||||
$access_token = $_REQUEST['t'] ?? '';
|
||||
|
||||
$token = get_config('system','realm_token');
|
||||
if($token && $access_token != $token) {
|
||||
@@ -45,7 +45,7 @@ class Dirsearch extends Controller {
|
||||
|
||||
$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) {
|
||||
@@ -61,22 +61,23 @@ class Dirsearch extends Controller {
|
||||
}
|
||||
}
|
||||
|
||||
$hash = ((x($_REQUEST['hash'])) ? $_REQUEST['hash'] : '');
|
||||
$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;
|
||||
|
||||
$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 );
|
||||
$forums = ((array_key_exists('pubforums',$_REQUEST)) ? intval($_REQUEST['pubforums']) : 0);
|
||||
|
||||
if(get_config('system','disable_directory_keywords'))
|
||||
@@ -109,7 +110,7 @@ class Dirsearch extends Controller {
|
||||
$sort_order = ((x($_REQUEST,'order')) ? $_REQUEST['order'] : '');
|
||||
|
||||
$joiner = ' OR ';
|
||||
if($_REQUEST['and'])
|
||||
if(isset($_REQUEST['and']) && $_REQUEST['and'])
|
||||
$joiner = ' AND ';
|
||||
|
||||
if($name)
|
||||
@@ -148,11 +149,11 @@ class Dirsearch extends Controller {
|
||||
}
|
||||
|
||||
|
||||
$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
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
if($_REQUEST['mid']) {
|
||||
if(isset($_REQUEST['mid']) && $_REQUEST['mid']) {
|
||||
$item_hash = $_REQUEST['mid'];
|
||||
}
|
||||
|
||||
@@ -56,6 +56,8 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
|
||||
$observer_is_owner = false;
|
||||
|
||||
$o = '';
|
||||
|
||||
if(local_channel() && (! $update)) {
|
||||
|
||||
$channel = App::get_channel();
|
||||
@@ -72,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' => '',
|
||||
@@ -87,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>';
|
||||
}
|
||||
@@ -107,17 +110,21 @@ class Display extends \Zotlabs\Web\Controller {
|
||||
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) {
|
||||
@@ -143,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'])
|
||||
@@ -266,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 = ''
|
||||
@@ -303,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 = ''
|
||||
@@ -341,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/' . gen_link_id($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>';
|
||||
|
||||
@@ -56,9 +56,12 @@ class Dreport extends \Zotlabs\Web\Controller {
|
||||
return;
|
||||
}
|
||||
|
||||
$r = q("select * from dreport where 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($mid)
|
||||
dbesc($mid),
|
||||
dbesc($mid . '#sync'),
|
||||
dbesc(str_replace('/item/', '/activity/', $mid)),
|
||||
dbesc(str_replace('/item/', '/activity/', $mid) . '#sync')
|
||||
);
|
||||
|
||||
if(! $r) {
|
||||
@@ -93,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');
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -60,25 +60,26 @@ class Fhublocs extends \Zotlabs\Web\Controller {
|
||||
|
||||
$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 {
|
||||
|
||||
@@ -41,16 +40,17 @@ class Group extends Controller {
|
||||
|
||||
$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');
|
||||
|
||||
@@ -65,10 +65,11 @@ class Group extends Controller {
|
||||
}
|
||||
$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,13 +80,25 @@ 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));
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
@@ -117,51 +130,32 @@ 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');
|
||||
|
||||
@@ -174,7 +168,7 @@ class Group extends Controller {
|
||||
intval(local_channel())
|
||||
);
|
||||
if($r)
|
||||
$result = group_rmv(local_channel(),$r[0]['gname']);
|
||||
$result = AccessList::remove(local_channel(),$r[0]['gname']);
|
||||
if($result) {
|
||||
$hookinfo = [ 'pgrp_extras' => '', 'group' => argv(2) ];
|
||||
call_hooks ('privacygroup_extras_drop',$hookinfo);
|
||||
@@ -215,7 +209,7 @@ class Group extends Controller {
|
||||
$group = $r[0];
|
||||
|
||||
|
||||
$members = group_get_members($group['id']);
|
||||
$members = AccessList::members(local_channel(), $group['id']);
|
||||
|
||||
$preselected = array();
|
||||
if(count($members)) {
|
||||
@@ -227,13 +221,13 @@ class Group extends Controller {
|
||||
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)) {
|
||||
@@ -252,9 +246,9 @@ 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,
|
||||
);
|
||||
@@ -280,7 +274,7 @@ 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",
|
||||
@@ -302,6 +296,12 @@ class Group extends Controller {
|
||||
$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);
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Zotlabs\Module;
|
||||
class Hcard extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
|
||||
if(argc() > 1)
|
||||
$which = argv(1);
|
||||
else {
|
||||
@@ -13,12 +13,12 @@ class Hcard extends \Zotlabs\Web\Controller {
|
||||
\App::$error = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
logger('hcard_request: ' . $which, LOGGER_DEBUG);
|
||||
|
||||
$profile = '';
|
||||
$channel = \App::get_channel();
|
||||
|
||||
|
||||
if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
|
||||
$which = $channel['channel_address'];
|
||||
$profile = argv(1);
|
||||
@@ -30,22 +30,22 @@ class Hcard extends \Zotlabs\Web\Controller {
|
||||
$profile = '';
|
||||
$profile = $r[0]['profile_guid'];
|
||||
}
|
||||
|
||||
head_add_link( [
|
||||
'rel' => 'alternate',
|
||||
|
||||
head_add_link( [
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/atom+xml',
|
||||
'title' => t('Posts and comments'),
|
||||
'href' => z_root() . '/feed/' . $which
|
||||
]);
|
||||
|
||||
head_add_link( [
|
||||
'rel' => 'alternate',
|
||||
head_add_link( [
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/atom+xml',
|
||||
'title' => t('Only posts'),
|
||||
'href' => z_root() . '/feed/' . $which . '?f=&top=1'
|
||||
]);
|
||||
|
||||
|
||||
|
||||
if(! $profile) {
|
||||
$x = q("select channel_id as profile_uid from channel where channel_address = '%s' limit 1",
|
||||
dbesc(argv(1))
|
||||
@@ -54,20 +54,20 @@ class Hcard extends \Zotlabs\Web\Controller {
|
||||
\App::$profile = $x[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
profile_load($which,$profile);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
$x = new \Zotlabs\Widget\Profile();
|
||||
$x = new \Zotlabs\Widget\Fullprofile();
|
||||
return $x->widget(array());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -17,7 +17,9 @@ class Help extends \Zotlabs\Web\Controller {
|
||||
function get() {
|
||||
nav_set_selected('Help');
|
||||
|
||||
if($_REQUEST['search']) {
|
||||
$o = '';
|
||||
|
||||
if(isset($_REQUEST['search']) && $_REQUEST['search']) {
|
||||
$o .= '<div id="help-content" class="generic-content-wrapper">';
|
||||
$o .= '<div class="section-title-wrapper">';
|
||||
$o .= '<h2>' . t('Documentation Search') . ' - ' . htmlspecialchars($_REQUEST['search']) . '</h2>';
|
||||
@@ -44,8 +46,8 @@ class Help extends \Zotlabs\Web\Controller {
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if(argc() > 2 && argv(argc()-2) === 'assets') {
|
||||
$path = '';
|
||||
for($x = 1; $x < argc(); $x ++) {
|
||||
@@ -87,11 +89,12 @@ class Help extends \Zotlabs\Web\Controller {
|
||||
'tutorials' => t('Tutorials')
|
||||
];
|
||||
|
||||
$heading = '';
|
||||
if(array_key_exists(argv(1), $headings))
|
||||
$heading = $headings[argv(1)];
|
||||
|
||||
$content = get_help_content();
|
||||
|
||||
|
||||
$language = determine_help_language()['language'];
|
||||
|
||||
return replace_macros(get_markup_template('help.tpl'), array(
|
||||
|
||||
@@ -36,7 +36,7 @@ class Home extends Controller {
|
||||
|
||||
$channel = App::get_channel();
|
||||
if (local_channel() && $channel && $channel['xchan_url'] && !$splash) {
|
||||
$dest = (($ret['startpage']) ? $ret['startpage'] : '');
|
||||
$dest = $ret['startpage'] ?? '';
|
||||
if (!$dest)
|
||||
$dest = get_config('system', 'startpage');
|
||||
if (!$dest)
|
||||
|
||||
@@ -27,6 +27,8 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
return;
|
||||
}
|
||||
|
||||
$item_hash = '';
|
||||
|
||||
if(argc() > 1 && argv(1) !== 'load') {
|
||||
$item_hash = unpack_link_id(argv(1));
|
||||
}
|
||||
@@ -42,24 +44,14 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
|
||||
$item_normal = item_normal();
|
||||
$item_normal_update = item_normal_update();
|
||||
|
||||
if(! $item_hash) {
|
||||
$r = q("SELECT mid FROM item
|
||||
WHERE uid = %d $item_normal
|
||||
AND mid = parent_mid
|
||||
AND item_private IN (0, 1)
|
||||
ORDER BY created DESC LIMIT 1",
|
||||
intval(local_channel())
|
||||
);
|
||||
if($r[0]['mid']) {
|
||||
$item_hash = $r[0]['mid'];
|
||||
}
|
||||
}
|
||||
$sys = get_sys_channel();
|
||||
$sys_item = false;
|
||||
$sql_extra = '';
|
||||
$target_item = null;
|
||||
$o = '';
|
||||
|
||||
if($item_hash) {
|
||||
|
||||
$target_item = null;
|
||||
|
||||
$r = q("select id, uid, mid, parent_mid, thr_parent, verb, item_type, item_deleted, item_blocked from item where mid = '%s' limit 1",
|
||||
dbesc($item_hash)
|
||||
);
|
||||
@@ -77,11 +69,6 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
if($update && $_SESSION['loadtime'])
|
||||
$simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) ";
|
||||
|
||||
$sys = get_sys_channel();
|
||||
$sql_extra = item_permissions_sql($sys['channel_id']);
|
||||
|
||||
$sys_item = false;
|
||||
|
||||
}
|
||||
|
||||
if(! $update) {
|
||||
@@ -99,7 +86,7 @@ class Hq 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' => '',
|
||||
@@ -114,7 +101,8 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
'reset' => t('Reset form')
|
||||
];
|
||||
|
||||
$o = status_editor($a, $x, true);
|
||||
$a = '';
|
||||
$o .= status_editor($a, $x, true);
|
||||
|
||||
}
|
||||
|
||||
@@ -183,6 +171,7 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
|
||||
if(!$r) {
|
||||
$sys_item = true;
|
||||
$sql_extra = item_permissions_sql($sys['channel_id']);
|
||||
|
||||
$r = q("SELECT item.id AS item_id FROM item
|
||||
LEFT JOIN abook ON item.author_xchan = abook.abook_xchan
|
||||
@@ -209,6 +198,7 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
|
||||
if(!$r) {
|
||||
$sys_item = true;
|
||||
$sql_extra = item_permissions_sql($sys['channel_id']);
|
||||
|
||||
$r = q("SELECT item.parent AS item_id FROM item
|
||||
LEFT JOIN abook ON item.author_xchan = abook.abook_xchan
|
||||
@@ -227,7 +217,7 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
if($r) {
|
||||
$items = q("SELECT item.*, item.id AS item_id
|
||||
FROM item
|
||||
WHERE parent = '%s' $item_normal ",
|
||||
WHERE parent = '%s' $item_normal $sql_extra",
|
||||
dbesc($r[0]['item_id'])
|
||||
);
|
||||
|
||||
@@ -253,9 +243,8 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
if (!local_channel())
|
||||
return;
|
||||
|
||||
$options['offset'] = $_REQUEST['offset'];
|
||||
$options['dm'] = $_REQUEST['dm'];
|
||||
$options['type'] = $_REQUEST['type'];
|
||||
$options['offset'] = $_REQUEST['offset'] ?? 0;
|
||||
$options['type'] = $_REQUEST['type'] ?? '';
|
||||
|
||||
$ret = Messages::get_messages_page($options);
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module; /** @file */
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use URLify;
|
||||
|
||||
/** @file */
|
||||
|
||||
// import page design element
|
||||
|
||||
@@ -9,33 +13,33 @@ require_once('include/menu.php');
|
||||
class Impel extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
|
||||
$ret = array('success' => false);
|
||||
|
||||
|
||||
if(! local_channel())
|
||||
json_return_and_die($ret);
|
||||
|
||||
|
||||
logger('impel: ' . print_r($_REQUEST,true), LOGGER_DATA);
|
||||
|
||||
|
||||
$elm = $_REQUEST['element'];
|
||||
$x = base64url_decode($elm);
|
||||
if(! $x)
|
||||
json_return_and_die($ret);
|
||||
|
||||
|
||||
$j = json_decode($x,true);
|
||||
if(! $j)
|
||||
json_return_and_die($ret);
|
||||
|
||||
|
||||
// logger('element: ' . print_r($j,true));
|
||||
|
||||
$channel = \App::get_channel();
|
||||
|
||||
|
||||
$arr = array();
|
||||
$is_menu = false;
|
||||
|
||||
|
||||
// a portable menu has its links rewritten with the local baseurl
|
||||
$portable_menu = false;
|
||||
|
||||
|
||||
switch($j['type']) {
|
||||
case 'webpage':
|
||||
$arr['item_type'] = ITEM_TYPE_WEBPAGE;
|
||||
@@ -58,12 +62,12 @@ class Impel extends \Zotlabs\Web\Controller {
|
||||
case 'menu':
|
||||
$is_menu = true;
|
||||
$installed_type = t('menu');
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
logger('mod_impel: unrecognised element type' . print_r($j,true));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if($is_menu) {
|
||||
$m = array();
|
||||
$m['menu_channel_id'] = local_channel();
|
||||
@@ -73,23 +77,23 @@ class Impel extends \Zotlabs\Web\Controller {
|
||||
$m['menu_created'] = datetime_convert($j['created']);
|
||||
if($j['edited'])
|
||||
$m['menu_edited'] = datetime_convert($j['edited']);
|
||||
|
||||
|
||||
$m['menu_flags'] = 0;
|
||||
if($j['flags']) {
|
||||
if(in_array('bookmark',$j['flags']))
|
||||
$m['menu_flags'] |= MENU_BOOKMARK;
|
||||
if(in_array('system',$j['flags']))
|
||||
$m['menu_flags'] |= MENU_SYSTEM;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
$menu_id = menu_create($m);
|
||||
|
||||
|
||||
if($menu_id) {
|
||||
if(is_array($j['items'])) {
|
||||
foreach($j['items'] as $it) {
|
||||
$mitem = array();
|
||||
|
||||
|
||||
$mitem['mitem_link'] = str_replace('[channelurl]',z_root() . '/channel/' . $channel['channel_address'],$it['link']);
|
||||
$mitem['mitem_link'] = str_replace('[pageurl]',z_root() . '/page/' . $channel['channel_address'],$it['link']);
|
||||
$mitem['mitem_link'] = str_replace('[cloudurl]',z_root() . '/cloud/' . $channel['channel_address'],$it['link']);
|
||||
@@ -115,7 +119,7 @@ class Impel extends \Zotlabs\Web\Controller {
|
||||
intval(local_channel())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
$ret['success'] = true;
|
||||
}
|
||||
$x = $ret;
|
||||
@@ -132,22 +136,21 @@ class Impel extends \Zotlabs\Web\Controller {
|
||||
$arr['owner_xchan'] = get_observer_hash();
|
||||
$arr['author_xchan'] = (($j['author_xchan']) ? $j['author_xchan'] : get_observer_hash());
|
||||
$arr['mimetype'] = (($j['mimetype']) ? $j['mimetype'] : 'text/bbcode');
|
||||
|
||||
|
||||
if(! $j['mid']) {
|
||||
$j['uuid'] = item_message_id();
|
||||
$j['mid'] = z_root() . '/item/' . $j['uuid'];
|
||||
}
|
||||
$arr['uuid'] = $j['uuid'];
|
||||
$arr['mid'] = $arr['parent_mid'] = $j['mid'];
|
||||
|
||||
|
||||
|
||||
|
||||
if($j['pagetitle']) {
|
||||
require_once('library/urlify/URLify.php');
|
||||
$pagetitle = strtolower(\URLify::transliterate($j['pagetitle']));
|
||||
$pagetitle = strtolower(URLify::transliterate($j['pagetitle']));
|
||||
}
|
||||
|
||||
|
||||
// Verify ability to use html or php!!!
|
||||
|
||||
|
||||
$execflag = ((intval($channel['channel_id']) == intval(local_channel()) && ($channel['channel_pageflags'] & PAGE_ALLOWCODE)) ? true : false);
|
||||
|
||||
$i = q("select id, edited, item_deleted from item where mid = '%s' and uid = %d limit 1",
|
||||
@@ -156,7 +159,7 @@ class Impel extends \Zotlabs\Web\Controller {
|
||||
);
|
||||
|
||||
\Zotlabs\Lib\IConfig::Set($arr,'system',$namespace,(($pagetitle) ? $pagetitle : substr($arr['mid'],0,16)),true);
|
||||
|
||||
|
||||
if($i) {
|
||||
$arr['id'] = $i[0]['id'];
|
||||
// don't update if it has the same timestamp as the original
|
||||
@@ -174,24 +177,24 @@ class Impel extends \Zotlabs\Web\Controller {
|
||||
else
|
||||
$x = item_store($arr,$execflag);
|
||||
}
|
||||
|
||||
|
||||
if($x && $x['success']) {
|
||||
$item_id = $x['item_id'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if($x['success']) {
|
||||
$ret['success'] = true;
|
||||
info( sprintf( t('%s element installed'), $installed_type));
|
||||
info( sprintf( t('%s element installed'), $installed_type));
|
||||
}
|
||||
else {
|
||||
notice( sprintf( t('%s element installation failed'), $installed_type));
|
||||
notice( sprintf( t('%s element installation failed'), $installed_type));
|
||||
}
|
||||
|
||||
//??? should perhaps return ret?
|
||||
|
||||
//??? should perhaps return ret?
|
||||
|
||||
json_return_and_die(true);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,10 +5,12 @@ namespace Zotlabs\Module;
|
||||
require_once('include/channel.php');
|
||||
require_once('include/import.php');
|
||||
require_once('include/perm_upgrade.php');
|
||||
require_once('library/urlify/URLify.php');
|
||||
|
||||
use Zotlabs\Lib\Crypto;
|
||||
use App;
|
||||
use URLify;
|
||||
use Zotlabs\Daemon\Master;
|
||||
use Zotlabs\Lib\Libzot;
|
||||
use Zotlabs\Web\Controller;
|
||||
|
||||
|
||||
/**
|
||||
@@ -17,7 +19,7 @@ use Zotlabs\Lib\Libzot;
|
||||
* Import a channel, either by direct file upload or via
|
||||
* connection to another server.
|
||||
*/
|
||||
class Import extends \Zotlabs\Web\Controller {
|
||||
class Import extends Controller {
|
||||
|
||||
/**
|
||||
* @brief Import channel into account.
|
||||
@@ -26,95 +28,94 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
*/
|
||||
function import_account($account_id) {
|
||||
|
||||
if(! $account_id){
|
||||
if (!$account_id) {
|
||||
logger('No account ID supplied');
|
||||
return;
|
||||
}
|
||||
|
||||
$max_friends = account_service_class_fetch($account_id,'total_channels');
|
||||
$max_feeds = account_service_class_fetch($account_id,'total_feeds');
|
||||
$data = null;
|
||||
$seize = ((x($_REQUEST,'make_primary')) ? intval($_REQUEST['make_primary']) : 0);
|
||||
$import_posts = ((x($_REQUEST,'import_posts')) ? intval($_REQUEST['import_posts']) : 0);
|
||||
$moving = intval($_REQUEST['moving']);
|
||||
$src = $_FILES['filename']['tmp_name'];
|
||||
$filename = basename($_FILES['filename']['name']);
|
||||
$filesize = intval($_FILES['filename']['size']);
|
||||
$filetype = $_FILES['filename']['type'];
|
||||
$newname = trim(strtolower($_REQUEST['newname']));
|
||||
$max_friends = account_service_class_fetch($account_id, 'total_channels');
|
||||
$max_feeds = account_service_class_fetch($account_id, 'total_feeds');
|
||||
$data = null;
|
||||
$seize = ((x($_REQUEST, 'make_primary')) ? intval($_REQUEST['make_primary']) : 0);
|
||||
$import_posts = ((x($_REQUEST, 'import_posts')) ? intval($_REQUEST['import_posts']) : 0);
|
||||
$moving = false; //intval($_REQUEST['moving']);
|
||||
$src = $_FILES['filename']['tmp_name'];
|
||||
$filename = basename($_FILES['filename']['name']);
|
||||
$filesize = intval($_FILES['filename']['size']);
|
||||
$filetype = $_FILES['filename']['type'];
|
||||
$newname = trim(strtolower($_REQUEST['newname']));
|
||||
|
||||
// import channel from file
|
||||
if($src) {
|
||||
if ($src) {
|
||||
|
||||
// This is OS specific and could also fail if your tmpdir isn't very
|
||||
// large mostly used for Diaspora which exports gzipped files.
|
||||
|
||||
if(strpos($filename,'.gz')){
|
||||
@rename($src,$src . '.gz');
|
||||
if (strpos($filename, '.gz')) {
|
||||
@rename($src, $src . '.gz');
|
||||
@system('gunzip ' . escapeshellarg($src . '.gz'));
|
||||
}
|
||||
|
||||
if($filesize) {
|
||||
if ($filesize) {
|
||||
$data = @file_get_contents($src);
|
||||
}
|
||||
unlink($src);
|
||||
}
|
||||
|
||||
// import channel from another server
|
||||
if(! $src) {
|
||||
$old_address = ((x($_REQUEST,'old_address')) ? $_REQUEST['old_address'] : '');
|
||||
if(! $old_address) {
|
||||
if (!$src) {
|
||||
$old_address = ((x($_REQUEST, 'old_address')) ? $_REQUEST['old_address'] : '');
|
||||
if (!$old_address) {
|
||||
logger('Nothing to import.');
|
||||
notice( t('Nothing to import.') . EOL);
|
||||
notice(t('Nothing to import.') . EOL);
|
||||
return;
|
||||
} else if(strpos($old_address, '@')) {
|
||||
}
|
||||
else if (strpos($old_address, '@')) {
|
||||
// if you copy the identity address from your profile page, make it work for convenience - WARNING: this is a utf-8 variant and NOT an ASCII ampersand. Please do not edit.
|
||||
$old_address = str_replace('@', '@', $old_address);
|
||||
}
|
||||
|
||||
$email = ((x($_REQUEST,'email')) ? $_REQUEST['email'] : '');
|
||||
$password = ((x($_REQUEST,'password')) ? $_REQUEST['password'] : '');
|
||||
$email = ((x($_REQUEST, 'email')) ? $_REQUEST['email'] : '');
|
||||
$password = ((x($_REQUEST, 'password')) ? $_REQUEST['password'] : '');
|
||||
|
||||
$channelname = substr($old_address,0,strpos($old_address,'@'));
|
||||
$servername = substr($old_address,strpos($old_address,'@')+1);
|
||||
$channelname = substr($old_address, 0, strpos($old_address, '@'));
|
||||
$servername = substr($old_address, strpos($old_address, '@') + 1);
|
||||
|
||||
$api_path = probe_api_path($servername);
|
||||
if(! $api_path) {
|
||||
notice( t('Unable to download data from old server') . EOL);
|
||||
if (!$api_path) {
|
||||
notice(t('Unable to download data from old server') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$api_path .= 'channel/export/basic?f=&channel=' . $channelname;
|
||||
if($import_posts)
|
||||
$api_path .= '&posts=1';
|
||||
|
||||
$binary = false;
|
||||
$binary = false;
|
||||
$redirects = 0;
|
||||
$opts = array('http_auth' => $email . ':' . $password);
|
||||
$ret = z_fetch_url($api_path, $binary, $redirects, $opts);
|
||||
if($ret['success']) {
|
||||
$opts = ['http_auth' => $email . ':' . $password];
|
||||
$ret = z_fetch_url($api_path, $binary, $redirects, $opts);
|
||||
if ($ret['success']) {
|
||||
$data = $ret['body'];
|
||||
}
|
||||
else {
|
||||
notice( t('Unable to download data from old server') . EOL);
|
||||
notice(t('Unable to download data from old server') . EOL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(! $data) {
|
||||
if (!$data) {
|
||||
logger('Empty import file.');
|
||||
notice( t('Imported file is empty.') . EOL);
|
||||
notice(t('Imported file is empty.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$data = json_decode($data,true);
|
||||
$data = json_decode($data, true);
|
||||
|
||||
//logger('import: data: ' . print_r($data,true));
|
||||
//print_r($data);
|
||||
|
||||
if(! array_key_exists('compatibility',$data)) {
|
||||
call_hooks('import_foreign_channel_data',$data);
|
||||
if($data['handled'])
|
||||
if (!array_key_exists('compatibility', $data)) {
|
||||
call_hooks('import_foreign_channel_data', $data);
|
||||
if ($data['handled'])
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -132,47 +133,47 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
|
||||
// prevent incompatible osada or zap data from horking your database
|
||||
|
||||
if(array_path_exists('compatibility/codebase',$data)) {
|
||||
if (array_path_exists('compatibility/codebase', $data)) {
|
||||
notice('Data export format is not compatible with this software');
|
||||
return;
|
||||
}
|
||||
|
||||
if(version_compare($data['compatibility']['version'], '4.7.3', '<=')) {
|
||||
if (version_compare($data['compatibility']['version'], '4.7.3', '<=')) {
|
||||
// zot6 transition: cloning is not compatible with older versions
|
||||
notice('Data export format is not compatible with this software (not a zot6 channel)');
|
||||
return;
|
||||
}
|
||||
|
||||
if($moving)
|
||||
if ($moving)
|
||||
$seize = 1;
|
||||
|
||||
// import channel
|
||||
|
||||
$relocate = ((array_key_exists('relocate',$data)) ? $data['relocate'] : null);
|
||||
$relocate = ((array_key_exists('relocate', $data)) ? $data['relocate'] : null);
|
||||
|
||||
if(array_key_exists('channel',$data)) {
|
||||
if (array_key_exists('channel', $data)) {
|
||||
|
||||
$max_identities = account_service_class_fetch($account_id,'total_identities');
|
||||
$max_identities = account_service_class_fetch($account_id, 'total_identities');
|
||||
|
||||
if($max_identities !== false) {
|
||||
$r = q("select channel_id from channel where channel_account_id = %d",
|
||||
if ($max_identities !== false) {
|
||||
$r = q("select channel_id from channel where channel_account_id = %d and channel_removed = 0",
|
||||
intval($account_id)
|
||||
);
|
||||
if($r && count($r) > $max_identities) {
|
||||
notice( sprintf( t('Your service plan only allows %d channels.'), $max_identities) . EOL);
|
||||
if ($r && count($r) > $max_identities) {
|
||||
notice(sprintf(t('Your service plan only allows %d channels.'), $max_identities) . EOL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if($newname) {
|
||||
$x = false;
|
||||
if ($newname) {
|
||||
$x = false;
|
||||
|
||||
if(get_config('system','unicode_usernames')) {
|
||||
$x = punify(mb_strtolower($newname));
|
||||
}
|
||||
if (get_config('system', 'unicode_usernames')) {
|
||||
$x = punify(mb_strtolower($newname));
|
||||
}
|
||||
|
||||
if((! $x) || strlen($x) > 64) {
|
||||
$x = strtolower(\URLify::transliterate($newname));
|
||||
if ((!$x) || strlen($x) > 64) {
|
||||
$x = strtolower(URLify::transliterate($newname));
|
||||
}
|
||||
$newname = $x;
|
||||
}
|
||||
@@ -181,36 +182,36 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
else {
|
||||
$moving = false;
|
||||
$channel = \App::get_channel();
|
||||
$channel = App::get_channel();
|
||||
}
|
||||
|
||||
if(! $channel) {
|
||||
logger('Channel not found. ', print_r($channel,true));
|
||||
notice( t('No channel. Import failed.') . EOL);
|
||||
if (!$channel) {
|
||||
logger('Channel not found. ', print_r($channel, true));
|
||||
notice(t('No channel. Import failed.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if(is_array($data['config'])) {
|
||||
import_config($channel,$data['config']);
|
||||
if (is_array($data['config'])) {
|
||||
import_config($channel, $data['config']);
|
||||
}
|
||||
|
||||
logger('import step 2');
|
||||
|
||||
if(array_key_exists('channel',$data)) {
|
||||
if($data['photo']) {
|
||||
if (array_key_exists('channel', $data)) {
|
||||
if ($data['photo']) {
|
||||
require_once('include/photo/photo_driver.php');
|
||||
import_channel_photo(base64url_decode($data['photo']['data']),$data['photo']['type'],$account_id,$channel['channel_id']);
|
||||
import_channel_photo(base64url_decode($data['photo']['data']), $data['photo']['type'], $account_id, $channel['channel_id']);
|
||||
}
|
||||
|
||||
if(is_array($data['profile']))
|
||||
import_profiles($channel,$data['profile']);
|
||||
if (is_array($data['profile']))
|
||||
import_profiles($channel, $data['profile']);
|
||||
}
|
||||
|
||||
logger('import step 3');
|
||||
|
||||
// create new hubloc for the new channel at this site
|
||||
|
||||
if(array_key_exists('channel',$data)) {
|
||||
if (array_key_exists('channel', $data)) {
|
||||
|
||||
// create a new zot6 hubloc
|
||||
|
||||
@@ -223,18 +224,18 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
'hubloc_network' => 'zot6',
|
||||
'hubloc_primary' => (($seize) ? 1 : 0),
|
||||
'hubloc_url' => z_root(),
|
||||
'hubloc_url_sig' => 'sha256.' . base64url_encode(Crypto::sign(z_root(),$channel['channel_prvkey'])),
|
||||
'hubloc_host' => \App::get_hostname(),
|
||||
'hubloc_url_sig' => Libzot::sign(z_root(), $channel['channel_prvkey']),
|
||||
'hubloc_host' => App::get_hostname(),
|
||||
'hubloc_callback' => z_root() . '/zot',
|
||||
'hubloc_sitekey' => get_config('system','pubkey'),
|
||||
'hubloc_sitekey' => get_config('system', 'pubkey'),
|
||||
'hubloc_updated' => datetime_convert(),
|
||||
'hubloc_id_url' => channel_url($channel),
|
||||
'hubloc_site_id' => Libzot::make_xchan_hash(z_root(),get_config('system','pubkey'))
|
||||
'hubloc_site_id' => Libzot::make_xchan_hash(z_root(), get_config('system', 'pubkey'))
|
||||
]
|
||||
);
|
||||
|
||||
// reset the original primary hubloc if it is being seized
|
||||
if($seize) {
|
||||
if ($seize) {
|
||||
$r = q("update hubloc set hubloc_primary = 0 where hubloc_primary = 1 and hubloc_hash = '%s' and hubloc_url != '%s' ",
|
||||
dbesc($channel['channel_hash']),
|
||||
dbesc(z_root())
|
||||
@@ -245,10 +246,9 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
|
||||
logger('import step 4');
|
||||
|
||||
|
||||
// import xchans and contact photos
|
||||
|
||||
if(array_key_exists('channel',$data) && $seize) {
|
||||
if (array_key_exists('channel', $data) && $seize) {
|
||||
|
||||
// replace any existing xchan we may have on this site if we're seizing control
|
||||
|
||||
@@ -258,21 +258,21 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
|
||||
$r = xchan_store_lowlevel(
|
||||
[
|
||||
'xchan_hash' => $channel['channel_hash'],
|
||||
'xchan_guid' => $channel['channel_guid'],
|
||||
'xchan_guid_sig' => $channel['channel_guid_sig'],
|
||||
'xchan_pubkey' => $channel['channel_pubkey'],
|
||||
'xchan_photo_l' => z_root() . "/photo/profile/l/" . $channel['channel_id'],
|
||||
'xchan_photo_m' => z_root() . "/photo/profile/m/" . $channel['channel_id'],
|
||||
'xchan_photo_s' => z_root() . "/photo/profile/s/" . $channel['channel_id'],
|
||||
'xchan_addr' => channel_reddress($channel),
|
||||
'xchan_url' => z_root() . '/channel/' . $channel['channel_address'],
|
||||
'xchan_connurl' => z_root() . '/poco/' . $channel['channel_address'],
|
||||
'xchan_follow' => z_root() . '/follow?f=&url=%s',
|
||||
'xchan_name' => $channel['channel_name'],
|
||||
'xchan_network' => 'zot6',
|
||||
'xchan_photo_date' => datetime_convert(),
|
||||
'xchan_name_date' => datetime_convert()
|
||||
'xchan_hash' => $channel['channel_hash'],
|
||||
'xchan_guid' => $channel['channel_guid'],
|
||||
'xchan_guid_sig' => $channel['channel_guid_sig'],
|
||||
'xchan_pubkey' => $channel['channel_pubkey'],
|
||||
'xchan_photo_l' => z_root() . "/photo/profile/l/" . $channel['channel_id'],
|
||||
'xchan_photo_m' => z_root() . "/photo/profile/m/" . $channel['channel_id'],
|
||||
'xchan_photo_s' => z_root() . "/photo/profile/s/" . $channel['channel_id'],
|
||||
'xchan_addr' => channel_reddress($channel),
|
||||
'xchan_url' => z_root() . '/channel/' . $channel['channel_address'],
|
||||
'xchan_connurl' => z_root() . '/poco/' . $channel['channel_address'],
|
||||
'xchan_follow' => z_root() . '/follow?f=&url=%s',
|
||||
'xchan_name' => $channel['channel_name'],
|
||||
'xchan_network' => 'zot6',
|
||||
'xchan_photo_date' => datetime_convert(),
|
||||
'xchan_name_date' => datetime_convert()
|
||||
]
|
||||
);
|
||||
|
||||
@@ -282,18 +282,18 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
|
||||
// import xchans
|
||||
$xchans = $data['xchan'];
|
||||
if($xchans) {
|
||||
foreach($xchans as $xchan) {
|
||||
if ($xchans) {
|
||||
foreach ($xchans as $xchan) {
|
||||
|
||||
if($xchan['xchan_network'] === 'zot6') {
|
||||
$zhash = Libzot::make_xchan_hash($xchan['xchan_guid'],$xchan['xchan_pubkey']);
|
||||
if($zhash !== $xchan['xchan_hash']) {
|
||||
logger('forged xchan: ' . print_r($xchan,true));
|
||||
if ($xchan['xchan_network'] === 'zot6') {
|
||||
$zhash = Libzot::make_xchan_hash($xchan['xchan_guid'], $xchan['xchan_pubkey']);
|
||||
if ($zhash !== $xchan['xchan_hash']) {
|
||||
logger('forged xchan: ' . print_r($xchan, true));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(! array_key_exists('xchan_hidden',$xchan)) {
|
||||
if (!array_key_exists('xchan_hidden', $xchan)) {
|
||||
$xchan['xchan_hidden'] = (($xchan['xchan_flags'] & 0x0001) ? 1 : 0);
|
||||
$xchan['xchan_orphan'] = (($xchan['xchan_flags'] & 0x0002) ? 1 : 0);
|
||||
$xchan['xchan_censored'] = (($xchan['xchan_flags'] & 0x0004) ? 1 : 0);
|
||||
@@ -306,14 +306,14 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
$r = q("select xchan_hash from xchan where xchan_hash = '%s' limit 1",
|
||||
dbesc($xchan['xchan_hash'])
|
||||
);
|
||||
if($r)
|
||||
if ($r)
|
||||
continue;
|
||||
|
||||
create_table_from_array('xchan',$xchan);
|
||||
create_table_from_array('xchan', $xchan);
|
||||
|
||||
require_once('include/photo/photo_driver.php');
|
||||
|
||||
if($xchan['xchan_hash'] === $channel['channel_hash']) {
|
||||
if ($xchan['xchan_hash'] === $channel['channel_hash']) {
|
||||
$r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s' where xchan_hash = '%s'",
|
||||
dbesc(z_root() . '/photo/profile/l/' . $channel['channel_id']),
|
||||
dbesc(z_root() . '/photo/profile/m/' . $channel['channel_id']),
|
||||
@@ -322,13 +322,13 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
);
|
||||
}
|
||||
else {
|
||||
$photos = import_xchan_photo($xchan['xchan_photo_l'],$xchan['xchan_hash']);
|
||||
if($photos[4])
|
||||
$photos = import_xchan_photo($xchan['xchan_photo_l'], $xchan['xchan_hash']);
|
||||
if ($photos[4])
|
||||
$photodate = NULL_DATE;
|
||||
else
|
||||
$photodate = $xchan['xchan_photo_date'];
|
||||
|
||||
$r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s', xchan_photo_date = '%s' where xchan_hash = '%s'",
|
||||
q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s', xchan_photo_date = '%s' where xchan_hash = '%s'",
|
||||
dbesc($photos[0]),
|
||||
dbesc($photos[1]),
|
||||
dbesc($photos[2]),
|
||||
@@ -345,22 +345,22 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
logger('import step 7');
|
||||
|
||||
// this must happen after xchans got imported!
|
||||
if(is_array($data['hubloc'])) {
|
||||
import_hublocs($channel,$data['hubloc'],$seize,$moving);
|
||||
if (is_array($data['hubloc'])) {
|
||||
import_hublocs($channel, $data['hubloc'], $seize, $moving);
|
||||
}
|
||||
|
||||
$friends = 0;
|
||||
$feeds = 0;
|
||||
$feeds = 0;
|
||||
|
||||
// import contacts
|
||||
$abooks = $data['abook'];
|
||||
if($abooks) {
|
||||
foreach($abooks as $abook) {
|
||||
if ($abooks) {
|
||||
foreach ($abooks as $abook) {
|
||||
|
||||
$abook_copy = $abook;
|
||||
|
||||
$abconfig = null;
|
||||
if(array_key_exists('abconfig',$abook) && is_array($abook['abconfig']) && count($abook['abconfig']))
|
||||
if (array_key_exists('abconfig', $abook) && is_array($abook['abconfig']) && count($abook['abconfig']))
|
||||
$abconfig = $abook['abconfig'];
|
||||
|
||||
unset($abook['abook_id']);
|
||||
@@ -373,33 +373,33 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
|
||||
$abook['abook_account'] = $account_id;
|
||||
$abook['abook_channel'] = $channel['channel_id'];
|
||||
if(! array_key_exists('abook_blocked',$abook)) {
|
||||
$abook['abook_blocked'] = (($abook['abook_flags'] & 0x0001 ) ? 1 : 0);
|
||||
$abook['abook_ignored'] = (($abook['abook_flags'] & 0x0002 ) ? 1 : 0);
|
||||
$abook['abook_hidden'] = (($abook['abook_flags'] & 0x0004 ) ? 1 : 0);
|
||||
$abook['abook_archived'] = (($abook['abook_flags'] & 0x0008 ) ? 1 : 0);
|
||||
$abook['abook_pending'] = (($abook['abook_flags'] & 0x0010 ) ? 1 : 0);
|
||||
$abook['abook_unconnected'] = (($abook['abook_flags'] & 0x0020 ) ? 1 : 0);
|
||||
$abook['abook_self'] = (($abook['abook_flags'] & 0x0080 ) ? 1 : 0);
|
||||
$abook['abook_feed'] = (($abook['abook_flags'] & 0x0100 ) ? 1 : 0);
|
||||
if (!array_key_exists('abook_blocked', $abook)) {
|
||||
$abook['abook_blocked'] = (($abook['abook_flags'] & 0x0001) ? 1 : 0);
|
||||
$abook['abook_ignored'] = (($abook['abook_flags'] & 0x0002) ? 1 : 0);
|
||||
$abook['abook_hidden'] = (($abook['abook_flags'] & 0x0004) ? 1 : 0);
|
||||
$abook['abook_archived'] = (($abook['abook_flags'] & 0x0008) ? 1 : 0);
|
||||
$abook['abook_pending'] = (($abook['abook_flags'] & 0x0010) ? 1 : 0);
|
||||
$abook['abook_unconnected'] = (($abook['abook_flags'] & 0x0020) ? 1 : 0);
|
||||
$abook['abook_self'] = (($abook['abook_flags'] & 0x0080) ? 1 : 0);
|
||||
$abook['abook_feed'] = (($abook['abook_flags'] & 0x0100) ? 1 : 0);
|
||||
}
|
||||
|
||||
if(array_key_exists('abook_instance',$abook) && $abook['abook_instance'] && strpos($abook['abook_instance'],z_root()) === false) {
|
||||
if (array_key_exists('abook_instance', $abook) && $abook['abook_instance'] && strpos($abook['abook_instance'], z_root()) === false) {
|
||||
$abook['abook_not_here'] = 1;
|
||||
}
|
||||
|
||||
if($abook['abook_self']) {
|
||||
$role = get_pconfig($channel['channel_id'],'system','permissions_role');
|
||||
if(($role === 'forum') || ($abook['abook_my_perms'] & PERMS_W_TAGWALL)) {
|
||||
if ($abook['abook_self']) {
|
||||
$role = get_pconfig($channel['channel_id'], 'system', 'permissions_role');
|
||||
if (($role === 'forum') || ($abook['abook_my_perms'] & PERMS_W_TAGWALL)) {
|
||||
q("update xchan set xchan_pubforum = 1 where xchan_hash = '%s' ",
|
||||
dbesc($abook['abook_xchan'])
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if($max_friends !== false && $friends > $max_friends)
|
||||
if ($max_friends !== false && $friends > $max_friends)
|
||||
continue;
|
||||
if($max_feeds !== false && intval($abook['abook_feed']) && ($feeds > $max_feeds))
|
||||
if ($max_feeds !== false && intval($abook['abook_feed']) && ($feeds > $max_feeds))
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -407,9 +407,9 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
dbesc($abook['abook_xchan']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if($r) {
|
||||
foreach($abook as $k => $v) {
|
||||
$r = q("UPDATE abook SET " . TQUOT . "%s" . TQUOT . " = '%s' WHERE abook_xchan = '%s' AND abook_channel = %d",
|
||||
if ($r) {
|
||||
foreach ($abook as $k => $v) {
|
||||
q("UPDATE abook SET " . TQUOT . "%s" . TQUOT . " = '%s' WHERE abook_xchan = '%s' AND abook_channel = %d",
|
||||
dbesc($k),
|
||||
dbesc($v),
|
||||
dbesc($abook['abook_xchan']),
|
||||
@@ -420,17 +420,17 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
else {
|
||||
abook_store_lowlevel($abook);
|
||||
|
||||
$friends ++;
|
||||
if(intval($abook['abook_feed']))
|
||||
$feeds ++;
|
||||
$friends++;
|
||||
if (intval($abook['abook_feed']))
|
||||
$feeds++;
|
||||
}
|
||||
|
||||
translate_abook_perms_inbound($channel,$abook_copy);
|
||||
translate_abook_perms_inbound($channel, $abook_copy);
|
||||
|
||||
if($abconfig) {
|
||||
if ($abconfig) {
|
||||
/// @FIXME does not handle sync of del_abconfig
|
||||
foreach($abconfig as $abc) {
|
||||
set_abconfig($channel['channel_id'],$abc['xchan'],$abc['cat'],$abc['k'],$abc['v']);
|
||||
foreach ($abconfig as $abc) {
|
||||
set_abconfig($channel['channel_id'], $abc['xchan'], $abc['cat'], $abc['k'], $abc['v']);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -438,13 +438,14 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
logger('import step 8');
|
||||
}
|
||||
|
||||
|
||||
// import groups
|
||||
$groups = $data['group'];
|
||||
if($groups) {
|
||||
$saved = array();
|
||||
foreach($groups as $group) {
|
||||
$saved[$group['hash']] = array('old' => $group['id']);
|
||||
if(array_key_exists('name', $group)) {
|
||||
if ($groups) {
|
||||
$saved = [];
|
||||
foreach ($groups as $group) {
|
||||
$saved[$group['hash']] = ['old' => $group['id']];
|
||||
if (array_key_exists('name', $group)) {
|
||||
$group['gname'] = $group['name'];
|
||||
unset($group['name']);
|
||||
}
|
||||
@@ -456,8 +457,8 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
$r = q("select * from pgrp where uid = %d",
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
$saved[$rr['hash']]['new'] = $rr['id'];
|
||||
}
|
||||
}
|
||||
@@ -465,12 +466,12 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
|
||||
// import group members
|
||||
$group_members = $data['group_member'];
|
||||
if($group_members) {
|
||||
foreach($group_members as $group_member) {
|
||||
if ($group_members) {
|
||||
foreach ($group_members as $group_member) {
|
||||
unset($group_member['id']);
|
||||
$group_member['uid'] = $channel['channel_id'];
|
||||
foreach($saved as $x) {
|
||||
if($x['old'] == $group_member['gid'])
|
||||
foreach ($saved as $x) {
|
||||
if ($x['old'] == $group_member['gid'])
|
||||
$group_member['gid'] = $x['new'];
|
||||
}
|
||||
create_table_from_array('pgrp_member', $group_member);
|
||||
@@ -479,59 +480,85 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
|
||||
logger('import step 9');
|
||||
|
||||
if(is_array($data['obj']))
|
||||
import_objs($channel,$data['obj']);
|
||||
|
||||
if(is_array($data['likes']))
|
||||
import_likes($channel,$data['likes']);
|
||||
if (is_array($data['obj']))
|
||||
import_objs($channel, $data['obj']);
|
||||
|
||||
if(is_array($data['app']))
|
||||
import_apps($channel,$data['app']);
|
||||
if (is_array($data['likes']))
|
||||
import_likes($channel, $data['likes']);
|
||||
|
||||
if(is_array($data['sysapp']))
|
||||
import_sysapps($channel,$data['sysapp']);
|
||||
if (is_array($data['app']))
|
||||
import_apps($channel, $data['app']);
|
||||
|
||||
if(is_array($data['chatroom']))
|
||||
import_chatrooms($channel,$data['chatroom']);
|
||||
if (is_array($data['sysapp']))
|
||||
import_sysapps($channel, $data['sysapp']);
|
||||
|
||||
if(is_array($data['event']))
|
||||
import_events($channel,$data['event']);
|
||||
if (is_array($data['chatroom']))
|
||||
import_chatrooms($channel, $data['chatroom']);
|
||||
|
||||
if(is_array($data['event_item']))
|
||||
import_items($channel,$data['event_item'],false,$relocate);
|
||||
if (is_array($data['event']))
|
||||
import_events($channel, $data['event']);
|
||||
|
||||
if(is_array($data['menu']))
|
||||
import_menus($channel,$data['menu']);
|
||||
if (is_array($data['event_item']))
|
||||
import_items($channel, $data['event_item'], false, $relocate);
|
||||
|
||||
if(is_array($data['wiki']))
|
||||
import_items($channel,$data['wiki'],false,$relocate);
|
||||
if (is_array($data['menu']))
|
||||
import_menus($channel, $data['menu']);
|
||||
|
||||
if(is_array($data['webpages']))
|
||||
import_items($channel,$data['webpages'],false,$relocate);
|
||||
if (is_array($data['wiki']))
|
||||
import_items($channel, $data['wiki'], false, $relocate);
|
||||
|
||||
$addon = array('channel' => $channel,'data' => $data);
|
||||
call_hooks('import_channel',$addon);
|
||||
if (is_array($data['webpages']))
|
||||
import_items($channel, $data['webpages'], false, $relocate);
|
||||
|
||||
$saved_notification_flags = notifications_off($channel['channel_id']);
|
||||
$addon = ['channel' => $channel, 'data' => $data];
|
||||
call_hooks('import_channel', $addon);
|
||||
|
||||
if($import_posts && array_key_exists('item',$data) && $data['item'])
|
||||
import_items($channel,$data['item'],false,$relocate);
|
||||
if ($import_posts && array_key_exists('item', $data) && $data['item']) {
|
||||
import_items($channel, $data['item'], false, $relocate);
|
||||
}
|
||||
|
||||
notifications_on($channel['channel_id'],$saved_notification_flags);
|
||||
|
||||
if(array_key_exists('item_id',$data) && $data['item_id'])
|
||||
import_item_ids($channel,$data['item_id']);
|
||||
// Immediately notify old server about the new clone
|
||||
Master::Summon(['Notifier', 'refresh_all', $channel['channel_id']]);
|
||||
|
||||
// This will indirectly perform a refresh_all *and* update the directory
|
||||
Master::Summon(['Directory', $channel['channel_id']]);
|
||||
|
||||
\Zotlabs\Daemon\Master::Summon(array('Directory', $channel['channel_id']));
|
||||
$cf_api_compat = true;
|
||||
|
||||
if ($api_path && $import_posts) { // we are importing from a server and not a file
|
||||
if (version_compare($data['compatibility']['version'], '6.3.4', '>=')) {
|
||||
|
||||
notice( t('Import completed.') . EOL);
|
||||
$m = parse_url($api_path);
|
||||
|
||||
$hz_server = $m['scheme'] . '://' . $m['host'];
|
||||
|
||||
$since = datetime_convert(date_default_timezone_get(), date_default_timezone_get(), '0001-01-01 00:00');
|
||||
$until = datetime_convert(date_default_timezone_get(), date_default_timezone_get(), 'now + 1 day');
|
||||
|
||||
$poll_interval = get_config('system', 'poll_interval', 3);
|
||||
$page = 0;
|
||||
|
||||
Master::Summon(['Content_importer', sprintf('%d', $page), $since, $until, $channel['channel_address'], urlencode($hz_server)]);
|
||||
Master::Summon(['File_importer', sprintf('%d', $page), $channel['channel_address'], urlencode($hz_server)]);
|
||||
}
|
||||
else {
|
||||
$cf_api_compat = false;
|
||||
}
|
||||
}
|
||||
|
||||
change_channel($channel['channel_id']);
|
||||
|
||||
goaway(z_root() . '/network' );
|
||||
if ($api_path && $import_posts && $cf_api_compat) {
|
||||
goaway(z_root() . '/import_progress');
|
||||
}
|
||||
|
||||
if (!$cf_api_compat) {
|
||||
notice(t('Automatic content and files import was not possible due to API version incompatiblity. Please import content and files manually!') . EOL);
|
||||
}
|
||||
|
||||
goaway(z_root());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -539,7 +566,7 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
*/
|
||||
function post() {
|
||||
$account_id = get_account_id();
|
||||
if(! $account_id)
|
||||
if (!$account_id)
|
||||
return;
|
||||
|
||||
check_form_security_token_redirectOnErr('/import', 'channel_import');
|
||||
@@ -554,33 +581,35 @@ class Import extends \Zotlabs\Web\Controller {
|
||||
*/
|
||||
function get() {
|
||||
|
||||
if(! get_account_id()) {
|
||||
notice( t('You must be logged in to use this feature.') . EOL);
|
||||
if (!get_account_id()) {
|
||||
notice(t('You must be logged in to use this feature.') . EOL);
|
||||
return '';
|
||||
}
|
||||
|
||||
$o = replace_macros(get_markup_template('channel_import.tpl'),array(
|
||||
'$title' => t('Import Channel'),
|
||||
'$desc' => t('Use this form to import an existing channel from a different server/hub. You may retrieve the channel identity from the old server/hub via the network or provide an export file.'),
|
||||
'$label_filename' => t('File to Upload'),
|
||||
'$choice' => t('Or provide the old server/hub details'),
|
||||
nav_set_selected('Channel Import');
|
||||
|
||||
'$old_address' => [ 'old_address', t('Your old identity address (xyz@example.com)'), '', ''],
|
||||
'$email' => [ 'email', t('Your old login email address'), '', '' ],
|
||||
'$password' => [ 'password', t('Your old login password'), '', '' ],
|
||||
'$import_posts' => [ 'import_posts', t('Import a few months of posts if possible (limited by available memory'), false, '', [ t('No'), t('Yes') ]],
|
||||
$o = replace_macros(get_markup_template('channel_import.tpl'), [
|
||||
'$title' => t('Channel Import'),
|
||||
'$desc' => t('Use this form to import an existing channel from a different server/hub. You may retrieve the channel identity from the old server/hub via the network or provide an export file.'),
|
||||
'$label_filename' => t('File to Upload'),
|
||||
'$choice' => t('Or provide the old server/hub details'),
|
||||
|
||||
'$old_address' => ['old_address', t('Your old identity address (xyz@example.com)'), '', ''],
|
||||
'$email' => ['email', t('Your old login email address'), '', ''],
|
||||
'$password' => ['password', t('Your old login password'), '', ''],
|
||||
'$import_posts' => ['import_posts', t('Import your items and files (limited by available memory)'), false, '', [t('No'), t('Yes')]],
|
||||
|
||||
'$common' => t('For either option, please choose whether to make this hub your new primary address, or whether your old location should continue this role. You will be able to post from either location, but only one can be marked as the primary location for files, photos, and media.'),
|
||||
|
||||
'$make_primary' => [ 'make_primary', t('Make this hub my primary location'), false, '', [ t('No'), t('Yes') ] ],
|
||||
'$moving' => [ 'moving', t('Move this channel (disable all previous locations)'), false, '', [ t('No'), t('Yes') ] ],
|
||||
'$newname' => [ 'newname', t('Use this channel nickname instead of the one provided'), '', t('Leave blank to keep your existing channel nickname. You will be randomly assigned a similar nickname if either name is already allocated on this site.')],
|
||||
'$make_primary' => ['make_primary', t('Make this hub my primary location'), false, '', [t('No'), t('Yes')]],
|
||||
'$moving' => ['moving', t('Move this channel (disable all previous locations)'), false, '', [t('No'), t('Yes')]],
|
||||
'$newname' => ['newname', t('Use this channel nickname instead of the one provided'), '', t('Leave blank to keep your existing channel nickname. You will be randomly assigned a similar nickname if either name is already allocated on this site.')],
|
||||
|
||||
'$pleasewait' => t('This process may take several minutes to complete. Please submit the form only once and leave this page open until finished.'),
|
||||
|
||||
'$form_security_token' => get_form_security_token('channel_import'),
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
'$submit' => t('Submit')
|
||||
]);
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use App;
|
||||
use ZipArchive;
|
||||
use Zotlabs\Web\Controller;
|
||||
|
||||
require_once('include/import.php');
|
||||
|
||||
/**
|
||||
@@ -8,104 +13,95 @@ require_once('include/import.php');
|
||||
*
|
||||
* Import existing posts and content from an export file.
|
||||
*/
|
||||
class Import_items extends \Zotlabs\Web\Controller {
|
||||
class Import_items extends Controller {
|
||||
|
||||
function post() {
|
||||
|
||||
if(! local_channel())
|
||||
if (!local_channel())
|
||||
return;
|
||||
|
||||
check_form_security_token_redirectOnErr('/import_items', 'import_items');
|
||||
|
||||
$data = null;
|
||||
$data = null;
|
||||
|
||||
$src = $_FILES['filename']['tmp_name'];
|
||||
$filename = basename($_FILES['filename']['name']);
|
||||
$filesize = intval($_FILES['filename']['size']);
|
||||
$filetype = $_FILES['filename']['type'];
|
||||
|
||||
if($src) {
|
||||
// This is OS specific and could also fail if your tmpdir isn't very large
|
||||
// mostly used for Diaspora which exports gzipped files.
|
||||
$channel = App::get_channel();
|
||||
|
||||
if(strpos($filename,'.gz')){
|
||||
@rename($src,$src . '.gz');
|
||||
@system('gunzip ' . escapeshellarg($src . '.gz'));
|
||||
}
|
||||
if ($src) {
|
||||
|
||||
if($filesize) {
|
||||
$data = @file_get_contents($src);
|
||||
}
|
||||
unlink($src);
|
||||
}
|
||||
if ($filetype === 'application/zip') {
|
||||
$zip = new ZipArchive;
|
||||
|
||||
if(! $src) {
|
||||
$r = $zip->open($src);
|
||||
if ($r === true) {
|
||||
for ($i = 0; $i < $zip->count(); $i++) {
|
||||
$data = $zip->getFromIndex($i);
|
||||
self::import($channel, $data);
|
||||
}
|
||||
$zip->close();
|
||||
unlink($src);
|
||||
return;
|
||||
}
|
||||
|
||||
$old_address = ((x($_REQUEST,'old_address')) ? $_REQUEST['old_address'] : '');
|
||||
|
||||
if(! $old_address) {
|
||||
logger('Nothing to import.');
|
||||
notice( t('Nothing to import.') . EOL);
|
||||
notice(t('Not a zip file or zip file corrupted.') . EOL);
|
||||
unlink($src);
|
||||
return;
|
||||
}
|
||||
|
||||
$email = ((x($_REQUEST,'email')) ? $_REQUEST['email'] : '');
|
||||
$password = ((x($_REQUEST,'password')) ? $_REQUEST['password'] : '');
|
||||
// This is OS specific and could also fail if your tmpdir isn't very large
|
||||
// mostly used for Diaspora which exports gzipped files.
|
||||
|
||||
$year = ((x($_REQUEST,'year')) ? $_REQUEST['year'] : '');
|
||||
//if(strpos($filename,'.gz')){
|
||||
//@rename($src,$src . '.gz');
|
||||
//@system('gunzip ' . escapeshellarg($src . '.gz'));
|
||||
//}
|
||||
|
||||
$channelname = substr($old_address,0,strpos($old_address,'@'));
|
||||
$servername = substr($old_address,strpos($old_address,'@')+1);
|
||||
|
||||
$scheme = 'https://';
|
||||
$api_path = '/api/red/channel/export/items?f=&channel=' . $channelname . '&year=' . intval($year);
|
||||
$binary = false;
|
||||
$redirects = 0;
|
||||
$opts = array('http_auth' => $email . ':' . $password);
|
||||
$url = $scheme . $servername . $api_path;
|
||||
$ret = z_fetch_url($url, $binary, $redirects, $opts);
|
||||
if(! $ret['success'])
|
||||
$ret = z_fetch_url('http://' . $servername . $api_path, $binary, $redirects, $opts);
|
||||
if($ret['success'])
|
||||
$data = $ret['body'];
|
||||
else
|
||||
notice( t('Unable to download data from old server') . EOL);
|
||||
}
|
||||
|
||||
if(! $data) {
|
||||
logger('Empty file.');
|
||||
notice( t('Imported file is empty.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$data = json_decode($data, true);
|
||||
|
||||
//logger('import: data: ' . print_r($data,true));
|
||||
//print_r($data);
|
||||
|
||||
if(! is_array($data))
|
||||
return;
|
||||
|
||||
if(array_key_exists('compatibility',$data) && array_key_exists('database',$data['compatibility'])) {
|
||||
$v1 = substr($data['compatibility']['database'],-4);
|
||||
$v2 = substr(DB_UPDATE_VERSION,-4);
|
||||
if($v2 > $v1) {
|
||||
$t = sprintf( t('Warning: Database versions differ by %1$d updates.'), $v2 - $v1 );
|
||||
notice($t . EOL);
|
||||
if ($filesize) {
|
||||
$data = @file_get_contents($src);
|
||||
self::import($channel, $data);
|
||||
}
|
||||
unlink($src);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
if(! $src) {
|
||||
|
||||
$channel = \App::get_channel();
|
||||
$old_address = ((x($_REQUEST,'old_address')) ? $_REQUEST['old_address'] : '');
|
||||
|
||||
if(array_key_exists('item',$data) && $data['item']) {
|
||||
import_items($channel,$data['item'],false,((array_key_exists('relocate',$data)) ? $data['relocate'] : null));
|
||||
}
|
||||
if(! $old_address) {
|
||||
logger('Nothing to import.');
|
||||
notice( t('Nothing to import.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if(array_key_exists('item_id',$data) && $data['item_id']) {
|
||||
import_item_ids($channel,$data['item_id']);
|
||||
}
|
||||
$email = ((x($_REQUEST,'email')) ? $_REQUEST['email'] : '');
|
||||
$password = ((x($_REQUEST,'password')) ? $_REQUEST['password'] : '');
|
||||
|
||||
$year = ((x($_REQUEST,'year')) ? $_REQUEST['year'] : '');
|
||||
|
||||
$channelname = substr($old_address,0,strpos($old_address,'@'));
|
||||
$servername = substr($old_address,strpos($old_address,'@')+1);
|
||||
|
||||
$scheme = 'https://';
|
||||
$api_path = '/api/red/channel/export/items?f=&channel=' . $channelname . '&year=' . intval($year);
|
||||
$binary = false;
|
||||
$redirects = 0;
|
||||
$opts = array('http_auth' => $email . ':' . $password);
|
||||
$url = $scheme . $servername . $api_path;
|
||||
$ret = z_fetch_url($url, $binary, $redirects, $opts);
|
||||
if(! $ret['success'])
|
||||
$ret = z_fetch_url('http://' . $servername . $api_path, $binary, $redirects, $opts);
|
||||
if($ret['success'])
|
||||
$data = $ret['body'];
|
||||
else
|
||||
notice( t('Unable to download data from old server') . EOL);
|
||||
}
|
||||
*/
|
||||
|
||||
info( t('Import completed') . EOL);
|
||||
}
|
||||
|
||||
|
||||
@@ -116,20 +112,85 @@ class Import_items extends \Zotlabs\Web\Controller {
|
||||
*/
|
||||
function get() {
|
||||
|
||||
if(! local_channel()) {
|
||||
notice( t('Permission denied') . EOL);
|
||||
if (!local_channel()) {
|
||||
notice(t('Permission denied') . EOL);
|
||||
return login();
|
||||
}
|
||||
|
||||
$o = replace_macros(get_markup_template('item_import.tpl'), array(
|
||||
'$title' => t('Import Items'),
|
||||
'$desc' => t('Use this form to import existing posts and content from an export file.'),
|
||||
'$label_filename' => t('File to Upload'),
|
||||
$o = replace_macros(get_markup_template('item_import.tpl'), [
|
||||
'$title' => t('Import Items'),
|
||||
'$desc' => t('Use this form to import existing posts and content from an export file.'),
|
||||
'$label_filename' => t('File to Upload'),
|
||||
'$form_security_token' => get_form_security_token('import_items'),
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
'$submit' => t('Submit')
|
||||
]);
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
public static function import($channel, $data) {
|
||||
|
||||
if (!$data) {
|
||||
logger('Empty file.');
|
||||
notice(t('Imported file is empty.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$data = json_decode($data, true);
|
||||
//logger('import: data: ' . print_r($data,true));
|
||||
//print_r($data);
|
||||
|
||||
if (!is_array($data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//if (array_key_exists('compatibility', $data) && array_key_exists('database', $data['compatibility'])) {
|
||||
//$v1 = substr($data['compatibility']['database'], -4);
|
||||
//$v2 = substr(DB_UPDATE_VERSION, -4);
|
||||
//if ($v2 > $v1) {
|
||||
//$t = sprintf(t('Warning: Database versions differ by %1$d updates.'), $v2 - $v1);
|
||||
//notice($t . EOL);
|
||||
//}
|
||||
//}
|
||||
|
||||
if (array_key_exists('item', $data) && is_array($data['item'])) {
|
||||
import_items($channel, $data['item'], false, ((array_key_exists('relocate', $data)) ? $data['relocate'] : null));
|
||||
info(t('Content import completed') . EOL);
|
||||
}
|
||||
|
||||
if (array_key_exists('chatroom', $data) && is_array($data['chatroom'])) {
|
||||
import_chatrooms($channel, $data['chatroom']);
|
||||
info(t('Chatroom import completed') . EOL);
|
||||
|
||||
}
|
||||
|
||||
if (array_key_exists('event', $data) && is_array($data['event'])) {
|
||||
import_events($channel, $data['event']);
|
||||
info(t('Channel calendar import 1/2 completed') . EOL);
|
||||
|
||||
}
|
||||
|
||||
if (array_key_exists('event_item', $data) && is_array($data['event_item'])) {
|
||||
import_items($channel, $data['event_item'], false, ((array_key_exists('relocate', $data)) ? $data['relocate'] : null));
|
||||
info(t('Channel calendar import 2/2 completed') . EOL);
|
||||
}
|
||||
|
||||
if (array_key_exists('menu', $data) && is_array($data['menu'])) {
|
||||
import_menus($channel, $data['menu']);
|
||||
info(t('Menu import completed') . EOL);
|
||||
}
|
||||
|
||||
if (array_key_exists('wiki', $data) && is_array($data['wiki'])) {
|
||||
import_items($channel, $data['wiki'], false, ((array_key_exists('relocate', $data)) ? $data['relocate'] : null));
|
||||
info(t('Wiki import completed') . EOL);
|
||||
}
|
||||
|
||||
if (array_key_exists('webpages', $data) && is_array($data['webpages'])) {
|
||||
import_items($channel, $data['webpages'], false, ((array_key_exists('relocate', $data)) ? $data['relocate'] : null));
|
||||
info(t('Webpages import completed') . EOL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
115
Zotlabs/Module/Import_progress.php
Normal file
115
Zotlabs/Module/Import_progress.php
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use Zotlabs\Lib\PConfig;
|
||||
use Zotlabs\Daemon\Master;
|
||||
|
||||
class Import_progress extends \Zotlabs\Web\Controller {
|
||||
|
||||
function post() {
|
||||
|
||||
if(! local_channel())
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
function get() {
|
||||
|
||||
if(! local_channel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nav_set_selected('Channel Import');
|
||||
|
||||
// items
|
||||
$c = PConfig::Get(local_channel(), 'import', 'content_progress');
|
||||
|
||||
if ($c) {
|
||||
$total_cpages = floor(intval($c['items_total']) / intval($c['items_page']));
|
||||
if(!$total_cpages) {
|
||||
$total_cpages = 1; // because of floor
|
||||
}
|
||||
|
||||
$cpage = $c['last_page'] + 1; // because page count start at 0
|
||||
|
||||
$cprogress = intval(floor((intval($cpage) * 100) / $total_cpages));
|
||||
$ccompleted_str = t('Item sync completed!');
|
||||
|
||||
if(argv(1) === 'resume_itemsync' && $cprogress < 100) {
|
||||
Master::Summon($c['next_cmd']);
|
||||
goaway('/import_progress');
|
||||
}
|
||||
}
|
||||
else {
|
||||
$cprogress = 'waiting to start...';
|
||||
|
||||
if (PConfig::Get(local_channel(), 'import', 'content_completed')) {
|
||||
// There was nothing todo. Fake 100% and mention that there were no files found
|
||||
$cprogress = 100;
|
||||
}
|
||||
|
||||
$ccompleted_str = t('Item sync completed but no items were found!');
|
||||
}
|
||||
|
||||
$cprogress_str = ((intval($cprogress)) ? $cprogress . '%' : $cprogress);
|
||||
|
||||
// files
|
||||
$f = PConfig::Get(local_channel(), 'import', 'files_progress');
|
||||
|
||||
if ($f) {
|
||||
$total_fpages = floor(intval($f['files_total']) / intval($f['files_page']));
|
||||
if(!$total_fpages) {
|
||||
$total_fpages = 1;
|
||||
}
|
||||
|
||||
$fpage = $f['last_page'] + 1;
|
||||
|
||||
$fprogress = intval(floor((intval($fpage) * 100) / $total_fpages));
|
||||
$fcompleted_str = t('File sync completed!');
|
||||
|
||||
if(argv(1) === 'resume_filesync' && $fprogress < 100) {
|
||||
Master::Summon($f['next_cmd']);
|
||||
goaway('/import_progress');
|
||||
}
|
||||
}
|
||||
else {
|
||||
$fprogress = 'waiting to start...';
|
||||
|
||||
if (PConfig::Get(local_channel(), 'import', 'files_completed')) {
|
||||
// There was nothing todo. Fake 100% and mention that there were no files found
|
||||
$fprogress = 100;
|
||||
}
|
||||
|
||||
$fcompleted_str = t('File sync completed but no files were found!');
|
||||
}
|
||||
|
||||
$fprogress_str = ((intval($fprogress)) ? $fprogress . '%' : $fprogress);
|
||||
|
||||
if(is_ajax()) {
|
||||
$ret = [
|
||||
'cprogress' => $cprogress,
|
||||
'fprogress' => $fprogress
|
||||
];
|
||||
|
||||
json_return_and_die($ret);
|
||||
}
|
||||
|
||||
$o = replace_macros(get_markup_template("import_progress.tpl"), [
|
||||
'$chtitle_str' => t('Channel clone status'),
|
||||
'$ctitle_str' => t('Item sync status'),
|
||||
'$ftitle_str' => t('File sync status'),
|
||||
'$cprogress_str' => $cprogress_str,
|
||||
'$cprogress' => intval($cprogress),
|
||||
'$fprogress_str' => $fprogress_str,
|
||||
'$fprogress' => intval($fprogress),
|
||||
'$fcompleted_str' => $fcompleted_str,
|
||||
'$ccompleted_str' => $ccompleted_str,
|
||||
'$chcompleted_str' => t('Channel cloning completed!'),
|
||||
'$resume_str' => t('Resume'),
|
||||
'$resume_helper_str' => t('Only resume if sync stalled!')
|
||||
]);
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -129,11 +129,11 @@ class Invite extends Controller {
|
||||
if(! $recip) continue;
|
||||
|
||||
// see if we have an email address who@domain.tld
|
||||
if (!preg_match('/^.{2,64}\@[a-z0-9.-]{4,32}\.[a-z]{2,12}$/', $recip)) {
|
||||
$feedbk .= 'ZAI0203E ' . ($n+1) . ': ' . sprintf( t('(%s) : Not a valid email address'), $recip) . $eol;
|
||||
$ko++;
|
||||
continue;
|
||||
}
|
||||
//if (!preg_match('/^.{2,64}\@[a-z0-9.-]{2,32}\.[a-z]{2,12}$/', $recip)) {
|
||||
//$feedbk .= 'ZAI0203E ' . ($n+1) . ': ' . sprintf( t('(%s) : Not a valid email address'), $recip) . $eol;
|
||||
//$ko++;
|
||||
//continue;
|
||||
//}
|
||||
if(! validate_email($recip)) {
|
||||
$feedbk .= 'ZAI0204E ' . ($n+1) . ': ' . sprintf( t('(%s) : Not a real email address'), $recip) . $eol;
|
||||
$ko++;
|
||||
@@ -225,7 +225,7 @@ class Invite extends Controller {
|
||||
'$projectname' => t('$Projectname'),
|
||||
'$invite_code' => $invite_code,
|
||||
'$invite_where' => z_root() . '/register',
|
||||
'$invite_whereami' => str_replace('@', '@+', $reonar['whereami']),
|
||||
'$invite_whereami' => $reonar['whereami'],
|
||||
'$invite_whoami' => z_root() . '/channel/' . $reonar['whoami'],
|
||||
'$invite_anywhere' => z_root() . '/pubsites'
|
||||
)
|
||||
@@ -422,8 +422,6 @@ class Invite extends Controller {
|
||||
// let take one descriptive for template (as said is never used)
|
||||
$invite_code = 'INVITATE2020';
|
||||
|
||||
// what languages we use now
|
||||
$lccmy = ((isset(App::$config['system']['language'])) ? App::$config['system']['language'] : 'en');
|
||||
// and all the localized templates belonging to invite
|
||||
$tpls = glob('view/*/invite.*.tpl');
|
||||
|
||||
@@ -444,6 +442,9 @@ class Invite extends Controller {
|
||||
$langs = array_keys($tpla);
|
||||
asort($langs);
|
||||
|
||||
// Use the current language if we have a template for it. Otherwise fall back to 'en'.
|
||||
$lccmy = ((in_array(App::$language, $langs)) ? App::$language : 'en');
|
||||
|
||||
$tplx = array_unique($tplx);
|
||||
asort($tplx);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -72,7 +72,7 @@ class Layouts extends \Zotlabs\Web\Controller {
|
||||
return;
|
||||
}
|
||||
|
||||
// Block design features from visitors
|
||||
// Block design features from visitors
|
||||
|
||||
if((! $uid) || ($uid != $owner)) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
@@ -95,8 +95,8 @@ class Layouts extends \Zotlabs\Web\Controller {
|
||||
// Use the buildin share/install feature instead.
|
||||
|
||||
if((argc() > 3) && (argv(2) === 'share') && (argv(3))) {
|
||||
$r = q("select iconfig.v, iconfig.k, mimetype, title, body from iconfig
|
||||
left join item on item.id = iconfig.iid
|
||||
$r = q("select iconfig.v, iconfig.k, mimetype, title, body from iconfig
|
||||
left join item on item.id = iconfig.iid
|
||||
where uid = %d and mid = '%s' and iconfig.cat = 'system' and iconfig.k = 'PDL' order by iconfig.v asc",
|
||||
intval($owner),
|
||||
dbesc(argv(3))
|
||||
@@ -110,7 +110,7 @@ class Layouts extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
// Create a status editor (for now - we'll need a WYSIWYG eventually) to create pages
|
||||
// Nickname is set to the observers xchan, and profile_uid to the owners.
|
||||
// Nickname is set to the observers xchan, and profile_uid to the owners.
|
||||
// This lets you post pages at other people's channels.
|
||||
|
||||
$x = array(
|
||||
@@ -134,16 +134,14 @@ class Layouts extends \Zotlabs\Web\Controller {
|
||||
'bbco_autocomplete' => 'comanche'
|
||||
);
|
||||
|
||||
if($_REQUEST['title'])
|
||||
$x['title'] = $_REQUEST['title'];
|
||||
if($_REQUEST['body'])
|
||||
$x['body'] = $_REQUEST['body'];
|
||||
if($_REQUEST['pagetitle'])
|
||||
$x['pagetitle'] = $_REQUEST['pagetitle'];
|
||||
$x['title'] = $_REQUEST['title'] ?? '';
|
||||
$x['body'] = $_REQUEST['body'] ?? '';
|
||||
$x['pagetitle'] = $_REQUEST['pagetitle'] ?? '';
|
||||
|
||||
$a = '';
|
||||
$editor = status_editor($a,$x,false,'Layouts');
|
||||
|
||||
$r = q("select iconfig.iid, iconfig.v, mid, title, body, mimetype, created, edited, item_type from iconfig
|
||||
$r = q("select iconfig.iid, iconfig.v, mid, title, body, mimetype, created, edited, item_type from iconfig
|
||||
left join item on iconfig.iid = item.id
|
||||
where uid = %d and iconfig.cat = 'system' and iconfig.k = 'PDL' and item_type = %d order by item.created desc",
|
||||
intval($owner),
|
||||
@@ -178,9 +176,9 @@ class Layouts extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
//Build the base URL for edit links
|
||||
$url = z_root() . '/editlayout/' . $which;
|
||||
$url = z_root() . '/editlayout/' . $which;
|
||||
|
||||
$o .= replace_macros(get_markup_template('layoutlist.tpl'), array(
|
||||
$o = replace_macros(get_markup_template('layoutlist.tpl'), array(
|
||||
'$title' => t('Layouts'),
|
||||
'$create' => t('Create'),
|
||||
'$help' => array('text' => t('Help'), 'url' => 'help/comanche', 'title' => t('Comanche page description language help')),
|
||||
|
||||
@@ -91,6 +91,12 @@ class Like extends Controller {
|
||||
'id' => $arr['item']['id'],
|
||||
'html' => conversation($items, $conv_mode, true, $page_mode),
|
||||
];
|
||||
|
||||
// mod photos
|
||||
if (isset($_REQUEST['reload']) && $_REQUEST['reload']) {
|
||||
$ret['reload'] = 1;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
||||
}
|
||||
@@ -100,7 +106,7 @@ class Like extends Controller {
|
||||
$o = EMPTY_STR;
|
||||
$sys_channel = get_sys_channel();
|
||||
$observer = App::get_observer();
|
||||
$interactive = $_REQUEST['interactive'];
|
||||
$interactive = $_REQUEST['interactive'] ?? false;
|
||||
|
||||
if ((!$observer) || ($interactive)) {
|
||||
$o .= '<h1>' . t('Like/Dislike') . '</h1>';
|
||||
@@ -134,7 +140,7 @@ class Like extends Controller {
|
||||
$extended_like = false;
|
||||
$object = $target = null;
|
||||
$post_type = EMPTY_STR;
|
||||
$objtype = EMPTY_STR;
|
||||
$obj_type = EMPTY_STR;
|
||||
|
||||
if (argc() == 3) {
|
||||
|
||||
@@ -176,7 +182,7 @@ class Like extends Controller {
|
||||
}
|
||||
}
|
||||
$post_type = t('channel');
|
||||
$objtype = ACTIVITY_OBJ_PROFILE;
|
||||
$obj_type = ACTIVITY_OBJ_PROFILE;
|
||||
|
||||
$profile = $r[0];
|
||||
}
|
||||
@@ -205,7 +211,7 @@ class Like extends Controller {
|
||||
$public = false;
|
||||
|
||||
$post_type = t('thing');
|
||||
$objtype = ACTIVITY_OBJ_PROFILE;
|
||||
$obj_type = ACTIVITY_OBJ_PROFILE;
|
||||
$tgttype = ACTIVITY_OBJ_THING;
|
||||
|
||||
$links = array();
|
||||
@@ -267,7 +273,7 @@ class Like extends Controller {
|
||||
intval($ch[0]['channel_id']),
|
||||
dbesc($observer['xchan_hash']),
|
||||
dbesc($activity),
|
||||
dbesc(($tgttype) ? $tgttype : $objtype),
|
||||
dbesc(($tgttype) ? $tgttype : $obj_type),
|
||||
dbesc($obj_id)
|
||||
);
|
||||
|
||||
@@ -440,10 +446,10 @@ class Like extends Controller {
|
||||
if ($item['obj_type'] === ACTIVITY_OBJ_EVENT)
|
||||
$post_type = t('event');
|
||||
|
||||
$objtype = (($item['resource_type'] === 'photo') ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE);
|
||||
$obj_type = (($item['resource_type'] === 'photo') ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE);
|
||||
|
||||
if ($objtype === ACTIVITY_OBJ_NOTE && (!intval($item['item_thread_top'])))
|
||||
$objtype = ACTIVITY_OBJ_COMMENT;
|
||||
if ($obj_type === ACTIVITY_OBJ_NOTE && (!intval($item['item_thread_top'])))
|
||||
$obj_type = ACTIVITY_OBJ_COMMENT;
|
||||
|
||||
$object = json_encode(Activity::fetch_item(['id' => $item['mid']]));
|
||||
|
||||
@@ -502,7 +508,7 @@ class Like extends Controller {
|
||||
$allow_gid = $item['allow_gid'];
|
||||
$deny_cid = $item['deny_cid'];
|
||||
$deny_gid = $item['deny_gid'];
|
||||
$private = $item['private'];
|
||||
$private = $item['item_private'];
|
||||
|
||||
}
|
||||
|
||||
@@ -527,7 +533,7 @@ class Like extends Controller {
|
||||
}
|
||||
|
||||
$arr['verb'] = $activity;
|
||||
$arr['obj_type'] = $objtype;
|
||||
$arr['obj_type'] = $obj_type;
|
||||
$arr['obj'] = $object;
|
||||
|
||||
if ($target) {
|
||||
@@ -563,7 +569,7 @@ class Like extends Controller {
|
||||
intval($post_id),
|
||||
dbesc($arr['mid']),
|
||||
dbesc($activity),
|
||||
dbesc(($tgttype) ? $tgttype : $objtype),
|
||||
dbesc(($tgttype) ? $tgttype : $obj_type),
|
||||
dbesc($obj_id),
|
||||
dbesc(($target) ? $target : $object)
|
||||
);
|
||||
@@ -572,7 +578,7 @@ class Like extends Controller {
|
||||
dbesc($ch[0]['channel_hash']),
|
||||
dbesc($arr['mid']),
|
||||
dbesc($activity),
|
||||
dbesc(($tgttype) ? $tgttype : $objtype),
|
||||
dbesc(($tgttype) ? $tgttype : $obj_type),
|
||||
dbesc($obj_id)
|
||||
);
|
||||
if ($r)
|
||||
|
||||
@@ -29,6 +29,9 @@ class Linkinfo extends \Zotlabs\Web\Controller {
|
||||
if((substr($url,0,1) != '/') && (substr($url,0,4) != 'http'))
|
||||
$url = 'http://' . $url;
|
||||
|
||||
$x = parse_url($url);
|
||||
if ($x)
|
||||
$url = str_replace($x['host'], punify($x['host']), $url);
|
||||
|
||||
if($_GET['title'])
|
||||
$title = strip_tags(trim($_GET['title']));
|
||||
|
||||
@@ -1,21 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use Zotlabs\Lib\AccessList;
|
||||
use Zotlabs\Web\Controller;
|
||||
|
||||
require_once('include/security.php');
|
||||
|
||||
class Lockview extends \Zotlabs\Web\Controller {
|
||||
class Lockview extends Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
$atokens = array();
|
||||
$atokens = [];
|
||||
$atoken_xchans = [];
|
||||
$access_list = [];
|
||||
$guest_access_list = [];
|
||||
|
||||
if(local_channel()) {
|
||||
if (local_channel()) {
|
||||
$at = q("select * from atoken where atoken_uid = %d",
|
||||
intval(local_channel())
|
||||
);
|
||||
if($at) {
|
||||
foreach($at as $t) {
|
||||
$atokens[] = atoken_xchan($t);
|
||||
if ($at) {
|
||||
foreach ($at as $t) {
|
||||
$atoken_xchan = atoken_xchan($t);
|
||||
$atokens[] = array_merge($t, $atoken_xchan);
|
||||
$atoken_xchans[] = $atoken_xchan['xchan_hash'];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,20 +32,20 @@ class Lockview extends \Zotlabs\Web\Controller {
|
||||
$type = ((argc() > 1) ? argv(1) : 0);
|
||||
if (is_numeric($type)) {
|
||||
$item_id = intval($type);
|
||||
$type='item';
|
||||
$type = 'item';
|
||||
}
|
||||
else {
|
||||
$item_id = ((argc() > 2) ? intval(argv(2)) : 0);
|
||||
}
|
||||
|
||||
if(! $item_id)
|
||||
if (!$item_id)
|
||||
killme();
|
||||
|
||||
if (! in_array($type, array('item', 'photo', 'attach', 'event', 'menu_item', 'chatroom')))
|
||||
if (!in_array($type, ['item', 'photo', 'attach', 'menu_item', 'chatroom']))
|
||||
killme();
|
||||
|
||||
// we have different naming in in menu_item table and chatroom table
|
||||
switch($type) {
|
||||
switch ($type) {
|
||||
case 'menu_item':
|
||||
$id = 'mitem_id';
|
||||
break;
|
||||
@@ -53,134 +62,177 @@ class Lockview extends \Zotlabs\Web\Controller {
|
||||
intval($item_id)
|
||||
);
|
||||
|
||||
if(! $r)
|
||||
if (!$r)
|
||||
killme();
|
||||
|
||||
$item = $r[0];
|
||||
$uid = null;
|
||||
$url = '';
|
||||
|
||||
//we have different naming in in menu_item table and chatroom table
|
||||
switch($type) {
|
||||
switch ($type) {
|
||||
case 'menu_item':
|
||||
$uid = $item['mitem_channel_id'];
|
||||
break;
|
||||
case 'chatroom':
|
||||
$uid = $item['cr_uid'];
|
||||
$uid = $item['cr_uid'];
|
||||
$channel = channelx_by_n($uid);
|
||||
$url = z_root() . '/chat/' . $channel['channel_address'] . '/' . $item['cr_id'];
|
||||
break;
|
||||
case 'item':
|
||||
$uid = $item['uid'];
|
||||
$url = $item['plink'];
|
||||
break;
|
||||
case 'photo':
|
||||
$uid = $item['uid'];
|
||||
$channel = channelx_by_n($uid);
|
||||
$url = z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $item['resource_id'];
|
||||
break;
|
||||
case 'attach':
|
||||
$uid = $item['uid'];
|
||||
$channel = channelx_by_n($uid);
|
||||
$url = z_root() . '/cloud/' . $channel['channel_address'] . '/' . $item['display_path'];
|
||||
break;
|
||||
default:
|
||||
$uid = $item['uid'];
|
||||
break;
|
||||
}
|
||||
|
||||
if($uid != local_channel()) {
|
||||
echo '<div class="dropdown-item">' . t('Remote privacy information not available.') . '</div>';
|
||||
if (intval($uid) !== local_channel()) {
|
||||
echo '<div class="dropdown-item-text">' . t('Remote privacy information not available') . '</div>';
|
||||
killme();
|
||||
}
|
||||
|
||||
if(intval($item['item_private']) && (! strlen($item['allow_cid'])) && (! strlen($item['allow_gid']))
|
||||
&& (! strlen($item['deny_cid'])) && (! strlen($item['deny_gid']))) {
|
||||
if ((isset($item['item_private']) && intval($item['item_private'])) && (!strlen($item['allow_cid'])) && (!strlen($item['allow_gid']))
|
||||
&& (!strlen($item['deny_cid'])) && (!strlen($item['deny_gid']))) {
|
||||
|
||||
// if the post is private, but public_policy is blank ("visible to the internet"), and there aren't any
|
||||
// specific recipients, we're the recipient of a post with "bcc" or targeted recipients; so we'll just show it
|
||||
// as unknown specific recipients. The sender will have the visibility list and will fall through to the
|
||||
// next section.
|
||||
|
||||
echo '<div class="dropdown-item">' . translate_scope((! $item['public_policy']) ? 'specific' : $item['public_policy']) . '</div>';
|
||||
echo '<div class="dropdown-item-text">' . translate_scope((!$item['public_policy']) ? 'specific' : $item['public_policy']) . '</div>';
|
||||
killme();
|
||||
}
|
||||
|
||||
$allowed_users = expand_acl($item['allow_cid']);
|
||||
$allowed_users = expand_acl($item['allow_cid']);
|
||||
$allowed_groups = expand_acl($item['allow_gid']);
|
||||
$deny_users = expand_acl($item['deny_cid']);
|
||||
$deny_groups = expand_acl($item['deny_gid']);
|
||||
$deny_users = expand_acl($item['deny_cid']);
|
||||
$deny_groups = expand_acl($item['deny_gid']);
|
||||
|
||||
$o = '<div class="dropdown-item">' . t('Visible to:') . '</div>';
|
||||
$l = array();
|
||||
|
||||
stringify_array_elms($allowed_groups,true);
|
||||
stringify_array_elms($allowed_users,true);
|
||||
stringify_array_elms($deny_groups,true);
|
||||
stringify_array_elms($deny_users,true);
|
||||
stringify_array_elms($allowed_groups, true);
|
||||
stringify_array_elms($allowed_users, true);
|
||||
stringify_array_elms($deny_groups, true);
|
||||
stringify_array_elms($deny_users, true);
|
||||
|
||||
$allowed_xchans = [];
|
||||
|
||||
$profile_groups = [];
|
||||
if($allowed_groups) {
|
||||
foreach($allowed_groups as $g) {
|
||||
if(substr($g,0,4) === '\'vp.') {
|
||||
$profile_groups[] = '\'' . substr($g,4);
|
||||
if ($allowed_groups) {
|
||||
foreach ($allowed_groups as $g) {
|
||||
if (substr($g, 0, 4) === '\'vp.') {
|
||||
$profile_groups[] = '\'' . substr($g, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(count($profile_groups)) {
|
||||
$r = q("SELECT profile_name FROM profile WHERE profile_guid IN ( " . implode(', ', $profile_groups) . " )");
|
||||
if($r)
|
||||
foreach($r as $rr)
|
||||
$l[] = '<div class="dropdown-item"><b>' . t('Profile','acl') . ' ' . $rr['profile_name'] . '</b></div>';
|
||||
|
||||
if ($profile_groups) {
|
||||
$r = q("SELECT id, profile_name FROM profile WHERE profile_guid IN ( " . implode(', ', $profile_groups) . " )");
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
$pgrp_members = AccessList::profile_members_xchan($uid, $rr['id']);
|
||||
$allowed_xchans = array_merge($allowed_xchans, $pgrp_members);
|
||||
$access_list[] = '<div class="dropdown-item-text" title="' . t('Profile', 'acl') . '">' . $rr['profile_name'] . '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(count($allowed_groups)) {
|
||||
$r = q("SELECT gname FROM pgrp WHERE hash IN ( " . implode(', ', $allowed_groups) . " )");
|
||||
if($r)
|
||||
foreach($r as $rr)
|
||||
$l[] = '<div class="dropdown-item"><b>' . $rr['gname'] . '</b></div>';
|
||||
if ($allowed_groups) {
|
||||
$r = q("SELECT id, gname FROM pgrp WHERE hash IN ( " . implode(', ', $allowed_groups) . " )");
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
$pgrp_members = AccessList::members_xchan($uid, $rr['id']);
|
||||
$allowed_xchans = array_merge($allowed_xchans, $pgrp_members);
|
||||
$access_list[] = '<div class="dropdown-item-text" title="' . t('Privacy group') . '">' . $rr['gname'] . '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
if(count($allowed_users)) {
|
||||
$r = q("SELECT xchan_name FROM xchan WHERE xchan_hash IN ( " . implode(', ',$allowed_users) . " )");
|
||||
if($r)
|
||||
foreach($r as $rr)
|
||||
$l[] = '<div class="dropdown-item">' . $rr['xchan_name'] . '</div>';
|
||||
if($atokens) {
|
||||
foreach($atokens as $at) {
|
||||
if(in_array("'" . $at['xchan_hash'] . "'",$allowed_users)) {
|
||||
$l[] = '<div class="dropdown-item">' . $at['xchan_name'] . '</div>';
|
||||
|
||||
if ($allowed_users) {
|
||||
$r = q("SELECT xchan_name, xchan_hash FROM xchan WHERE xchan_hash IN ( " . implode(', ', $allowed_users) . " )");
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
$allowed_xchans[] = $rr['xchan_hash'];
|
||||
if (!in_array($rr['xchan_hash'], $atoken_xchans)) {
|
||||
$access_list[] = '<div class="dropdown-item-text">' . $rr['xchan_name'] . '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$profile_groups = [];
|
||||
if($deny_groups) {
|
||||
foreach($deny_groups as $g) {
|
||||
if(substr($g,0,4) === '\'vp.') {
|
||||
$profile_groups[] = '\'' . substr($g,4);
|
||||
if ($deny_groups) {
|
||||
foreach ($deny_groups as $g) {
|
||||
if (substr($g, 0, 4) === '\'vp.') {
|
||||
$profile_groups[] = '\'' . substr($g, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(count($profile_groups)) {
|
||||
|
||||
if ($profile_groups) {
|
||||
$r = q("SELECT profile_name FROM profile WHERE profile_guid IN ( " . implode(', ', $profile_groups) . " )");
|
||||
if($r)
|
||||
foreach($r as $rr)
|
||||
$l[] = '<div class="dropdown-item"><b><strike>' . t('Profile','acl') . ' ' . $rr['profile_name'] . '</strike></b></div>';
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
$access_list[] = '<div class="dropdown-item-text" title="' . t('Profile', 'acl') . '"><strike>' . $rr['profile_name'] . '</strike></b></div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(count($deny_groups)) {
|
||||
if ($deny_groups) {
|
||||
$r = q("SELECT gname FROM pgrp WHERE hash IN ( " . implode(', ', $deny_groups) . " )");
|
||||
if($r)
|
||||
foreach($r as $rr)
|
||||
$l[] = '<div class="dropdown-item"><b><strike>' . $rr['gname'] . '</strike></b></div>';
|
||||
}
|
||||
if(count($deny_users)) {
|
||||
$r = q("SELECT xchan_name FROM xchan WHERE xchan_hash IN ( " . implode(', ', $deny_users) . " )");
|
||||
if($r)
|
||||
foreach($r as $rr)
|
||||
$l[] = '<div class="dropdown-item"><strike>' . $rr['xchan_name'] . '</strike></div>';
|
||||
|
||||
if($atokens) {
|
||||
foreach($atokens as $at) {
|
||||
if(in_array("'" . $at['xchan_hash'] . "'",$deny_users)) {
|
||||
$l[] = '<div class="dropdown-item"><strike>' . $at['xchan_name'] . '</strike></div>';
|
||||
}
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
$access_list[] = '<div class="dropdown-item-text" title="' . t('Privacy group') . '"><strike>' . $rr['gname'] . '</strike></b></div>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
echo $o . implode($l);
|
||||
killme();
|
||||
if ($deny_users) {
|
||||
$r = q("SELECT xchan_name FROM xchan WHERE xchan_hash IN ( " . implode(', ', $deny_users) . " )");
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
$access_list[] = '<div class="dropdown-item-text"><strike>' . $rr['xchan_name'] . '</strike></div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($atokens && $allowed_xchans && $url) {
|
||||
|
||||
$guest_access_list = [];
|
||||
|
||||
$allowed_xchans = array_unique($allowed_xchans);
|
||||
foreach ($atokens as $atoken) {
|
||||
if (in_array($atoken['xchan_hash'], $allowed_xchans)) {
|
||||
$guest_access_list[] = '<div class="dropdown-item d-flex justify-content-between cursor-pointer" title="' . sprintf(t('Click to copy link to this ressource for guest %s to clipboard'), $atoken['xchan_name']) . '" data-token="' . $url . '?zat=' . $atoken['atoken_token'] . '" onclick="navigator.clipboard.writeText(this.dataset.token); $.jGrowl(\'' . t('Link copied') . '\', { sticky: false, theme: \'info\', life: 1000 });"><span>' . $atoken['xchan_name'] . '</span><i class="fa fa-copy p-1"></i></div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$access_list_header = '';
|
||||
if ($access_list) {
|
||||
$access_list_header = '<div class="dropdown-header text-uppercase h6">' . t('Access') . '</div>';
|
||||
}
|
||||
|
||||
$guest_access_list_header = '';
|
||||
if ($guest_access_list) {
|
||||
$guest_access_list_header = '<div class="dropdown-header text-uppercase h6">' . t('Guest access') . '</div>';
|
||||
}
|
||||
|
||||
$divider = '';
|
||||
if ($access_list && $guest_access_list) {
|
||||
$divider = '<div class="dropdown-divider"></div>';
|
||||
}
|
||||
|
||||
echo $access_list_header . implode($access_list) . $divider . $guest_access_list_header . implode($guest_access_list);
|
||||
killme();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -116,11 +116,6 @@ class Locs extends Controller {
|
||||
return;
|
||||
}
|
||||
|
||||
for($x = 0; $x < count($r); $x ++) {
|
||||
$r[$x]['primary'] = (intval($r[$x]['hubloc_primary']) ? true : false);
|
||||
$r[$x]['deleted'] = (intval($r[$x]['hubloc_deleted']) ? true : false);
|
||||
}
|
||||
|
||||
$o = replace_macros(get_markup_template('locmanage.tpl'), array(
|
||||
'$header' => t('Manage Channel Locations'),
|
||||
'$loc' => t('Location'),
|
||||
@@ -132,7 +127,8 @@ class Locs extends Controller {
|
||||
'$sync_text' => t('Please wait several minutes between consecutive operations.'),
|
||||
'$drop_text' => t('When possible, drop a location by logging into that website/hub and removing your channel.'),
|
||||
'$last_resort' => t('Use this form to drop the location if the hub is no longer operating.'),
|
||||
'$hubs' => $r
|
||||
'$hubs' => $r,
|
||||
'$base_url' => z_root()
|
||||
));
|
||||
|
||||
return $o;
|
||||
|
||||
@@ -6,32 +6,32 @@ namespace Zotlabs\Module;
|
||||
class Lostpass extends \Zotlabs\Web\Controller {
|
||||
|
||||
function post() {
|
||||
|
||||
|
||||
$loginame = notags(trim($_POST['login-name']));
|
||||
if(! $loginame)
|
||||
goaway(z_root());
|
||||
|
||||
|
||||
$r = q("SELECT * FROM account WHERE account_email = '%s' LIMIT 1",
|
||||
dbesc($loginame)
|
||||
);
|
||||
|
||||
|
||||
if(! $r) {
|
||||
notice( t('No valid account found.') . EOL);
|
||||
goaway(z_root());
|
||||
}
|
||||
|
||||
|
||||
$aid = $r[0]['account_id'];
|
||||
$email = $r[0]['account_email'];
|
||||
|
||||
|
||||
$hash = random_string();
|
||||
|
||||
|
||||
$r = q("UPDATE account SET account_reset = '%s' WHERE account_id = %d",
|
||||
dbesc($hash),
|
||||
intval($aid)
|
||||
);
|
||||
if($r)
|
||||
info( t('Password reset request issued. Check your email.') . EOL);
|
||||
|
||||
|
||||
$email_tpl = get_intltext_template("lostpass_eml.tpl");
|
||||
$message = replace_macros($email_tpl, array(
|
||||
'$sitename' => get_config('system','sitename'),
|
||||
@@ -40,11 +40,11 @@ class Lostpass extends \Zotlabs\Web\Controller {
|
||||
'$email' => $email,
|
||||
'$reset_link' => z_root() . '/lostpass?verify=' . $hash
|
||||
));
|
||||
|
||||
|
||||
$subject = email_header_encode(sprintf( t('Password reset requested at %s'),get_config('system','sitename')), 'UTF-8');
|
||||
|
||||
|
||||
$res = z_mail(
|
||||
[
|
||||
[
|
||||
'toEmail' => $email,
|
||||
'messageSubject' => sprintf( t('Password reset requested at %s'), get_config('system','sitename')),
|
||||
'textVersion' => $message,
|
||||
@@ -53,14 +53,14 @@ class Lostpass extends \Zotlabs\Web\Controller {
|
||||
|
||||
goaway(z_root());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
|
||||
|
||||
|
||||
if(x($_GET,'verify')) {
|
||||
$verify = $_GET['verify'];
|
||||
|
||||
|
||||
$r = q("SELECT * FROM account WHERE account_reset = '%s' LIMIT 1",
|
||||
dbesc($verify)
|
||||
);
|
||||
@@ -69,25 +69,25 @@ class Lostpass extends \Zotlabs\Web\Controller {
|
||||
goaway(z_root());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$aid = $r[0]['account_id'];
|
||||
$email = $r[0]['account_email'];
|
||||
|
||||
|
||||
$new_password = autoname(6) . mt_rand(100,9999);
|
||||
|
||||
|
||||
$salt = random_string(32);
|
||||
$password_encoded = hash('whirlpool', $salt . $new_password);
|
||||
|
||||
|
||||
$r = q("UPDATE account SET account_salt = '%s', account_password = '%s', account_reset = '', account_flags = (account_flags & ~%d) where account_id = %d",
|
||||
dbesc($salt),
|
||||
dbesc($password_encoded),
|
||||
intval(ACCOUNT_UNVERIFIED),
|
||||
intval($aid)
|
||||
);
|
||||
|
||||
|
||||
if($r) {
|
||||
$tpl = get_markup_template('pwdreset.tpl');
|
||||
$o .= replace_macros($tpl,array(
|
||||
$o = replace_macros($tpl,array(
|
||||
'$lbl1' => t('Password Reset'),
|
||||
'$lbl2' => t('Your password has been reset as requested.'),
|
||||
'$lbl3' => t('Your new password is'),
|
||||
@@ -96,23 +96,23 @@ class Lostpass extends \Zotlabs\Web\Controller {
|
||||
'$lbl6' => t('Your password may be changed from the <em>Settings</em> page after successful login.'),
|
||||
'$newpass' => $new_password,
|
||||
'$baseurl' => z_root()
|
||||
|
||||
|
||||
));
|
||||
|
||||
|
||||
info("Your password has been reset." . EOL);
|
||||
|
||||
|
||||
$email_tpl = get_intltext_template("passchanged_eml.tpl");
|
||||
$message = replace_macros($email_tpl, array(
|
||||
'$sitename' => \App::$config['sitename'],
|
||||
'$siteurl' => z_root(),
|
||||
'$username' => sprintf( t('Site Member (%s)'), $email),
|
||||
'$email' => $email,
|
||||
'$new_password' => $new_password,
|
||||
'$uid' => $newuid )
|
||||
'$new_password' => $new_password
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
$res = z_mail(
|
||||
[
|
||||
[
|
||||
'toEmail' => $email,
|
||||
'messageSubject' => sprintf( t('Your password has changed at %s'), get_config('system','sitename')),
|
||||
'textVersion' => $message,
|
||||
@@ -121,21 +121,21 @@ class Lostpass extends \Zotlabs\Web\Controller {
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
$tpl = get_markup_template('lostpass.tpl');
|
||||
|
||||
$o .= replace_macros($tpl,array(
|
||||
|
||||
$o = replace_macros($tpl,array(
|
||||
'$title' => t('Forgot your Password?'),
|
||||
'$desc' => t('Enter your email address and submit to have your password reset. Then check your email for further instructions.'),
|
||||
'$name' => t('Email Address'),
|
||||
'$submit' => t('Reset')
|
||||
'$submit' => t('Reset')
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ class Manage extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
if((! get_account_id()) || ($_SESSION['delegate'])) {
|
||||
if((! get_account_id()) || (isset($_SESSION['delegate']) && $_SESSION['delegate'])) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
@@ -61,7 +61,7 @@ class Manage extends \Zotlabs\Web\Controller {
|
||||
$channels[$x]['default'] = (($channels[$x]['channel_id'] == $account['account_default_channel']) ? "1" : '');
|
||||
$channels[$x]['default_links'] = '1';
|
||||
|
||||
|
||||
/* this is not currently implemented in the UI and probably should not (performance)
|
||||
$c = q("SELECT id, item_wall FROM item
|
||||
WHERE item_unseen = 1 and uid = %d " . item_normal(),
|
||||
intval($channels[$x]['channel_id'])
|
||||
@@ -75,7 +75,7 @@ class Manage extends \Zotlabs\Web\Controller {
|
||||
$channels[$x]['network'] ++;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
$intr = 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_pending = 1 and abook_self = 0 and abook_ignored = 0 and xchan_deleted = 0 and xchan_orphan = 0 ",
|
||||
intval($channels[$x]['channel_id'])
|
||||
@@ -84,6 +84,7 @@ class Manage extends \Zotlabs\Web\Controller {
|
||||
if($intr)
|
||||
$channels[$x]['intros'] = intval($intr[0]['total']);
|
||||
|
||||
/* this is not currently implemented in the UI and probably should not (performance)
|
||||
$events = q("SELECT etype, dtstart, adjust FROM event
|
||||
WHERE event.uid = %d AND dtstart < '%s' AND dtstart > '%s' and dismissed = 0
|
||||
ORDER BY dtstart ASC ",
|
||||
@@ -116,6 +117,7 @@ class Manage extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user