Compare commits
3166 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84105c3b05 | ||
|
|
a70db805b7 | ||
|
|
750e0a8d11 | ||
|
|
be3bfa3806 | ||
|
|
4f4d0e416e | ||
|
|
8fde0f01b8 | ||
|
|
757489beb7 | ||
|
|
7773ef0ff4 | ||
|
|
2f5990962c | ||
|
|
81ae0fa252 | ||
|
|
fefc78a849 | ||
|
|
ffe058d48f | ||
|
|
57214fd659 | ||
|
|
5a2b17a1da | ||
|
|
ae3067200b | ||
|
|
568cf2a9e4 | ||
|
|
c2ad28a000 | ||
|
|
f7ad5bbaad | ||
|
|
2a8c4bfbae | ||
|
|
c0f7b8879d | ||
|
|
3a347d7a56 | ||
|
|
c735503f7e | ||
|
|
b0f4929d41 | ||
|
|
10a1569c9a | ||
|
|
301e5383c7 | ||
|
|
66d0b4d0d5 | ||
|
|
94212766cc | ||
|
|
5b436d8fc3 | ||
|
|
cd2d1ff02a | ||
|
|
4ab4224277 | ||
|
|
b5b2e34da5 | ||
|
|
34d28e7ba9 | ||
|
|
259f425050 | ||
|
|
340d437ab2 | ||
|
|
34f576f540 | ||
|
|
64a97d42ff | ||
|
|
beb51040c2 | ||
|
|
8fc9d87b1b | ||
|
|
9845272522 | ||
|
|
7b77e05f3a | ||
|
|
a284e1f9d8 | ||
|
|
ec11ebbd54 | ||
|
|
edf804ea67 | ||
|
|
6f586ae11a | ||
|
|
22c89b6c66 | ||
|
|
cfae618c60 | ||
|
|
7766db40f5 | ||
|
|
18349efccc | ||
|
|
1c5630ef5a | ||
|
|
03d95ec089 | ||
|
|
09d84b5b68 | ||
|
|
9d16666484 | ||
|
|
bb4dcbe89e | ||
|
|
8a8c757327 | ||
|
|
8c75ace6ec | ||
|
|
eb5dfcc9df | ||
|
|
a29c84b522 | ||
|
|
ab3b126ff6 | ||
|
|
6a17da9b08 | ||
|
|
fca405741a | ||
|
|
715847bf74 | ||
|
|
01289048a9 | ||
|
|
dc90f103d4 | ||
|
|
2f026b66a2 | ||
|
|
48db3a189f | ||
|
|
08820fd655 | ||
|
|
66991a0778 | ||
|
|
814dfcd4ac | ||
|
|
48be6ad5c4 | ||
|
|
fbc2bb02b4 | ||
|
|
861bd15c72 | ||
|
|
b8fcfc7698 | ||
|
|
494ce9b872 | ||
|
|
a984cd2b27 | ||
|
|
7a7bfd9de7 | ||
|
|
d0956eb39d | ||
|
|
4d7acdd44d | ||
|
|
5b1ef760a0 | ||
|
|
4859e6e11a | ||
|
|
c2990964f0 | ||
|
|
d4bb6c17d1 | ||
|
|
fca1a7506e | ||
|
|
27bc5fa4b0 | ||
|
|
ad6cb63e07 | ||
|
|
adec67d5fa | ||
|
|
85b7c90637 | ||
|
|
e9ae51cfbc | ||
|
|
3dac1a8d4a | ||
|
|
d326e7a75c | ||
|
|
4c08d7c480 | ||
|
|
ffaab27e77 | ||
|
|
9ba72a06b3 | ||
|
|
a604236d89 | ||
|
|
5024fe3e2d | ||
|
|
44cb68a356 | ||
|
|
157966eb11 | ||
|
|
b7ca2b41cc | ||
|
|
8451ee20c9 | ||
|
|
d4acf41192 | ||
|
|
24d256e253 | ||
|
|
cb39d9435d | ||
|
|
0305983360 | ||
|
|
11c703cb4b | ||
|
|
657ec75c3d | ||
|
|
a79b268438 | ||
|
|
5c12b56e87 | ||
|
|
11b03ca4d2 | ||
|
|
91e3c5c34e | ||
|
|
1c821640ce | ||
|
|
7ed80bf443 | ||
|
|
1c32c5fd2a | ||
|
|
ba547c2257 | ||
|
|
dae0107dd0 | ||
|
|
d5763ba476 | ||
|
|
8a8689c191 | ||
|
|
dd2c4c37ff | ||
|
|
0afdb3ed4d | ||
|
|
9a04b49585 | ||
|
|
dcad9ce26a | ||
|
|
3b6d7e3066 | ||
|
|
3d8de8cf0a | ||
|
|
19ec8488e0 | ||
|
|
0e8e0b48b3 | ||
|
|
cc0d53e695 | ||
|
|
cce2b08e6b | ||
|
|
a68e2999f1 | ||
|
|
fc5b688716 | ||
|
|
6b327f9f4c | ||
|
|
d59c1bb6bf | ||
|
|
6a4050cc93 | ||
|
|
5abcb8c978 | ||
|
|
aa7f6111a6 | ||
|
|
b1f82257e8 | ||
|
|
bc0f4b4fa5 | ||
|
|
e6a59ad36f | ||
|
|
e375224dfe | ||
|
|
f55ef7e728 | ||
|
|
bf1ec44186 | ||
|
|
e47c08ed72 | ||
|
|
e1a209a3da | ||
|
|
76703dee84 | ||
|
|
df45c13f62 | ||
|
|
455720ae93 | ||
|
|
8073be87da | ||
|
|
8d3bf59b7b | ||
|
|
d5c56c0f5d | ||
|
|
f3c0e212bf | ||
|
|
7092458945 | ||
|
|
56772e4807 | ||
|
|
3e7ab8e113 | ||
|
|
53fca8a248 | ||
|
|
1c712ce93e | ||
|
|
dc53573975 | ||
|
|
1ad1b74512 | ||
|
|
0e91810ed6 | ||
|
|
063654373d | ||
|
|
ee929752e3 | ||
|
|
88ebfe6edb | ||
|
|
e1fdac3278 | ||
|
|
d65740311b | ||
|
|
55868ad02d | ||
|
|
014b629928 | ||
|
|
4bffa49add | ||
|
|
fe37b03757 | ||
|
|
4b2bd871b7 | ||
|
|
2108173e74 | ||
|
|
08900b730b | ||
|
|
9dd545f420 | ||
|
|
fda5231a71 | ||
|
|
b03545f899 | ||
|
|
e327b8cb9a | ||
|
|
64c81ed174 | ||
|
|
87eaa6d8e5 | ||
|
|
874cff1a87 | ||
|
|
3bb0efd2cb | ||
|
|
a99ebd42ec | ||
|
|
0cfe2ecd7b | ||
|
|
14f1292743 | ||
|
|
c96f1dbbe2 | ||
|
|
8fcf16ee63 | ||
|
|
4fc8416c3c | ||
|
|
6c178d4485 | ||
|
|
8bd8af7d16 | ||
|
|
b4f8f4df7b | ||
|
|
98e2b2a60b | ||
|
|
eb69f6c346 | ||
|
|
2cb3ccbf14 | ||
|
|
fb1e3cba8b | ||
|
|
94d6461568 | ||
|
|
09f1e4bdfb | ||
|
|
8dceb8e3a7 | ||
|
|
d942818bd9 | ||
|
|
1acef2e242 | ||
|
|
e2814f5d80 | ||
|
|
542d9130b5 | ||
|
|
159d6469fd | ||
|
|
53445ba6bd | ||
|
|
1810edae93 | ||
|
|
7f9ab491f2 | ||
|
|
77190cca92 | ||
|
|
d2e3e3003a | ||
|
|
56d981c8ef | ||
|
|
250d758d74 | ||
|
|
e32f9e0354 | ||
|
|
0325efeb35 | ||
|
|
9ab33f1e13 | ||
|
|
66c0ac591c | ||
|
|
6241967112 | ||
|
|
250d947667 | ||
|
|
6a49e3124e | ||
|
|
16f584608f | ||
|
|
88d0bf94d8 | ||
|
|
241a0829dc | ||
|
|
66a0b4790e | ||
|
|
46ab7ca786 | ||
|
|
3efe144fa0 | ||
|
|
744960d36d | ||
|
|
727b49c8ab | ||
|
|
0aa01740d1 | ||
|
|
1c75e71eb3 | ||
|
|
fbc57fa8e3 | ||
|
|
60fcb5f4f2 | ||
|
|
eb1e9edd33 | ||
|
|
6b6c2ccfa3 | ||
|
|
8a4ee0506c | ||
|
|
ee2ba21246 | ||
|
|
8e6ebd4f7b | ||
|
|
76af8fa754 | ||
|
|
601ebee969 | ||
|
|
becd5f1446 | ||
|
|
ab363e3132 | ||
|
|
7c655c8d61 | ||
|
|
7386fa57c8 | ||
|
|
3f2b7d756c | ||
|
|
cba602bf64 | ||
|
|
78c9f752af | ||
|
|
d13a6180be | ||
|
|
d479ed00e4 | ||
|
|
67b6d41d57 | ||
|
|
601f1eb624 | ||
|
|
301b41eaa4 | ||
|
|
ed0d7890ab | ||
|
|
f50ae07560 | ||
|
|
8e53491867 | ||
|
|
3c3c0ed342 | ||
|
|
8d9c47acdf | ||
|
|
9d69792e08 | ||
|
|
5b4aa71878 | ||
|
|
240db7b602 | ||
|
|
aff476d0d4 | ||
|
|
d5ff82bbe4 | ||
|
|
c8dbcf8a2a | ||
|
|
d893eb67b8 | ||
|
|
5dad444026 | ||
|
|
217a684e5f | ||
|
|
1ef558d7e6 | ||
|
|
7b6ddeb859 | ||
|
|
b12dc89bb1 | ||
|
|
a387868540 | ||
|
|
1ac35dd047 | ||
|
|
458f2e748d | ||
|
|
b62dee4c90 | ||
|
|
6ea7ef43e0 | ||
|
|
3838472a8e | ||
|
|
064464a553 | ||
|
|
9bf366b7d4 | ||
|
|
4668f36ddd | ||
|
|
a68308b164 | ||
|
|
f7e3d0dbf6 | ||
|
|
bd3bc503ed | ||
|
|
e2eb36ded6 | ||
|
|
4ac3cec66e | ||
|
|
823729d2c1 | ||
|
|
34b38f06e0 | ||
|
|
0fef599341 | ||
|
|
124e08efde | ||
|
|
66338a5757 | ||
|
|
ebee3e208c | ||
|
|
f8cf68ab53 | ||
|
|
28c85cf3ae | ||
|
|
cf4e2b2953 | ||
|
|
f3d3ec5744 | ||
|
|
29829eb011 | ||
|
|
129e6bddde | ||
|
|
8260817cf7 | ||
|
|
47d15f3bf4 | ||
|
|
96d439bcee | ||
|
|
47fab97210 | ||
|
|
5dec3ff18e | ||
|
|
bd3e5156c4 | ||
|
|
fccc1da666 | ||
|
|
55995b0494 | ||
|
|
eb17598254 | ||
|
|
0d512dffc3 | ||
|
|
988028577b | ||
|
|
6cf3ebb7db | ||
|
|
c571ca40d7 | ||
|
|
3a17225546 | ||
|
|
5e541ff53b | ||
|
|
9b19e40a74 | ||
|
|
766a7fb1b4 | ||
|
|
40a7446e3e | ||
|
|
fc96cd3710 | ||
|
|
40c625158f | ||
|
|
7dad842f35 | ||
|
|
909f67fb3a | ||
|
|
e7d20efb1b | ||
|
|
a8d527f1cd | ||
|
|
e5f3296c6b | ||
|
|
9d584fc720 | ||
|
|
92e0c502f7 | ||
|
|
b5d4acf10a | ||
|
|
47fbdda409 | ||
|
|
1bb6dfc9a0 | ||
|
|
549866c090 | ||
|
|
7b69dc574b | ||
|
|
5376a734d4 | ||
|
|
3f1a4b6559 | ||
|
|
11a7a08b9d | ||
|
|
d16bbfb224 | ||
|
|
48959d5606 | ||
|
|
94e548b07a | ||
|
|
4be48b8d8b | ||
|
|
9cd715bbbf | ||
|
|
04d66ba7f4 | ||
|
|
7efcb3c75f | ||
|
|
359bfb76f6 | ||
|
|
0e1c628066 | ||
|
|
65bc146afa | ||
|
|
9630d2ef2c | ||
|
|
6e9d5a03c2 | ||
|
|
839c154869 | ||
|
|
6995d54a3c | ||
|
|
d31df715fb | ||
|
|
26fa091aa2 | ||
|
|
cfbeb1655d | ||
|
|
39c194c5c3 | ||
|
|
9dfb471c0b | ||
|
|
f51a7225c8 | ||
|
|
1d903655af | ||
|
|
9abb061e71 | ||
|
|
6e48c36519 | ||
|
|
d450fc61c4 | ||
|
|
a899ce1c22 | ||
|
|
1a737be2b4 | ||
|
|
fae9c23637 | ||
|
|
1159dd59ed | ||
|
|
0ce7358f0f | ||
|
|
41749f5eda | ||
|
|
1567b7b383 | ||
|
|
e70bd0054c | ||
|
|
b450b6a435 | ||
|
|
0403738981 | ||
|
|
0d7062ffdf | ||
|
|
8f59b2d3e0 | ||
|
|
1b290f573a | ||
|
|
b77169f1d8 | ||
|
|
00d8783e45 | ||
|
|
cf5beafcfd | ||
|
|
cdaf5f3fc0 | ||
|
|
bdf50a824e | ||
|
|
f23c8e7597 | ||
|
|
52657b6215 | ||
|
|
28cd2759d7 | ||
|
|
12f33d2cd4 | ||
|
|
11cdc36bcc | ||
|
|
22d45a8d1e | ||
|
|
7d9d1e0cdb | ||
|
|
98b53801e0 | ||
|
|
bff1e215cc | ||
|
|
6efef3922b | ||
|
|
caec565de5 | ||
|
|
16a2bfa95b | ||
|
|
60da235efb | ||
|
|
71e0e55b0b | ||
|
|
b28ff509b1 | ||
|
|
8467ecb1d7 | ||
|
|
1f47f4ff96 | ||
|
|
4fef29e61c | ||
|
|
56c3d5dbcb | ||
|
|
ceed0f7a1b | ||
|
|
906d91d4d1 | ||
|
|
e539a9e7bd | ||
|
|
1be98d7b7f | ||
|
|
66832c41e9 | ||
|
|
8e4c5db766 | ||
|
|
1dc3253d4a | ||
|
|
feebe7d4c6 | ||
|
|
9a8071e014 | ||
|
|
9ce817bb6e | ||
|
|
fe2a937cf2 | ||
|
|
1cf90dd14d | ||
|
|
6823f0aa52 | ||
|
|
f2efa8c753 | ||
|
|
e5cfb8a0cd | ||
|
|
4a3149d1ba | ||
|
|
dafe0a5547 | ||
|
|
fe5f1e4d67 | ||
|
|
5cf06a679c | ||
|
|
859195d07a | ||
|
|
344aa13c64 | ||
|
|
69b22e3f79 | ||
|
|
a782c9944c | ||
|
|
39055c919c | ||
|
|
bc890d3038 | ||
|
|
e424ae0473 | ||
|
|
780abe7dd4 | ||
|
|
a3fc9e3742 | ||
|
|
325cbfcdb3 | ||
|
|
69e7a7594a | ||
|
|
c489f734db | ||
|
|
60a54e9aac | ||
|
|
280baf7c82 | ||
|
|
a23f8b6231 | ||
|
|
ccc8ff107e | ||
|
|
59a9f6bf02 | ||
|
|
2aff3a1a05 | ||
|
|
25988ddefa | ||
|
|
c99962106d | ||
|
|
52c1f79f2e | ||
|
|
2c07a92ad7 | ||
|
|
e67ff5c122 | ||
|
|
37b7b2f1a8 | ||
|
|
fd5764e166 | ||
|
|
c49eec71f0 | ||
|
|
812d904c98 | ||
|
|
a4fdf3fbbb | ||
|
|
9090bfd1c3 | ||
|
|
8c57ed64d0 | ||
|
|
b58bf75f21 | ||
|
|
189a15fe37 | ||
|
|
c7d9a5ac91 | ||
|
|
d0bc81f8d2 | ||
|
|
0dc777bc45 | ||
|
|
4f39119e37 | ||
|
|
8aa4af372d | ||
|
|
d5e90d678a | ||
|
|
0061ac8584 | ||
|
|
f648809856 | ||
|
|
687114b407 | ||
|
|
40f805c94a | ||
|
|
9751d03a4d | ||
|
|
36678d1b90 | ||
|
|
8f465e3097 | ||
|
|
c80f4feb62 | ||
|
|
2d06e86b5b | ||
|
|
400441d56b | ||
|
|
7d92e9026e | ||
|
|
42416aad22 | ||
|
|
9d51318c53 | ||
|
|
cdb1bc9be6 | ||
|
|
52183f8bf8 | ||
|
|
00dc7c916d | ||
|
|
5fd6e36be7 | ||
|
|
c2714262b3 | ||
|
|
a58f386831 | ||
|
|
e61b44ddbb | ||
|
|
f3c374b6ff | ||
|
|
21b2c0afa3 | ||
|
|
ca4c725d57 | ||
|
|
fe1aa90304 | ||
|
|
656ec585b2 | ||
|
|
64a49eb54a | ||
|
|
b106b53d05 | ||
|
|
a791809a84 | ||
|
|
71c3a0a197 | ||
|
|
9497c6c0f7 | ||
|
|
18279234fd | ||
|
|
4dd05dc4e8 | ||
|
|
cf7481da53 | ||
|
|
b8a9390f49 | ||
|
|
61c86212b9 | ||
|
|
a33562144b | ||
|
|
9b94ad2ffe | ||
|
|
70b39e829b | ||
|
|
29a29f277e | ||
|
|
e5f1bcacc8 | ||
|
|
ccbc532c1a | ||
|
|
e6c166a182 | ||
|
|
26bd532bc5 | ||
|
|
c89b2ac3b7 | ||
|
|
6acd96fd33 | ||
|
|
a652e546cc | ||
|
|
ee307729fc | ||
|
|
48d2b3afa8 | ||
|
|
491856fa79 | ||
|
|
56a675f713 | ||
|
|
05c8d4819d | ||
|
|
c8d5390512 | ||
|
|
f3cf708c85 | ||
|
|
24d1d752fe | ||
|
|
ba55400f14 | ||
|
|
0c5918f290 | ||
|
|
0216dc733d | ||
|
|
ff8ee6fb22 | ||
|
|
1a7ccc462b | ||
|
|
769da564e2 | ||
|
|
09b4660c7d | ||
|
|
69394c1680 | ||
|
|
4203d43c58 | ||
|
|
f273815d8f | ||
|
|
6a2c5e0731 | ||
|
|
07ae431950 | ||
|
|
0c4a1fb9be | ||
|
|
e6f1fb3d95 | ||
|
|
030d703a05 | ||
|
|
edc262f5af | ||
|
|
41cf846ee3 | ||
|
|
335536bbbf | ||
|
|
89aa9a80c4 | ||
|
|
d636ff586d | ||
|
|
8797049144 | ||
|
|
623dfa1384 | ||
|
|
cc1ffff7cd | ||
|
|
5698462588 | ||
|
|
f99c007187 | ||
|
|
54a0690323 | ||
|
|
23812e5b48 | ||
|
|
c37908f344 | ||
|
|
4011dd18f0 | ||
|
|
52b1ea10a1 | ||
|
|
09009d4b32 | ||
|
|
ec173e7eb2 | ||
|
|
bcf4cb519a | ||
|
|
27bc8294ae | ||
|
|
5cc6c6c1e9 | ||
|
|
991db280be | ||
|
|
6f709a6f57 | ||
|
|
71c206fdb9 | ||
|
|
4c0e8a61ae | ||
|
|
dc2c6d00fe | ||
|
|
e7c8012794 | ||
|
|
9bd30eb8bf | ||
|
|
b883b9c983 | ||
|
|
5468ebbb43 | ||
|
|
27f8320353 | ||
|
|
e15307747f | ||
|
|
f427b4a325 | ||
|
|
a6835f4e71 | ||
|
|
052ed1f88b | ||
|
|
34a0ec4089 | ||
|
|
2ed77b5986 | ||
|
|
d70e6f273b | ||
|
|
d2e22d8c2f | ||
|
|
7c501ef60f | ||
|
|
a0eb628526 | ||
|
|
0ddc3e4af2 | ||
|
|
5be9477f21 | ||
|
|
4ab21edba8 | ||
|
|
2862baeee1 | ||
|
|
15b9a67c01 | ||
|
|
80ca99fe5b | ||
|
|
6f88d5e92b | ||
|
|
295ed07d40 | ||
|
|
d6b1eff70e | ||
|
|
7fb02752de | ||
|
|
d88d4b3c3a | ||
|
|
58155864cb | ||
|
|
9cf9217686 | ||
|
|
fa93114804 | ||
|
|
66511d8f07 | ||
|
|
f52e5d90b0 | ||
|
|
f571b753b6 | ||
|
|
40e747ecde | ||
|
|
9e24b28376 | ||
|
|
5abdee73ee | ||
|
|
2feb6795b0 | ||
|
|
c200808fbb | ||
|
|
1f8b705a6a | ||
|
|
a3c2ef4084 | ||
|
|
9dcbef4cb1 | ||
|
|
8bd4e004ff | ||
|
|
47b2959486 | ||
|
|
f70d27b793 | ||
|
|
7c845aafa2 | ||
|
|
16b57a2b28 | ||
|
|
89457c8390 | ||
|
|
ea4d1b5101 | ||
|
|
dd38fad9ee | ||
|
|
c61853ff0b | ||
|
|
bdecb61bfa | ||
|
|
c9231785ab | ||
|
|
f79d5ec18e | ||
|
|
98e0534984 | ||
|
|
617f2863c4 | ||
|
|
0f36916fb4 | ||
|
|
1fd2b6f5b6 | ||
|
|
7d386c2777 | ||
|
|
fb60eeaa9a | ||
|
|
9625d940a5 | ||
|
|
b8a0bc0b0b | ||
|
|
cee41bb1e5 | ||
|
|
4a270d10d1 | ||
|
|
ea5262a0df | ||
|
|
86e888e5eb | ||
|
|
9d7a88b40d | ||
|
|
be8061b64b | ||
|
|
d91a82430a | ||
|
|
b9664f6980 | ||
|
|
66334374af | ||
|
|
741af8c164 | ||
|
|
137f5b3dbc | ||
|
|
e1cd51d8d9 | ||
|
|
237aca32e3 | ||
|
|
906a810735 | ||
|
|
808605cd65 | ||
|
|
06a674775e | ||
|
|
b195407028 | ||
|
|
1650d79862 | ||
|
|
e8a888caab | ||
|
|
3648f9952c | ||
|
|
8b7ab90836 | ||
|
|
866dc9a9b3 | ||
|
|
0e76cec28f | ||
|
|
2988e33b57 | ||
|
|
aef239f421 | ||
|
|
3456c192fe | ||
|
|
ae5a1362a7 | ||
|
|
fefc2290a1 | ||
|
|
6bd35ef740 | ||
|
|
b772a5f564 | ||
|
|
234e9476fb | ||
|
|
a7d339be5a | ||
|
|
b745a143c3 | ||
|
|
6e9e267b27 | ||
|
|
2e9336beb5 | ||
|
|
5951fa56ae | ||
|
|
4372e1fcda | ||
|
|
24a9c3ba79 | ||
|
|
c4261b9c4b | ||
|
|
7b060dff68 | ||
|
|
90f759412b | ||
|
|
15691d3ced | ||
|
|
6f2dd5d325 | ||
|
|
9e46472ca2 | ||
|
|
61d9b34929 | ||
|
|
00fe4e747f | ||
|
|
b0cdec0c35 | ||
|
|
373af6d4f4 | ||
|
|
4ae503bef7 | ||
|
|
72a19a14af | ||
|
|
a7d0c45606 | ||
|
|
dbc0cc8c92 | ||
|
|
a1be6f11ed | ||
|
|
143e389695 | ||
|
|
962a3f7945 | ||
|
|
bced63e823 | ||
|
|
51e40add66 | ||
|
|
4500faf463 | ||
|
|
66fb0fdcd7 | ||
|
|
105e7626fc | ||
|
|
c6bcea0f82 | ||
|
|
4fbebe7b2d | ||
|
|
e812836a60 | ||
|
|
d11d36040d | ||
|
|
c3b3f41a21 | ||
|
|
46daaa11fd | ||
|
|
cca2b1621f | ||
|
|
807776cb15 | ||
|
|
9914e171b1 | ||
|
|
b3c805d7d0 | ||
|
|
d31c91c9d3 | ||
|
|
bf252d2388 | ||
|
|
5c379b4d35 | ||
|
|
4d3b0577c9 | ||
|
|
d37e6b9271 | ||
|
|
654139933f | ||
|
|
1d9e0f17a6 | ||
|
|
9120a82ab4 | ||
|
|
ca24bfdc46 | ||
|
|
aaa83ae5d2 | ||
|
|
8123a62302 | ||
|
|
e84281b620 | ||
|
|
6239a27288 | ||
|
|
0b272264ea | ||
|
|
d5ffa5508d | ||
|
|
991db80646 | ||
|
|
cb3fb0049f | ||
|
|
eef1fcbb07 | ||
|
|
186dd9dee0 | ||
|
|
373651c3db | ||
|
|
663802e699 | ||
|
|
4c5722c766 | ||
|
|
6734854776 | ||
|
|
1c0ece8411 | ||
|
|
cf120b2351 | ||
|
|
6481722fd9 | ||
|
|
b1876ac14f | ||
|
|
d7ec6865b4 | ||
|
|
46b6415f5f | ||
|
|
5aa0fe2bf0 | ||
|
|
f43f38c054 | ||
|
|
235ba81f25 | ||
|
|
55aaabc2f1 | ||
|
|
5be132f877 | ||
|
|
b5966041be | ||
|
|
62d6bada4c | ||
|
|
e8e61c83d5 | ||
|
|
13788af908 | ||
|
|
d5bd5cda97 | ||
|
|
29b0ed87d6 | ||
|
|
0e6d84e207 | ||
|
|
796228b7ad | ||
|
|
7489a4442e | ||
|
|
5e99295bf6 | ||
|
|
4ff89a5862 | ||
|
|
87ca60b0b1 | ||
|
|
525d554a35 | ||
|
|
4c121aff30 | ||
|
|
d77872de50 | ||
|
|
91ed3b357d | ||
|
|
d4e53bb86f | ||
|
|
471449f539 | ||
|
|
187fc9a51b | ||
|
|
abbf245d14 | ||
|
|
20ae69ab7b | ||
|
|
67024c023a | ||
|
|
2f76d63835 | ||
|
|
754329097f | ||
|
|
c5950c0370 | ||
|
|
e2e7bee3cc | ||
|
|
edada2b786 | ||
|
|
ccc9cc8202 | ||
|
|
84c86f01c8 | ||
|
|
9b542c5bcf | ||
|
|
108bb7649b | ||
|
|
1104e2652f | ||
|
|
f2dc55244c | ||
|
|
048a8c5f44 | ||
|
|
1fbb1e6c2a | ||
|
|
7e9162ef06 | ||
|
|
f09fe8da78 | ||
|
|
4d794103be | ||
|
|
61f339a874 | ||
|
|
7b3aa92b5a | ||
|
|
27e9b5618b | ||
|
|
4d1f5c1752 | ||
|
|
23e774db8e | ||
|
|
4190a40de8 | ||
|
|
6143f49042 | ||
|
|
607c414634 | ||
|
|
d65007b230 | ||
|
|
41e0d5f664 | ||
|
|
fa7a6203fb | ||
|
|
5877e28d72 | ||
|
|
318643cf9a | ||
|
|
ab9b82e778 | ||
|
|
fee65f0c69 | ||
|
|
643f515eaf | ||
|
|
1305584d77 | ||
|
|
0a7364d494 | ||
|
|
2cce599fd7 | ||
|
|
7dc99cb4a4 | ||
|
|
45eb61bcf0 | ||
|
|
80400d7191 | ||
|
|
9ca7cc565b | ||
|
|
6147f819ce | ||
|
|
842a041a88 | ||
|
|
68a91ec3ea | ||
|
|
d58f965b9a | ||
|
|
83d0e48ebe | ||
|
|
ca58ef80ae | ||
|
|
0956dcadd3 | ||
|
|
304c393f38 | ||
|
|
05654e4980 | ||
|
|
c8000fca1f | ||
|
|
48547f5f9e | ||
|
|
b4f8136315 | ||
|
|
06f1910ac0 | ||
|
|
03b31932d1 | ||
|
|
e4b0e31a28 | ||
|
|
ba4f75ba19 | ||
|
|
fc62f07a08 | ||
|
|
3d0a7f4fc5 | ||
|
|
47ef41695a | ||
|
|
4adf2caaa6 | ||
|
|
db82d303e2 | ||
|
|
0fac35686b | ||
|
|
5ae2d15dc0 | ||
|
|
dc18440c18 | ||
|
|
499b7de0d2 | ||
|
|
1a0cf2666a | ||
|
|
7bff60edac | ||
|
|
e935473c5c | ||
|
|
3af3b36db3 | ||
|
|
9333503600 | ||
|
|
7a42aed1f6 | ||
|
|
5bffae6219 | ||
|
|
ae8cdc3b42 | ||
|
|
b413beeb36 | ||
|
|
0cf5536e90 | ||
|
|
5e767144c9 | ||
|
|
6d87311394 | ||
|
|
0ee2378cec | ||
|
|
28d6b9ce16 | ||
|
|
f3c0db0f39 | ||
|
|
3a52af6327 | ||
|
|
aec92e0e17 | ||
|
|
c364bff0c1 | ||
|
|
74f55d1504 | ||
|
|
f436ec6f21 | ||
|
|
be097bf415 | ||
|
|
f1b014b7eb | ||
|
|
ad637b5b50 | ||
|
|
5abc9ef10b | ||
|
|
d47df8663f | ||
|
|
77267e049a | ||
|
|
e2b6464f83 | ||
|
|
973f15438a | ||
|
|
1f42d23332 | ||
|
|
b80f0b8960 | ||
|
|
06be21af05 | ||
|
|
ab5e7ad7a2 | ||
|
|
0d3c378e10 | ||
|
|
471031390c | ||
|
|
8517e7e798 | ||
|
|
e70bf97508 | ||
|
|
6385d11b54 | ||
|
|
d0d0a2df3a | ||
|
|
99ca2a7cc6 | ||
|
|
acacea5efe | ||
|
|
187f19b170 | ||
|
|
49b38bd71b | ||
|
|
75f3e9202e | ||
|
|
0098dce597 | ||
|
|
cff5e360fd | ||
|
|
45c033b9aa | ||
|
|
5c92337821 | ||
|
|
341386a95b | ||
|
|
bd84a3ee08 | ||
|
|
383b7928cf | ||
|
|
9cb856d5fd | ||
|
|
2d5768b71c | ||
|
|
90ec3340e4 | ||
|
|
cf2609530f | ||
|
|
cdccf60132 | ||
|
|
df2725a360 | ||
|
|
592cf893c0 | ||
|
|
85f24c292f | ||
|
|
1c4629f5e1 | ||
|
|
af8ed605f8 | ||
|
|
186f85483f | ||
|
|
e157e3bec8 | ||
|
|
4450170790 | ||
|
|
66b032823b | ||
|
|
c9745a4129 | ||
|
|
bf7b0b11ef | ||
|
|
e778815605 | ||
|
|
f2e802229a | ||
|
|
64cf36a2b5 | ||
|
|
8873fbfee9 | ||
|
|
89df4551aa | ||
|
|
ecfc7b8f4c | ||
|
|
3b68df1be6 | ||
|
|
9518dc0e4e | ||
|
|
e084b776ee | ||
|
|
6c38857502 | ||
|
|
41ff8fdd37 | ||
|
|
182f94a9ac | ||
|
|
92077725c3 | ||
|
|
9f37dbc6dc | ||
|
|
33528c616a | ||
|
|
894f0156af | ||
|
|
9d5b6858ea | ||
|
|
7a405da3b7 | ||
|
|
49cc952825 | ||
|
|
31e62bd19e | ||
|
|
52c6ea5115 | ||
|
|
f15d96bebe | ||
|
|
18c57eeaa0 | ||
|
|
2b898537d7 | ||
|
|
081bff605a | ||
|
|
8a5c23fd50 | ||
|
|
830f1bcd50 | ||
|
|
17e81095b3 | ||
|
|
ed71afa6c7 | ||
|
|
4cafa6280d | ||
|
|
b488034352 | ||
|
|
944cd883bb | ||
|
|
f9dd4188b4 | ||
|
|
557aa18526 | ||
|
|
b18f3f4f7a | ||
|
|
4111ba8dee | ||
|
|
035449e4a3 | ||
|
|
2a2abf14bb | ||
|
|
b553ecbb18 | ||
|
|
d87a270e2c | ||
|
|
3443416540 | ||
|
|
f2589cc820 | ||
|
|
691fadc93d | ||
|
|
65a320c509 | ||
|
|
b0f2c22000 | ||
|
|
ef8a251115 | ||
|
|
4a7384bc0c | ||
|
|
90bc21f2d5 | ||
|
|
1c5629263b | ||
|
|
6adfbabbb7 | ||
|
|
2a48222393 | ||
|
|
4addde782e | ||
|
|
9b87940ed2 | ||
|
|
8000d6b5d4 | ||
|
|
e9679d251c | ||
|
|
68f6043d44 | ||
|
|
f560a88ff3 | ||
|
|
4b0d0df781 | ||
|
|
05453ce493 | ||
|
|
af7ea07b43 | ||
|
|
289161aad1 | ||
|
|
6a3919587f | ||
|
|
80e7337984 | ||
|
|
6cea5ddfad | ||
|
|
ba08555efc | ||
|
|
f99b62b516 | ||
|
|
2f45182b48 | ||
|
|
9da1439a4d | ||
|
|
57602647ef | ||
|
|
4848dc5ec8 | ||
|
|
8b5a190d71 | ||
|
|
a4804ff977 | ||
|
|
998bd585bb | ||
|
|
0123a28186 | ||
|
|
ff1d900ccb | ||
|
|
1808ffcdf2 | ||
|
|
86c4743ed9 | ||
|
|
1408e3da3b | ||
|
|
5f6eedcc1a | ||
|
|
7cec3f4dbf | ||
|
|
80ff7fa353 | ||
|
|
7892ed9e77 | ||
|
|
0e3b5536e2 | ||
|
|
6c55e44f4c | ||
|
|
5b88e9574f | ||
|
|
ecfb608518 | ||
|
|
9411732c1b | ||
|
|
acb8eeb853 | ||
|
|
d1c7e78990 | ||
|
|
0a96cdd950 | ||
|
|
5686901869 | ||
|
|
6531cbd1d2 | ||
|
|
09da109eba | ||
|
|
fa2de77abe | ||
|
|
8ab3a4ebd7 | ||
|
|
8eb6dafe31 | ||
|
|
ca11d7b9a7 | ||
|
|
a7a73a5150 | ||
|
|
83b5bbfeea | ||
|
|
59108b18ae | ||
|
|
037e1edb1f | ||
|
|
c00796d553 | ||
|
|
23f9f8bc3b | ||
|
|
88a4889780 | ||
|
|
bac297cf31 | ||
|
|
3c73228d80 | ||
|
|
0085b64b2b | ||
|
|
1c0c01ccfe | ||
|
|
b0d1fa09c1 | ||
|
|
68b32cd8f4 | ||
|
|
d5dcaacf2c | ||
|
|
03ca0bfa69 | ||
|
|
3aa22c29fd | ||
|
|
06a211704f | ||
|
|
913046aa28 | ||
|
|
b4707705f1 | ||
|
|
a618f70f56 | ||
|
|
05444f92f9 | ||
|
|
9566eab934 | ||
|
|
d704832ff6 | ||
|
|
3c1dff3039 | ||
|
|
4edf580ebf | ||
|
|
7b177be271 | ||
|
|
d183e47dc9 | ||
|
|
dc7c3f70eb | ||
|
|
d06ce6294d | ||
|
|
21ee29e46d | ||
|
|
bee09a6d8b | ||
|
|
a100c47f11 | ||
|
|
ba62f14482 | ||
|
|
2a34a497d5 | ||
|
|
4ea4a036ef | ||
|
|
2dbf8a5e00 | ||
|
|
9359f9fe4d | ||
|
|
01526a9a79 | ||
|
|
01fc590938 | ||
|
|
6e9fb9b9fd | ||
|
|
a97b09210e | ||
|
|
acddf5aa8d | ||
|
|
6614d465d6 | ||
|
|
2ba2187c2e | ||
|
|
2ea482d163 | ||
|
|
599b395e24 | ||
|
|
1416b81877 | ||
|
|
aa766b53d6 | ||
|
|
4e2a050afb | ||
|
|
cf437c6a33 | ||
|
|
8b6a24c67d | ||
|
|
a72b549aa7 | ||
|
|
46d8cf3f94 | ||
|
|
91d19a3326 | ||
|
|
a510c91d48 | ||
|
|
2f8c5cf7d0 | ||
|
|
1f2482f6ab | ||
|
|
9476c631b0 | ||
|
|
10e459140b | ||
|
|
b66cd8363e | ||
|
|
376b05bcc9 | ||
|
|
a4a99d2d46 | ||
|
|
2fcbbfe3d4 | ||
|
|
2095937c60 | ||
|
|
d33974cec4 | ||
|
|
9ec995dbf0 | ||
|
|
79a806f328 | ||
|
|
445fa6825a | ||
|
|
e3c8e4f483 | ||
|
|
8f3a99ad1f | ||
|
|
a3fef34a3f | ||
|
|
17618be14d | ||
|
|
3faca10efc | ||
|
|
280f52f007 | ||
|
|
126e06b32a | ||
|
|
988371be0b | ||
|
|
b4efe8ad8d | ||
|
|
964a02d684 | ||
|
|
40effa4417 | ||
|
|
35c05a3180 | ||
|
|
4a071b9a1c | ||
|
|
ead80481b9 | ||
|
|
297057d2bd | ||
|
|
11cdd0033d | ||
|
|
06bd540cfa | ||
|
|
3451fe2d40 | ||
|
|
2ee0f769d9 | ||
|
|
8161ec88e5 | ||
|
|
7b992decd4 | ||
|
|
9b9fe39839 | ||
|
|
1f57a59618 | ||
|
|
5a1b850dd6 | ||
|
|
c4e0e20eb3 | ||
|
|
eedee6d0a1 | ||
|
|
e316494e06 | ||
|
|
4585e35b3e | ||
|
|
9717d4502f | ||
|
|
f9b342c87d | ||
|
|
222113ee57 | ||
|
|
5f7b2e7c17 | ||
|
|
179478a940 | ||
|
|
53570de5a3 | ||
|
|
41a6300d3c | ||
|
|
1376e59d00 | ||
|
|
d623228cf6 | ||
|
|
75d63684b8 | ||
|
|
d3d184192d | ||
|
|
9be4c4d6d1 | ||
|
|
d3a5911932 | ||
|
|
dbbae4bac8 | ||
|
|
9132b9c026 | ||
|
|
769f697ae3 | ||
|
|
7d891a54e7 | ||
|
|
e71cdf02a8 | ||
|
|
7d82b5f28d | ||
|
|
eec2871680 | ||
|
|
029cf6395d | ||
|
|
08f15a6fc6 | ||
|
|
c24cfbc62a | ||
|
|
caf077cbf8 | ||
|
|
5cc8837fb6 | ||
|
|
ddecbf052e | ||
|
|
6a7fa6bf54 | ||
|
|
5ed4ed2246 | ||
|
|
72ed290ccd | ||
|
|
16067db718 | ||
|
|
363d872326 | ||
|
|
f4a4d70149 | ||
|
|
4335e49381 | ||
|
|
992f8272d3 | ||
|
|
27678a523c | ||
|
|
1bdcfe5219 | ||
|
|
89d21c0873 | ||
|
|
23e2b3be09 | ||
|
|
a346399fe6 | ||
|
|
8e5c56dcc2 | ||
|
|
77b58ec02f | ||
|
|
ceeb9836b9 | ||
|
|
df7f0eb9a4 | ||
|
|
6103c30184 | ||
|
|
b52a968c74 | ||
|
|
82aa87c190 | ||
|
|
1af844e474 | ||
|
|
c664a4bdcd | ||
|
|
229f95d555 | ||
|
|
ac6ebeee47 | ||
|
|
8896ebf7cb | ||
|
|
9bd11afc62 | ||
|
|
08c0d78296 | ||
|
|
9daa3b85c8 | ||
|
|
d8c93c0d13 | ||
|
|
42abc2201c | ||
|
|
27257de995 | ||
|
|
15e836b7dd | ||
|
|
0d062251b6 | ||
|
|
ecb1515e5d | ||
|
|
4728e72d18 | ||
|
|
c352047228 | ||
|
|
1aedf22228 | ||
|
|
5408264559 | ||
|
|
b7d92d3a09 | ||
|
|
bd17dc52f2 | ||
|
|
e6315d252a | ||
|
|
ce3be598bb | ||
|
|
e891199a23 | ||
|
|
b1d4e97699 | ||
|
|
16dcaaa3a8 | ||
|
|
fd5c92822c | ||
|
|
77f71303f2 | ||
|
|
266dab1b59 | ||
|
|
2d119c81a4 | ||
|
|
88bb61018d | ||
|
|
c940d8d7ca | ||
|
|
aa70cbbf21 | ||
|
|
6db717a1a0 | ||
|
|
ad9990e100 | ||
|
|
403e90861c | ||
|
|
2d63bbb91e | ||
|
|
271ed82d0d | ||
|
|
c47439fca4 | ||
|
|
e3734328eb | ||
|
|
ddc454bd82 | ||
|
|
799d4ad549 | ||
|
|
8dcdcd55e5 | ||
|
|
1fca442828 | ||
|
|
d077f15270 | ||
|
|
31d1a72854 | ||
|
|
f9a989fe1b | ||
|
|
46e079beea | ||
|
|
4048cb67d2 | ||
|
|
b16e4c558f | ||
|
|
2d6e87fb17 | ||
|
|
024d2737d0 | ||
|
|
b2e5b6c977 | ||
|
|
75f058e15e | ||
|
|
7fb849ab87 | ||
|
|
fca8e0aa6a | ||
|
|
8dd9ab05a9 | ||
|
|
c3b93de099 | ||
|
|
27c8c74988 | ||
|
|
80352dab5f | ||
|
|
00a49b42e4 | ||
|
|
f5735fb67b | ||
|
|
fb5b588349 | ||
|
|
9e497cde40 | ||
|
|
f3816836e5 | ||
|
|
038c928b9b | ||
|
|
c596248f40 | ||
|
|
6ae3a92f53 | ||
|
|
fbf868e976 | ||
|
|
5e0bb6ecd5 | ||
|
|
a34d8773f1 | ||
|
|
4bc94c0ee9 | ||
|
|
bf1a21e46f | ||
|
|
d18427a522 | ||
|
|
76850a7340 | ||
|
|
d096106824 | ||
|
|
562124c29f | ||
|
|
48063fa5ef | ||
|
|
41111bcdad | ||
|
|
133292e241 | ||
|
|
64cad0a041 | ||
|
|
b73c844d1a | ||
|
|
da1b10b741 | ||
|
|
c7b4a53af2 | ||
|
|
024809f970 | ||
|
|
126af3a24a | ||
|
|
b91d95d241 | ||
|
|
8ca5a65dcf | ||
|
|
798a03c2ab | ||
|
|
34c4775916 | ||
|
|
c5cff7d637 | ||
|
|
c2af370282 | ||
|
|
118fed29b5 | ||
|
|
4c50bfebc2 | ||
|
|
dab00a98e0 | ||
|
|
2b2ea40bce | ||
|
|
1273ac67f4 | ||
|
|
676481de58 | ||
|
|
54c5e03b4f | ||
|
|
a8374b25f1 | ||
|
|
4d81c498e2 | ||
|
|
b0dd824dbc | ||
|
|
5dc638c5b3 | ||
|
|
7f982a0778 | ||
|
|
28a1be4d36 | ||
|
|
c456e01219 | ||
|
|
ef53db0b91 | ||
|
|
21542d1f9e | ||
|
|
07d6472eea | ||
|
|
6c771f84ce | ||
|
|
02b7bc0803 | ||
|
|
681d6ca1dd | ||
|
|
3b4f70ae83 | ||
|
|
0e100a864b | ||
|
|
dc14f8bf2c | ||
|
|
37b9a809a6 | ||
|
|
5f1a1db30f | ||
|
|
99ff808b8a | ||
|
|
08c0729f5f | ||
|
|
7e4e2f28db | ||
|
|
08d9316d76 | ||
|
|
0233e9ad2a | ||
|
|
31e0812711 | ||
|
|
76e9809169 | ||
|
|
07a8151ae6 | ||
|
|
075ced80a6 | ||
|
|
4c96b9778e | ||
|
|
1b31c9f8a8 | ||
|
|
b858eec644 | ||
|
|
5af9923e29 | ||
|
|
e122901e49 | ||
|
|
aed1373b70 | ||
|
|
3b5e1c05b7 | ||
|
|
1472f85b16 | ||
|
|
3d6255ae24 | ||
|
|
f25e0c3829 | ||
|
|
b0a6a5a91e | ||
|
|
b917cf1ecc | ||
|
|
4d5469f27e | ||
|
|
1848a22118 | ||
|
|
b429576349 | ||
|
|
bb9557a9ae | ||
|
|
0d7e7ac657 | ||
|
|
b8c77bbcfc | ||
|
|
327b22d24e | ||
|
|
8b3d2c02e1 | ||
|
|
1ac799f629 | ||
|
|
234c64574b | ||
|
|
7b948bdd29 | ||
|
|
1f075d92bc | ||
|
|
fe02665f54 | ||
|
|
ec74b57000 | ||
|
|
3f488e9842 | ||
|
|
54e07389fa | ||
|
|
28906bf50a | ||
|
|
70e912736f | ||
|
|
ec1156d37a | ||
|
|
dcbc65a796 | ||
|
|
8eccd7d47d | ||
|
|
5530833bf8 | ||
|
|
2f8fb2b663 | ||
|
|
5d2035b729 | ||
|
|
7c36331042 | ||
|
|
36cfdd529b | ||
|
|
3e13568f91 | ||
|
|
e84ed1cb9a | ||
|
|
f1fd672d7b | ||
|
|
02b0472058 | ||
|
|
5854a226d7 | ||
|
|
bdf8940040 | ||
|
|
2b9a8fa1ac | ||
|
|
45137a55a4 | ||
|
|
d6dd2c5bd6 | ||
|
|
d4330ceacc | ||
|
|
364da7a57e | ||
|
|
05eeb8432e | ||
|
|
fce68f1a39 | ||
|
|
7f374fe69f | ||
|
|
836cb16455 | ||
|
|
dd8feac540 | ||
|
|
f526b9fcfb | ||
|
|
8bf9b1311d | ||
|
|
5b3e863323 | ||
|
|
6ce9eedb5f | ||
|
|
6f78183b74 | ||
|
|
1d96544c9d | ||
|
|
69f6a5c08c | ||
|
|
38b4f6a391 | ||
|
|
425e13843e | ||
|
|
f28fa0ab5a | ||
|
|
f162993001 | ||
|
|
af774a7269 | ||
|
|
d82cfdf581 | ||
|
|
b84818a334 | ||
|
|
9c26ee122e | ||
|
|
f27047dd2e | ||
|
|
643a62038e | ||
|
|
fbb83d831b | ||
|
|
2a4032d71a | ||
|
|
42c9f853a7 | ||
|
|
3389df77cc | ||
|
|
97732f7006 | ||
|
|
8f2457855c | ||
|
|
7e4c880e1e | ||
|
|
2a21285037 | ||
|
|
61bf77f668 | ||
|
|
cf583168dd | ||
|
|
236b528552 | ||
|
|
f730e476f0 | ||
|
|
3563568f6f | ||
|
|
912be5a792 | ||
|
|
30358100ab | ||
|
|
492665a8a1 | ||
|
|
005baea319 | ||
|
|
4f3b1edf9d | ||
|
|
2e692fca93 | ||
|
|
9dbd997141 | ||
|
|
416a82bf12 | ||
|
|
2e35dc648f | ||
|
|
55836e8ca6 | ||
|
|
a17acfb04f | ||
|
|
e9fe258b5e | ||
|
|
79e618415a | ||
|
|
bea0a491cf | ||
|
|
108b052e4e | ||
|
|
f5b593ff42 | ||
|
|
cdfd42053d | ||
|
|
36d4086673 | ||
|
|
01b541d8b0 | ||
|
|
928fce875e | ||
|
|
1d3c6e7420 | ||
|
|
c96fe2931a | ||
|
|
8a11dc0c90 | ||
|
|
324d427ac7 | ||
|
|
84c04cfe1c | ||
|
|
1925f2dec2 | ||
|
|
5235a72bca | ||
|
|
80c65ea8f3 | ||
|
|
3a2a7d0508 | ||
|
|
59002cb873 | ||
|
|
f49ce500a1 | ||
|
|
40b9130c63 | ||
|
|
e917b94929 | ||
|
|
abce12ccd9 | ||
|
|
83f8f8ebb8 | ||
|
|
4bd825e778 | ||
|
|
2fea5ff889 | ||
|
|
a94a42d609 | ||
|
|
4784f847c9 | ||
|
|
867d8510ca | ||
|
|
d53fb9d1b5 | ||
|
|
58b5c4cc16 | ||
|
|
10ecb6d368 | ||
|
|
e7c3ca9bd8 | ||
|
|
e8a4e9a31f | ||
|
|
43914852e5 | ||
|
|
c7f097ec84 | ||
|
|
7562f77bdf | ||
|
|
c4ed04fc82 | ||
|
|
f3061651d4 | ||
|
|
0b740826c5 | ||
|
|
e2d028fb97 | ||
|
|
e0913dc8e6 | ||
|
|
56f3b12171 | ||
|
|
927313968a | ||
|
|
2e54024b92 | ||
|
|
cdfcb1ed24 | ||
|
|
e6581aa09c | ||
|
|
8ebb000650 | ||
|
|
fc98bd1563 | ||
|
|
7ccf47f4c6 | ||
|
|
35debe46bc | ||
|
|
98c18f416a | ||
|
|
ea19971285 | ||
|
|
47d55694a4 | ||
|
|
f0e615dee5 | ||
|
|
5376b478b8 | ||
|
|
909e618f6c | ||
|
|
c492573429 | ||
|
|
8ae97b556e | ||
|
|
dfc0d4cf59 | ||
|
|
bfad624528 | ||
|
|
062b9ecbf3 | ||
|
|
d3cad5a651 | ||
|
|
a7ecf51915 | ||
|
|
893ae17b99 | ||
|
|
e48d5383ce | ||
|
|
9675acdf87 | ||
|
|
14229d0dd3 | ||
|
|
2b5d19924b | ||
|
|
3f658cc2ea | ||
|
|
6962bc5147 | ||
|
|
321957781e | ||
|
|
fd91513832 | ||
|
|
4fcfcc8117 | ||
|
|
11cecea597 | ||
|
|
e549833077 | ||
|
|
b15a5f03e6 | ||
|
|
7738083f3e | ||
|
|
98fe474276 | ||
|
|
03b8ecd0de | ||
|
|
bb669ccd2c | ||
|
|
e9d924b5d7 | ||
|
|
143601374c | ||
|
|
586c72fbe5 | ||
|
|
8bb832e23f | ||
|
|
184f522d5f | ||
|
|
0f0e23445a | ||
|
|
1b75e4de0d | ||
|
|
2deafa0dea | ||
|
|
938a621810 | ||
|
|
583a047e83 | ||
|
|
57edfa7ae8 | ||
|
|
b4da2d35bf | ||
|
|
fd357f87be | ||
|
|
df8c69f73b | ||
|
|
8ce98e38dc | ||
|
|
3a00140797 | ||
|
|
bf580fcc06 | ||
|
|
31d9208172 | ||
|
|
508ea9153c | ||
|
|
6ff16e2651 | ||
|
|
da682717ab | ||
|
|
647b5d098f | ||
|
|
3a9e5f0f98 | ||
|
|
50c9aec436 | ||
|
|
ec7ecc285e | ||
|
|
dea0d07b9a | ||
|
|
357e7af6ad | ||
|
|
53057830e0 | ||
|
|
7ae0317b6a | ||
|
|
547df2219a | ||
|
|
1c8c7479b8 | ||
|
|
36a960adec | ||
|
|
07ee4984cb | ||
|
|
e4448423fb | ||
|
|
50e9d02458 | ||
|
|
45233dd53c | ||
|
|
1a9fdc565c | ||
|
|
e32e616031 | ||
|
|
b14fb1759d | ||
|
|
abd757d356 | ||
|
|
28645b492e | ||
|
|
3919c8f79f | ||
|
|
803be11bbc | ||
|
|
335de94343 | ||
|
|
b62463107c | ||
|
|
93ce1661af | ||
|
|
f59ed38a38 | ||
|
|
3fad69e5ca | ||
|
|
005db13c45 | ||
|
|
d7ddafb39f | ||
|
|
3fe7bf27de | ||
|
|
4b718929df | ||
|
|
a44c908147 | ||
|
|
1bf37305a8 | ||
|
|
ed4d589077 | ||
|
|
47a080d79c | ||
|
|
66a8e5ddbb | ||
|
|
8c39ed61a9 | ||
|
|
a12d403981 | ||
|
|
ccf0274d13 | ||
|
|
21103f8bc4 | ||
|
|
a1ba44db72 | ||
|
|
3c22a7b482 | ||
|
|
d056b13e14 | ||
|
|
7a39ccf7bb | ||
|
|
3be90c2e45 | ||
|
|
60caecffdd | ||
|
|
df3eb562f0 | ||
|
|
c4b247e75e | ||
|
|
d9fdd0ce36 | ||
|
|
226fcac72e | ||
|
|
5c8a911c93 | ||
|
|
2cc1844d97 | ||
|
|
3916d5c567 | ||
|
|
ef51c1c2b2 | ||
|
|
f637faf0d2 | ||
|
|
d010f4fcae | ||
|
|
d5e436d15b | ||
|
|
18ee1ba589 | ||
|
|
795b39250f | ||
|
|
ae89f1b3b3 | ||
|
|
cbe600369c | ||
|
|
1de1b58a08 | ||
|
|
4f577cbdeb | ||
|
|
c2bd7d1e56 | ||
|
|
e501289a55 | ||
|
|
1ebc9de1e6 | ||
|
|
f34b060e23 | ||
|
|
84064b90a6 | ||
|
|
08e21fd0b8 | ||
|
|
1077686bda | ||
|
|
582d075c45 | ||
|
|
b60f1085db | ||
|
|
a3bdfc1580 | ||
|
|
76a8711570 | ||
|
|
87b424123b | ||
|
|
9a66d47d54 | ||
|
|
5a0712f766 | ||
|
|
660ea89521 | ||
|
|
60204becf4 | ||
|
|
032216153f | ||
|
|
dac4447e33 | ||
|
|
fa94c0a65b | ||
|
|
76d78571d6 | ||
|
|
556407408f | ||
|
|
a862bf488c | ||
|
|
f629dc51aa | ||
|
|
96cc6a916d | ||
|
|
6c0e0b3eae | ||
|
|
8a129610da | ||
|
|
8688753522 | ||
|
|
9a0400c93a | ||
|
|
13b5eb0ad8 | ||
|
|
e059efb4c4 | ||
|
|
0be74c6551 | ||
|
|
6fe6e1596f | ||
|
|
0e7c3951a6 | ||
|
|
40c8549cf5 | ||
|
|
a7ea370ec3 | ||
|
|
b6c6f06537 | ||
|
|
2e531c103f | ||
|
|
1a05939e0b | ||
|
|
acb8e85b61 | ||
|
|
8c38841a4d | ||
|
|
2c2ee706ac | ||
|
|
b7df4de4b7 | ||
|
|
b237425c94 | ||
|
|
bd3708870d | ||
|
|
2aa699d03e | ||
|
|
1d20b2603a | ||
|
|
6576f9c0c3 | ||
|
|
f840082aae | ||
|
|
f162508ad1 | ||
|
|
3ccefa20e8 | ||
|
|
00b19ccee0 | ||
|
|
54d55fb62f | ||
|
|
dcc8a94d07 | ||
|
|
5dd501e0ea | ||
|
|
af7a3fc2ea | ||
|
|
4b4b06bec5 | ||
|
|
54259593ea | ||
|
|
73cb270b14 | ||
|
|
3d1df8337e | ||
|
|
f08001a5a6 | ||
|
|
ecbba93784 | ||
|
|
47ebddf99f | ||
|
|
c70ac572fa | ||
|
|
f0a2747d80 | ||
|
|
67918033f9 | ||
|
|
93335cdb0e | ||
|
|
e308c3d34a | ||
|
|
977677d005 | ||
|
|
faf9814788 | ||
|
|
eeb9103e26 | ||
|
|
1f6386bd60 | ||
|
|
5c7acf4807 | ||
|
|
a92b9b7adb | ||
|
|
b4529229d2 | ||
|
|
bc776a9534 | ||
|
|
45c64c2d2e | ||
|
|
73f41023f3 | ||
|
|
139c1a956f | ||
|
|
b08af13872 | ||
|
|
1e59d9ade5 | ||
|
|
519aef7ff5 | ||
|
|
05cbdc6915 | ||
|
|
8d5e028b5b | ||
|
|
153ffbe558 | ||
|
|
394352d882 | ||
|
|
c0edfee224 | ||
|
|
06d2d31777 | ||
|
|
535691a05c | ||
|
|
d2058ee151 | ||
|
|
263cfe2538 | ||
|
|
717190975f | ||
|
|
d6a3f7765a | ||
|
|
f9d40adb18 | ||
|
|
087f9784e3 | ||
|
|
3bd74aabaa | ||
|
|
4933aef543 | ||
|
|
0e5d824bff | ||
|
|
b2d2dcc7fe | ||
|
|
7acb068590 | ||
|
|
80ec92ce8d | ||
|
|
83c4dd6bda | ||
|
|
e332d1074f | ||
|
|
42ed73ed4a | ||
|
|
5ed5c76d3f | ||
|
|
fe2288a88f | ||
|
|
8f0a0add1e | ||
|
|
3645eb18f8 | ||
|
|
610e80a19b | ||
|
|
d8460f147b | ||
|
|
71e508c7cd | ||
|
|
d3fcef43f8 | ||
|
|
cbc906c438 | ||
|
|
d57169fcf6 | ||
|
|
fdf639e1fb | ||
|
|
25760e30f9 | ||
|
|
3cdcb121c5 | ||
|
|
968209471e | ||
|
|
d71a53f24e | ||
|
|
c845d20352 | ||
|
|
11e888fb7c | ||
|
|
230617208b | ||
|
|
e99be61d49 | ||
|
|
635b8ff73a | ||
|
|
c9daafc887 | ||
|
|
033cf61380 | ||
|
|
70e17f9194 | ||
|
|
89e7e5e4fb | ||
|
|
ab32372f8f | ||
|
|
2778e63d6c | ||
|
|
d16fbda0f8 | ||
|
|
e8ea8d203d | ||
|
|
ac670856f6 | ||
|
|
88149f56bb | ||
|
|
6fcfab3488 | ||
|
|
dab3e90353 | ||
|
|
1c304eb8ba | ||
|
|
d1c84ad9f0 | ||
|
|
c39a680096 | ||
|
|
e8ddee284c | ||
|
|
abd7cfdc97 | ||
|
|
c904bd3a62 | ||
|
|
d48bda88e6 | ||
|
|
4ca24f114b | ||
|
|
7667c630a4 | ||
|
|
97458b2885 | ||
|
|
803bff4043 | ||
|
|
17aa8da9f0 | ||
|
|
7d5ee81628 | ||
|
|
b88be137ca | ||
|
|
195eb71200 | ||
|
|
f36e384ed7 | ||
|
|
3a3bd582b1 | ||
|
|
a342a5f8e0 | ||
|
|
42d139ee82 | ||
|
|
f1c6fd08c4 | ||
|
|
8ad2b3e7a1 | ||
|
|
a84695bb86 | ||
|
|
c2ec3b0bf4 | ||
|
|
bda9a833ba | ||
|
|
ac12f923ea | ||
|
|
b6be0e1b99 | ||
|
|
01809b08c9 | ||
|
|
42f5291f69 | ||
|
|
1d271ee771 | ||
|
|
1d19ea4a33 | ||
|
|
0d9b6ebc36 | ||
|
|
d9a48092e6 | ||
|
|
02ea713d6a | ||
|
|
94f15e3551 | ||
|
|
2d90b831f0 | ||
|
|
35110b6327 | ||
|
|
f52c670c05 | ||
|
|
f3adc8d738 | ||
|
|
40f6280c48 | ||
|
|
1c6d2857cb | ||
|
|
09967598e1 | ||
|
|
d3feb93619 | ||
|
|
0bba5cdc30 | ||
|
|
a3b1eec548 | ||
|
|
f174c4fccb | ||
|
|
32eead1542 | ||
|
|
1701e100cf | ||
|
|
397fef519c | ||
|
|
53bd0146bb | ||
|
|
a037758245 | ||
|
|
ffce1fc177 | ||
|
|
368f88740a | ||
|
|
ab369ab91d | ||
|
|
ddddf29f82 | ||
|
|
fdc36fb140 | ||
|
|
9ce5e25507 | ||
|
|
0bc4de2f34 | ||
|
|
e3dc242a3c | ||
|
|
bff2ed3837 | ||
|
|
9c31e26cf1 | ||
|
|
7a31c039fb | ||
|
|
7cca2b7fb0 | ||
|
|
10e5cf01cc | ||
|
|
384c19e54e | ||
|
|
7d5e7bf6c8 | ||
|
|
b6459e6172 | ||
|
|
b4f65840d1 | ||
|
|
b266ade4fe | ||
|
|
0f0fba0e9e | ||
|
|
54f25609c9 | ||
|
|
c48e90a556 | ||
|
|
e0409386c2 | ||
|
|
2aa69257a4 | ||
|
|
60d4b4c4f6 | ||
|
|
4a6a06fdc0 | ||
|
|
c631da7b0d | ||
|
|
9d425b4727 | ||
|
|
07d62bc111 | ||
|
|
91d0f87181 | ||
|
|
1c32564536 | ||
|
|
da07108be9 | ||
|
|
d7f4526a00 | ||
|
|
63dd6ad01a | ||
|
|
7b173a75e4 | ||
|
|
cb5a047e5d | ||
|
|
ed5abe5981 | ||
|
|
940534e303 | ||
|
|
1609473e5d | ||
|
|
1f951e2bd3 | ||
|
|
ed8e4962b9 | ||
|
|
10f9f9cc80 | ||
|
|
56c8e00b84 | ||
|
|
063577c19e | ||
|
|
57f20c0c22 | ||
|
|
e682b93883 | ||
|
|
a32b097e3c | ||
|
|
2ebf76cd50 | ||
|
|
65e5894363 | ||
|
|
dbef80f7bd | ||
|
|
06b0c89aee | ||
|
|
113bfe8fa2 | ||
|
|
df4e193990 | ||
|
|
28207c3313 | ||
|
|
e685c580f2 | ||
|
|
e6139c9f49 | ||
|
|
fac654ec5d | ||
|
|
1352e334b1 | ||
|
|
69ab6639b2 | ||
|
|
d52ee7ae27 | ||
|
|
ebcfc7f2b2 | ||
|
|
b347e1d861 | ||
|
|
8cb4a29a51 | ||
|
|
9fb08fb502 | ||
|
|
6710a77c26 | ||
|
|
e442fe753e | ||
|
|
a4685e6df3 | ||
|
|
a4f6c24273 | ||
|
|
53853814ff | ||
|
|
fb31f629c6 | ||
|
|
50612565e9 | ||
|
|
a92256e1cb | ||
|
|
d6c23486d5 | ||
|
|
d2bafdb2bf | ||
|
|
f2f2b534e6 | ||
|
|
2d9ae8ff2c | ||
|
|
4e4d406d23 | ||
|
|
a9bda2b12e | ||
|
|
5fb7ea8dbd | ||
|
|
d35678b891 | ||
|
|
405e3fc214 | ||
|
|
fbba78411d | ||
|
|
75cd816e02 | ||
|
|
c8a886e399 | ||
|
|
19b2568133 | ||
|
|
ccc8a05eb0 | ||
|
|
26125bcf0b | ||
|
|
263efbfe39 | ||
|
|
9a5ce2354d | ||
|
|
f25f5aeaaa | ||
|
|
af14020e42 | ||
|
|
4a49643bcd | ||
|
|
29596d12e3 | ||
|
|
1a28fb2a0c | ||
|
|
d985db60cc | ||
|
|
a76ad1478f | ||
|
|
044067f055 | ||
|
|
810d9e21bc | ||
|
|
7256579c16 | ||
|
|
ecf30b2c71 | ||
|
|
95f4f14dca | ||
|
|
391854058e | ||
|
|
1bcee2f11c | ||
|
|
572a04b40a | ||
|
|
d9ee8b2c32 | ||
|
|
614366e499 | ||
|
|
89e3f3210f | ||
|
|
dc55c710da | ||
|
|
47817b8ae1 | ||
|
|
3e66549ea4 | ||
|
|
8b7d0f33c3 | ||
|
|
a20fd4d463 | ||
|
|
bfd506f184 | ||
|
|
c20aa6062c | ||
|
|
b2a51db14e | ||
|
|
33ff7bf968 | ||
|
|
57a8b3f857 | ||
|
|
6e5a06421f | ||
|
|
5f0004b416 | ||
|
|
e79f450af9 | ||
|
|
c4f5d17db6 | ||
|
|
d1a018f2e8 | ||
|
|
6118570118 | ||
|
|
a9cceea850 | ||
|
|
81736a0129 | ||
|
|
dea4879938 | ||
|
|
2e2f984c45 | ||
|
|
bb639b08f7 | ||
|
|
5167f70015 | ||
|
|
cca5349110 | ||
|
|
5abe7d2dfb | ||
|
|
181d9a0777 | ||
|
|
5219c4a09a | ||
|
|
4da65183e0 | ||
|
|
b51ca4c8d3 | ||
|
|
198d2ab607 | ||
|
|
f43428aacf | ||
|
|
2d4f84563b | ||
|
|
418d102663 | ||
|
|
3b6a0d8e5c | ||
|
|
29c9972b86 | ||
|
|
7033966bb8 | ||
|
|
e90e4e4a59 | ||
|
|
954176cfc3 | ||
|
|
a8a6d807ff | ||
|
|
fe5f109af5 | ||
|
|
f1da003020 | ||
|
|
ea5a7180c7 | ||
|
|
9d0e2cbd89 | ||
|
|
032b6f193d | ||
|
|
e49c59959b | ||
|
|
b03cd330e5 | ||
|
|
542fa4a08c | ||
|
|
515f1e76b0 | ||
|
|
d95f7efea7 | ||
|
|
e97dd48b4c | ||
|
|
5915f31950 | ||
|
|
8caa4d9e37 | ||
|
|
d5525a38f1 | ||
|
|
e9a5af6109 | ||
|
|
fd6b32758e | ||
|
|
4387fb715b | ||
|
|
d7aaca6947 | ||
|
|
fa5115b3ed | ||
|
|
ec5e1067bc | ||
|
|
ee46faff1a | ||
|
|
fa629841bd | ||
|
|
155b57c2de | ||
|
|
6ea32a8ba3 | ||
|
|
8d72cea2d1 | ||
|
|
3ee4dd0d52 | ||
|
|
0f7832dc30 | ||
|
|
107083e3e4 | ||
|
|
d7a9d22a15 | ||
|
|
ecfbb10326 | ||
|
|
6c92a240cc | ||
|
|
0bad26e116 | ||
|
|
cd57483ed9 | ||
|
|
0908da9529 | ||
|
|
6e101e4582 | ||
|
|
f60309efa1 | ||
|
|
47f4007951 | ||
|
|
74f58818d6 | ||
|
|
17977effe7 | ||
|
|
477ed97c2f | ||
|
|
242ef70a77 | ||
|
|
755b751614 | ||
|
|
ad3a327366 | ||
|
|
a54bb07753 | ||
|
|
323ab3dba4 | ||
|
|
6947194824 | ||
|
|
879350b658 | ||
|
|
046e5e239f | ||
|
|
c5828fecc1 | ||
|
|
d12b360e92 | ||
|
|
5564b47dbc | ||
|
|
28ad60f892 | ||
|
|
171b6a222d | ||
|
|
f05181322c | ||
|
|
33d23a4a61 | ||
|
|
3e6088c614 | ||
|
|
8292553a20 | ||
|
|
6375401e0a | ||
|
|
b6b62506c5 | ||
|
|
f66aa336ac | ||
|
|
779cab047a | ||
|
|
cd575e80dd | ||
|
|
060cc15f81 | ||
|
|
6ed5784491 | ||
|
|
eab9040ee7 | ||
|
|
099b30afbf | ||
|
|
5cbf603203 | ||
|
|
c327b00efa | ||
|
|
7634d4ce69 | ||
|
|
98c6548d64 | ||
|
|
d169ee658e | ||
|
|
f718e2b0db | ||
|
|
dc59817a9d | ||
|
|
66fcea0ad8 | ||
|
|
a572609dbd | ||
|
|
94e458018b | ||
|
|
e5e0a6b31f | ||
|
|
5c63f7dd58 | ||
|
|
b0b5db770d | ||
|
|
878614f97a | ||
|
|
49e77e0f71 | ||
|
|
2115eb26a7 | ||
|
|
4f4c9bf5d6 | ||
|
|
90ab050493 | ||
|
|
28e0911f29 | ||
|
|
fd23844c8d | ||
|
|
5dc457b16c | ||
|
|
aadfb97d5a | ||
|
|
83abceb8be | ||
|
|
727a2fe4ea | ||
|
|
cb6c21ce90 | ||
|
|
a2e1019978 | ||
|
|
1171e1dd9c | ||
|
|
fff7be2c0f | ||
|
|
a1ef698cf2 | ||
|
|
43a794a905 | ||
|
|
4d50fe0928 | ||
|
|
e98938d03d | ||
|
|
c3c1572683 | ||
|
|
708f738952 | ||
|
|
5f1da17406 | ||
|
|
0499deea69 | ||
|
|
0fb0241901 | ||
|
|
24b55bbc9b | ||
|
|
3a7db8ec60 | ||
|
|
bc3e1e99fe | ||
|
|
efdd95fe7f | ||
|
|
65ecc5ae15 | ||
|
|
83a78a949d | ||
|
|
a7bf4366ce | ||
|
|
066ab8c1fc | ||
|
|
bedc393425 | ||
|
|
c1cc7bfc94 | ||
|
|
caae956f6e | ||
|
|
30a3339653 | ||
|
|
ef73607288 | ||
|
|
e7c3ecd192 | ||
|
|
a7d184ba54 | ||
|
|
546867c102 | ||
|
|
42fbc28b11 | ||
|
|
82631c3413 | ||
|
|
b153c651b4 | ||
|
|
8821986d87 | ||
|
|
35fc7328de | ||
|
|
7a611c6d47 | ||
|
|
f252f3efc5 | ||
|
|
da823125b9 | ||
|
|
7de5717418 | ||
|
|
a6f232f2b0 | ||
|
|
cbcd195461 | ||
|
|
837efcf5e7 | ||
|
|
8b0bcdb2a5 | ||
|
|
ca14ab3d55 | ||
|
|
cfdf1def2a | ||
|
|
37d350c3f5 | ||
|
|
b10c519cc1 | ||
|
|
78aeb50ce5 | ||
|
|
a12a614e7e | ||
|
|
f746418fda | ||
|
|
1bdab6e633 | ||
|
|
1bf2a9d47b | ||
|
|
8b4b135036 | ||
|
|
be10bf2ceb | ||
|
|
d4bd4ca000 | ||
|
|
2f3f95d3a9 | ||
|
|
d958f1099b | ||
|
|
7b0f3d9e26 | ||
|
|
92d581a342 | ||
|
|
8e11b2d6f0 | ||
|
|
79bd2ddd9c | ||
|
|
949ca844c5 | ||
|
|
f31af3c7c0 | ||
|
|
a0245f3e93 | ||
|
|
99811c90b6 | ||
|
|
c85f1a208d | ||
|
|
774923be1c | ||
|
|
d78b64d5b3 | ||
|
|
0938db8f7b | ||
|
|
d2c971eda9 | ||
|
|
57584ea429 | ||
|
|
49d84a364d | ||
|
|
89b5507354 | ||
|
|
2a25ddff36 | ||
|
|
b0b96daec0 | ||
|
|
8764cdf16a | ||
|
|
a45dd09fc0 | ||
|
|
320c32fd0f | ||
|
|
4afeefb5ce | ||
|
|
b2ad4e8c2a | ||
|
|
2bdf63d069 | ||
|
|
b897fd8315 | ||
|
|
82b35e2762 | ||
|
|
56f32104d5 | ||
|
|
2556d05602 | ||
|
|
7b06cb6682 | ||
|
|
cbd401c3e8 | ||
|
|
9277806664 | ||
|
|
828028259c | ||
|
|
d10525a375 | ||
|
|
d903758940 | ||
|
|
cf11ba1147 | ||
|
|
446b5550a2 | ||
|
|
4c2bdc9dc0 | ||
|
|
051759580d | ||
|
|
fb3f63bf59 | ||
|
|
f6b643e84e | ||
|
|
16d750d1f6 | ||
|
|
dfd626548f | ||
|
|
92d7c32f61 | ||
|
|
0ee48f6a58 | ||
|
|
664c762b35 | ||
|
|
9cb9608209 | ||
|
|
b20062efa6 | ||
|
|
8d4744d115 | ||
|
|
14f16a7ef0 | ||
|
|
df6c07aaad | ||
|
|
c95e9b9ba5 | ||
|
|
472a824a1e | ||
|
|
16df1c1ad4 | ||
|
|
e1fe637dcd | ||
|
|
2dce86d38e | ||
|
|
bcd02edd80 | ||
|
|
a73ea134cd | ||
|
|
e7a5aa7b9c | ||
|
|
aa33cacb62 | ||
|
|
0c74c79b18 | ||
|
|
0c973cc9fa | ||
|
|
62c921815f | ||
|
|
211cda540d | ||
|
|
6078d02c3a | ||
|
|
fa89b8f66d | ||
|
|
e399de8ad4 | ||
|
|
32a9487ff9 | ||
|
|
e891380ed5 | ||
|
|
2c73b457ef | ||
|
|
2f5f1a4d64 | ||
|
|
5c080ca4e8 | ||
|
|
4a85726e55 | ||
|
|
cb2eee1d2e | ||
|
|
8e80500ee6 | ||
|
|
03db9833e8 | ||
|
|
33153b8f3a | ||
|
|
3b2398ed01 | ||
|
|
a0a376e95e | ||
|
|
7b9df1d401 | ||
|
|
1244b0e36a | ||
|
|
ab58c95d27 | ||
|
|
a153368814 | ||
|
|
41fd729209 | ||
|
|
58aa0f3e1a | ||
|
|
02b390d7b8 | ||
|
|
41c2f74772 | ||
|
|
6c641b1834 | ||
|
|
700c05a55b | ||
|
|
188782c461 | ||
|
|
bdfdd23b36 | ||
|
|
9f0c3b496b | ||
|
|
1ae715da21 | ||
|
|
d5feb5135d | ||
|
|
fc533107ed | ||
|
|
1ee76cb506 | ||
|
|
4bb90dffc1 | ||
|
|
f4cd4184f8 | ||
|
|
c39c925d8d | ||
|
|
b1fc29be11 | ||
|
|
2a1f6e3df2 | ||
|
|
6f3493bb3c | ||
|
|
61257094b7 | ||
|
|
8aabc6bc3d | ||
|
|
f68148b7e0 | ||
|
|
4c526c7d3d | ||
|
|
4a24a8de43 | ||
|
|
b8ad22f525 | ||
|
|
d9ecca8591 | ||
|
|
83d07b9551 | ||
|
|
ee03391293 | ||
|
|
30503d6533 | ||
|
|
bbb83bea38 | ||
|
|
0f9ddbf3b2 | ||
|
|
8c4b8e623f | ||
|
|
b1c97dfcfd | ||
|
|
1a49f0d164 | ||
|
|
a2371d56fd | ||
|
|
c93db2cd21 | ||
|
|
15d422db80 | ||
|
|
14d1912115 | ||
|
|
b6477cd38b | ||
|
|
c42cbda904 | ||
|
|
39d56fd08f | ||
|
|
403f4c1a6b | ||
|
|
15ab331b6b | ||
|
|
495da14e38 | ||
|
|
bc2b948f1f | ||
|
|
ff9442474d | ||
|
|
9ca53fdc5d | ||
|
|
8e3a026276 | ||
|
|
b5ddd08630 | ||
|
|
92996e550c | ||
|
|
a037590ce3 | ||
|
|
c3c4254882 | ||
|
|
a18e8e1ede | ||
|
|
751c4c3169 | ||
|
|
595cb13d8f | ||
|
|
f783d594cc | ||
|
|
6e32be7e43 | ||
|
|
9e44b07275 | ||
|
|
4471c45fb7 | ||
|
|
99e681c09f | ||
|
|
4f5e9d77b2 | ||
|
|
98ccdf65fb | ||
|
|
4c0c153b8f | ||
|
|
c533c62c64 | ||
|
|
384db9d10d | ||
|
|
5d8b0acc16 | ||
|
|
3d23f4ec77 | ||
|
|
215bd07f0b | ||
|
|
6c79e0c077 | ||
|
|
b2ea61ea3e | ||
|
|
47d2467e24 | ||
|
|
a165303602 | ||
|
|
8e1716065e | ||
|
|
7251ce6e17 | ||
|
|
eaefb36212 | ||
|
|
a2f6f48daf | ||
|
|
a894456550 | ||
|
|
608e679d33 | ||
|
|
155844f142 | ||
|
|
cee9a20e85 | ||
|
|
70ca4a7fea | ||
|
|
7445f1881e | ||
|
|
e58dc726c5 | ||
|
|
1eba847e99 | ||
|
|
6bf6462a37 | ||
|
|
729d52f10a | ||
|
|
79e8e4599e | ||
|
|
ba5cfd8b25 | ||
|
|
dd8a3d845e | ||
|
|
66fc1dcf33 | ||
|
|
816f4907e3 | ||
|
|
d7e24b2494 | ||
|
|
288905c361 | ||
|
|
d4a957ca16 | ||
|
|
3071f3b71c | ||
|
|
e08e6c182c | ||
|
|
1ca0b85196 | ||
|
|
df57e7ab93 | ||
|
|
fa02f3a108 | ||
|
|
07d443a159 | ||
|
|
360397b2ed | ||
|
|
fa944fc526 | ||
|
|
df6e75e1d6 | ||
|
|
c49935d91c | ||
|
|
85082ea509 | ||
|
|
47731c75fc | ||
|
|
b5481edfd7 | ||
|
|
1325a81e9a | ||
|
|
1acfe53f74 | ||
|
|
265eb2b440 | ||
|
|
18b22f5f8a | ||
|
|
d609d2d2ad | ||
|
|
503c368f9e | ||
|
|
2848d1caaf | ||
|
|
69e145a630 | ||
|
|
a6d13f290b | ||
|
|
1a28720c56 | ||
|
|
b6cad08273 | ||
|
|
805cae7b31 | ||
|
|
7f423016f0 | ||
|
|
1070f3ed6b | ||
|
|
a41603ed85 | ||
|
|
2467698045 | ||
|
|
f93431b43e | ||
|
|
f5a03102d8 | ||
|
|
b6c4e6a6d0 | ||
|
|
8e3e90ddd2 | ||
|
|
e0e30ead58 | ||
|
|
0f208fb36b | ||
|
|
94fdcabac9 | ||
|
|
8a69a5c3c7 | ||
|
|
4f07abe655 | ||
|
|
bc01b6b4ad | ||
|
|
8783ccfd72 | ||
|
|
e819727b09 | ||
|
|
92615247ac | ||
|
|
78ed01f3ef | ||
|
|
4b1f87050f | ||
|
|
919de44a71 | ||
|
|
232862ae08 | ||
|
|
d59095c2e6 | ||
|
|
285e04c77e | ||
|
|
70f8840fbd | ||
|
|
8d0d2015d7 | ||
|
|
cf11a89457 | ||
|
|
65e18f5b8f | ||
|
|
732dfa63c7 | ||
|
|
b1ff5367e7 | ||
|
|
96fdb88690 | ||
|
|
3e992604c7 | ||
|
|
e9243e9660 | ||
|
|
59645f51a9 | ||
|
|
c866c48252 | ||
|
|
7b4d0168c0 | ||
|
|
dd3e530a63 | ||
|
|
3e2e60fb86 | ||
|
|
9bab858fd1 | ||
|
|
0ef8c5bda8 | ||
|
|
d4be96cd03 | ||
|
|
3d0c6700db | ||
|
|
5012baba15 | ||
|
|
41c67fa345 | ||
|
|
c75852455b | ||
|
|
27fa15e95d | ||
|
|
175e222927 | ||
|
|
55924f5c5b | ||
|
|
956f0043fc | ||
|
|
70cdbe4816 | ||
|
|
6644dc4861 | ||
|
|
3e144baacd | ||
|
|
bbacfbdd6a | ||
|
|
cbc0e5b934 | ||
|
|
81d556d32e | ||
|
|
5ad5a0fa07 | ||
|
|
e54ba7ecbc | ||
|
|
1c1d1f1185 | ||
|
|
bc1812840a | ||
|
|
74def75ca3 | ||
|
|
924b353e5a | ||
|
|
31618a4310 | ||
|
|
21e3481810 | ||
|
|
d7ba2c7168 | ||
|
|
6f811fd7f9 | ||
|
|
573846707c | ||
|
|
02e487f306 | ||
|
|
73b28b5d94 | ||
|
|
2a7ec29cd1 | ||
|
|
d4f8a8dedd | ||
|
|
f23c380cae | ||
|
|
7151467db7 | ||
|
|
16a8416495 | ||
|
|
5db3b71c6a | ||
|
|
8897c5763a | ||
|
|
07d92796d2 | ||
|
|
1f39c16d99 | ||
|
|
c8aeb5b160 | ||
|
|
69b08a2062 | ||
|
|
05fd5eb8be | ||
|
|
8ed0913df6 | ||
|
|
d85bcb2e37 | ||
|
|
09e5732f8a | ||
|
|
d7fcf31be5 | ||
|
|
f63aaa5429 | ||
|
|
321241da02 | ||
|
|
7c72886b1b | ||
|
|
2a52592292 | ||
|
|
ccdfbc721f | ||
|
|
a3436aea02 | ||
|
|
f62b2fc114 | ||
|
|
baf612bd59 | ||
|
|
f3490440b4 | ||
|
|
5cc1c30d7f | ||
|
|
0017de46e4 | ||
|
|
1cd1328b0c | ||
|
|
8ff9ad7636 | ||
|
|
1ba1c5b44e | ||
|
|
7db55d8db2 | ||
|
|
e058b19f53 | ||
|
|
bc3605a502 | ||
|
|
ce4daad431 | ||
|
|
0360d42d30 | ||
|
|
1fb37f93cc | ||
|
|
fce33402e7 | ||
|
|
abadd0bd34 | ||
|
|
16f27d0004 | ||
|
|
242eede258 | ||
|
|
8dc349caac | ||
|
|
91819bfc2d | ||
|
|
6ee691e019 | ||
|
|
28f0833237 | ||
|
|
eb415fd869 | ||
|
|
ace0a1cb75 | ||
|
|
6ceaea8478 | ||
|
|
30659aef50 | ||
|
|
46d0e23e7b | ||
|
|
2d3e20d96e | ||
|
|
723b51c931 | ||
|
|
a6160e3026 | ||
|
|
ecca69442d | ||
|
|
b2bae867d0 | ||
|
|
cfe843b870 | ||
|
|
1cef3f15d5 | ||
|
|
1bb56309a6 | ||
|
|
6468b7a914 | ||
|
|
6a083e8452 | ||
|
|
27cac334e1 | ||
|
|
947478ca76 | ||
|
|
c75357faa3 | ||
|
|
e9a27393b8 | ||
|
|
5d12c56510 | ||
|
|
00cfc4be44 | ||
|
|
70edcabca1 | ||
|
|
dce5e8d0cc | ||
|
|
59baf34170 | ||
|
|
5aa1146fe9 | ||
|
|
8059260c18 | ||
|
|
91bc8d473f | ||
|
|
3d4f2d146e | ||
|
|
ce61a64bd2 | ||
|
|
e2a498c8ca | ||
|
|
758e7b92eb | ||
|
|
cf4cdffcc1 | ||
|
|
e70c87ed41 | ||
|
|
d8472cc9f5 | ||
|
|
56a08f0d17 | ||
|
|
eb3685f537 | ||
|
|
201a6b8742 | ||
|
|
e2ee4ae024 | ||
|
|
23e3e2c504 | ||
|
|
ab698305bf | ||
|
|
143ae2b788 | ||
|
|
baf50ea84a | ||
|
|
73845e01ed | ||
|
|
178e3d5bc8 | ||
|
|
a94254a375 | ||
|
|
fc4083346e | ||
|
|
f79a11cbf7 | ||
|
|
edc0a7ef91 | ||
|
|
dce9a70ff5 | ||
|
|
631a8278d3 | ||
|
|
bae37c8e6f | ||
|
|
a5c1685ea0 | ||
|
|
d0a0051d85 | ||
|
|
8e4960f31d | ||
|
|
dd2a5e6b28 | ||
|
|
7e1e9ac94a | ||
|
|
29daf1ecee | ||
|
|
c62df39ce3 | ||
|
|
a91e7cbe8d | ||
|
|
159f02ba07 | ||
|
|
2daafe80a5 | ||
|
|
028b2a655d | ||
|
|
fd52cefe09 | ||
|
|
0e0dee43ab | ||
|
|
e2ee565f05 | ||
|
|
63e06578c4 | ||
|
|
a1f03015ec | ||
|
|
8220a6584c | ||
|
|
d4b51c491f | ||
|
|
3f66d9f8cd | ||
|
|
852073fc68 | ||
|
|
17082cda3c | ||
|
|
7ffa98118f | ||
|
|
c3bada3c32 | ||
|
|
23303391e0 | ||
|
|
8ac8acc49c | ||
|
|
94290102b6 | ||
|
|
f94c244b9f | ||
|
|
ec823196e0 | ||
|
|
957647bf06 | ||
|
|
df5524979d | ||
|
|
0ae3e50bd4 | ||
|
|
db710cd2df | ||
|
|
61407ad6c8 | ||
|
|
2e0180ba55 | ||
|
|
d476b7477b | ||
|
|
ec037abf92 | ||
|
|
1a56045b42 | ||
|
|
bf820beb79 | ||
|
|
cde7a3f66c | ||
|
|
4f99d641c5 | ||
|
|
f4aca35a88 | ||
|
|
732065bf13 | ||
|
|
d3d540a28b | ||
|
|
a6cbebe03c | ||
|
|
e1b54b6843 | ||
|
|
aadbd5a92d | ||
|
|
7b065365e0 | ||
|
|
d0827dbb3c | ||
|
|
fab103524a | ||
|
|
15be542e56 | ||
|
|
eebea70019 | ||
|
|
b58d56826b | ||
|
|
e770768b79 | ||
|
|
17011a7637 | ||
|
|
f891860408 | ||
|
|
3424c7dc87 | ||
|
|
dbf7ff9791 | ||
|
|
9addcfe827 | ||
|
|
d5d67708ac | ||
|
|
5aa0017e91 | ||
|
|
f90d5f3dc8 | ||
|
|
8b5793e629 | ||
|
|
de668f5999 | ||
|
|
606463114b | ||
|
|
40242ff7dc | ||
|
|
e411c7e8b3 | ||
|
|
80e1130bb5 | ||
|
|
d9a5b11c9a | ||
|
|
22839e48d0 | ||
|
|
f7f39cf6c0 | ||
|
|
54826808cf | ||
|
|
b30e799847 | ||
|
|
b4aaa1953c | ||
|
|
d64dcd298e | ||
|
|
02e8058c50 | ||
|
|
93057fae8c | ||
|
|
5bc6941b57 | ||
|
|
45dbd31d28 | ||
|
|
45a9eca792 | ||
|
|
b43064ce6e | ||
|
|
660c658c85 | ||
|
|
7804ae6a78 | ||
|
|
c916906716 | ||
|
|
1db57c498d | ||
|
|
54f7cd5302 | ||
|
|
9e70d54300 | ||
|
|
7465ca269b | ||
|
|
508157f07f | ||
|
|
33aa373b3f | ||
|
|
d96a7bc1fa | ||
|
|
dad8397763 | ||
|
|
e26295b6fa | ||
|
|
c8239c739d | ||
|
|
6c4f7caba1 | ||
|
|
cb47354a4f | ||
|
|
61588a4b77 | ||
|
|
142dd0053a | ||
|
|
0d9e12737a | ||
|
|
dfafa81bfe | ||
|
|
cda284424f | ||
|
|
610699d3c4 | ||
|
|
17f1d39fcf | ||
|
|
85766126e3 | ||
|
|
3bafa05ad1 | ||
|
|
1627297143 | ||
|
|
951376852c | ||
|
|
4d3647066f | ||
|
|
9e509aa25b | ||
|
|
d2226c0e9b | ||
|
|
1d65bc6382 | ||
|
|
b513662b52 | ||
|
|
8794106e85 | ||
|
|
88caa14030 | ||
|
|
bb233a9872 | ||
|
|
9acd3ebd42 | ||
|
|
0368b6730f | ||
|
|
ece1dd1d7e | ||
|
|
f57926d9ec | ||
|
|
96f196febd | ||
|
|
4295b1945e | ||
|
|
5ce96b9b95 | ||
|
|
7dfadfea4a | ||
|
|
d4e58e94f6 | ||
|
|
6e504b7bc9 | ||
|
|
7f944515de | ||
|
|
b6595a44d1 | ||
|
|
335d9af8dc | ||
|
|
8478ecc675 | ||
|
|
e5662dc893 | ||
|
|
0ef2cd8719 | ||
|
|
c32bc9dda4 | ||
|
|
d7080defd3 | ||
|
|
b20cce1408 | ||
|
|
9682c48b5b | ||
|
|
6a242f0d08 | ||
|
|
b1f3ccc6ee | ||
|
|
a36d74dad5 | ||
|
|
128d47430d | ||
|
|
e843d27f8c | ||
|
|
4f1e4ffa70 | ||
|
|
7249eebc75 | ||
|
|
8ea0b2051a | ||
|
|
c8678ba5a9 | ||
|
|
2ace4c57d0 | ||
|
|
8ef84e2aa7 | ||
|
|
bb0f3afb71 | ||
|
|
9fb8661eef | ||
|
|
91b81d6a2c | ||
|
|
88ac326caf | ||
|
|
bdd420a08e | ||
|
|
76daa03df0 | ||
|
|
62ad4dd109 | ||
|
|
41dc40dd84 | ||
|
|
2fc47cc52b | ||
|
|
9ad44a2060 | ||
|
|
5092cb75f4 | ||
|
|
f2f6a05342 | ||
|
|
52441dd754 | ||
|
|
38dd1c342a | ||
|
|
0f89db3b46 | ||
|
|
120afb30c1 | ||
|
|
47bc573de5 | ||
|
|
a6272fcf76 | ||
|
|
b8f0e565f5 | ||
|
|
83c9753507 | ||
|
|
91e0733e8e | ||
|
|
dd97d84c19 | ||
|
|
b2a4075e12 | ||
|
|
96e668a5b9 | ||
|
|
c9f4184126 | ||
|
|
6f1209ea49 | ||
|
|
89f0ecf25d | ||
|
|
eca70d81c8 | ||
|
|
639966622f | ||
|
|
be7e249630 | ||
|
|
d1493e6b70 | ||
|
|
fb059bfdc3 | ||
|
|
a3c45d47e6 | ||
|
|
6db2561eda | ||
|
|
ba2d0fae0e | ||
|
|
7f9e91f1c7 | ||
|
|
2312302dea | ||
|
|
dfede52048 | ||
|
|
a87d12f167 | ||
|
|
ec18c3770b | ||
|
|
3e0ea9727f | ||
|
|
e64378f94f | ||
|
|
888a7aa6b2 | ||
|
|
9cf2f424ad | ||
|
|
a1b35fb7d1 | ||
|
|
982b596fa4 | ||
|
|
1ce8168d72 | ||
|
|
93ce2728b7 | ||
|
|
0364bf4913 | ||
|
|
48813c55d5 | ||
|
|
a9a35ccb6b | ||
|
|
4d5c20ce17 | ||
|
|
ced84a2b01 | ||
|
|
6a0055f69f | ||
|
|
07b299abd2 | ||
|
|
ae563e2b1c | ||
|
|
1ceca4ae19 | ||
|
|
fa611b3616 | ||
|
|
bc0d4f28ef | ||
|
|
369a29ac90 | ||
|
|
b88a735e54 | ||
|
|
dca4de80fd | ||
|
|
bead3e6095 | ||
|
|
1436b075bf | ||
|
|
9831b358f8 | ||
|
|
7b11e634aa | ||
|
|
dce5c7e249 | ||
|
|
7f60ab49b2 | ||
|
|
d1d3dcf1a0 | ||
|
|
ce87a0c1d3 | ||
|
|
75067524ae | ||
|
|
1cd779459b | ||
|
|
e2eb0b2eac | ||
|
|
709bcedbed | ||
|
|
444e938e2d | ||
|
|
9820baf82e | ||
|
|
7f2c7cacd3 | ||
|
|
62a911a57e | ||
|
|
fcd34e41ca | ||
|
|
ba8a5ac82b | ||
|
|
e5a6c0a94d | ||
|
|
a9c8d4a216 | ||
|
|
6c7da13cd3 | ||
|
|
2ba23ebb13 | ||
|
|
74d69bdedc | ||
|
|
8a074dedb6 | ||
|
|
3dd4bf9955 | ||
|
|
2e2254371a | ||
|
|
693f7366a2 | ||
|
|
b673c804be | ||
|
|
03a1086ba3 | ||
|
|
e8a2ad4315 | ||
|
|
c9cbd2f4f6 | ||
|
|
90a99fc221 | ||
|
|
a649c3b72e | ||
|
|
caec5d81eb | ||
|
|
e4ec976a1f | ||
|
|
13768fdb9b | ||
|
|
46e4bd5fe0 | ||
|
|
95683c6239 | ||
|
|
db9ea66069 | ||
|
|
ef02464e3c | ||
|
|
d29bd4b054 | ||
|
|
17b7042a25 | ||
|
|
75afb37987 | ||
|
|
528a66fc97 | ||
|
|
b245311a7e | ||
|
|
4b2ef39648 | ||
|
|
286c3eafe3 | ||
|
|
3bb6c667db | ||
|
|
b530d1d449 | ||
|
|
fdbb5b67a8 | ||
|
|
67f09fb1d6 | ||
|
|
1a5dd5c87c | ||
|
|
c2a189ab18 | ||
|
|
56219f9f61 | ||
|
|
c38e7ee3e3 | ||
|
|
5e490ed8b7 | ||
|
|
9f9b1d3ce6 | ||
|
|
35ed9b9b72 | ||
|
|
c2830c4a98 | ||
|
|
3b9b03cf86 | ||
|
|
ef39c1e94b | ||
|
|
4ab2d46113 | ||
|
|
1e53528363 | ||
|
|
b46a8344d3 | ||
|
|
5d8334d7f4 | ||
|
|
c9a6e0155b | ||
|
|
7a9fab8f57 | ||
|
|
4bcc1f5adb | ||
|
|
3629468d47 | ||
|
|
d7f65ca125 | ||
|
|
c5d6f58988 | ||
|
|
a7a3ce7245 | ||
|
|
6cb527a937 | ||
|
|
007ba2bee4 | ||
|
|
2ce6d47519 | ||
|
|
f2bfdfdedd | ||
|
|
9d49faca61 | ||
|
|
bb85e139f1 | ||
|
|
c87d025902 | ||
|
|
c37b8f7f9d | ||
|
|
1ee5dba9b3 | ||
|
|
e8be8139cb | ||
|
|
fcc92299eb | ||
|
|
0c23cd62db | ||
|
|
04472bd730 | ||
|
|
c1f1d4e2ce | ||
|
|
e91a4bebed | ||
|
|
3d811a17fe | ||
|
|
f3ec818a66 | ||
|
|
a270ca5101 | ||
|
|
493aa9f20d | ||
|
|
6ff462abf3 | ||
|
|
4103344e48 | ||
|
|
193705a08a | ||
|
|
b59230067f | ||
|
|
7b7fa5f77b | ||
|
|
27b4c17f06 | ||
|
|
6491e30a80 | ||
|
|
4d478a3306 | ||
|
|
90dfa2ccaf | ||
|
|
c968d11943 | ||
|
|
e0918816fb | ||
|
|
66e84b68fc | ||
|
|
3d18f1447e | ||
|
|
d4ab74b25e | ||
|
|
d2cc7df7db | ||
|
|
231b70b987 | ||
|
|
1798ebd395 | ||
|
|
b1f4ea6206 | ||
|
|
350627988e | ||
|
|
87248c9f47 | ||
|
|
3fe616b8fe | ||
|
|
a12b2c8d33 | ||
|
|
468fb3c77a | ||
|
|
3a4bd27333 | ||
|
|
ac9974fd64 | ||
|
|
1e1b51bc1c | ||
|
|
127772e1b4 | ||
|
|
3ad3d3037f | ||
|
|
9c5f2de4ec | ||
|
|
59772ef772 | ||
|
|
96260ba26d | ||
|
|
ca2e2f5f45 | ||
|
|
92f3d863fa | ||
|
|
5970df0606 | ||
|
|
e1819a874f | ||
|
|
0c665e11f1 | ||
|
|
827d4c5fb0 | ||
|
|
e46fcc2893 | ||
|
|
ae8129f1fd | ||
|
|
6eed7eb540 | ||
|
|
7c86f11167 | ||
|
|
dc34bf18bb | ||
|
|
6bde70d60a | ||
|
|
b8370cffb9 | ||
|
|
b863447c2b | ||
|
|
7403f9f870 | ||
|
|
5252211c92 | ||
|
|
1d63654662 | ||
|
|
f83fc2e35c | ||
|
|
6cf17c7bcc | ||
|
|
19d7cfd66b | ||
|
|
a89772652d | ||
|
|
95485a0da2 | ||
|
|
f67acc82cf | ||
|
|
e2f1ce7758 | ||
|
|
4744e50244 | ||
|
|
61f105da6f | ||
|
|
273ab304b9 | ||
|
|
1d3af68f29 | ||
|
|
2a2a4b96c7 | ||
|
|
b630a01131 | ||
|
|
e70dbec6b9 | ||
|
|
f25189fc74 | ||
|
|
00fc66d8e8 | ||
|
|
97f17374f2 | ||
|
|
f16b19faf3 | ||
|
|
4ce16e9e91 | ||
|
|
be4bbd7b9b | ||
|
|
bae28965ab | ||
|
|
9daa97f279 | ||
|
|
4094c47e29 | ||
|
|
63efbdffe6 | ||
|
|
a7af6d8a3c | ||
|
|
ee1fe95ee5 | ||
|
|
f79c619065 | ||
|
|
028935a318 | ||
|
|
62353191e8 | ||
|
|
cbffd32d8e | ||
|
|
0394a3e939 | ||
|
|
8e400e9e40 | ||
|
|
66a53c6d3c | ||
|
|
f111c5c325 | ||
|
|
c4a9b61da6 | ||
|
|
a65ebbb319 | ||
|
|
bc78cf8a87 | ||
|
|
23823811e9 | ||
|
|
2bcc41c851 | ||
|
|
dce03a36d0 | ||
|
|
b24b3d21e1 | ||
|
|
556e507f68 | ||
|
|
29bf6e5d32 | ||
|
|
0927af40c3 | ||
|
|
c434d98365 | ||
|
|
0979f11cc3 | ||
|
|
68bdd26426 | ||
|
|
342c4384e4 | ||
|
|
73a41b16be | ||
|
|
e00062ea8f | ||
|
|
ca44ce5f8c | ||
|
|
812ac259e2 | ||
|
|
b8da386e55 | ||
|
|
3c0358c9cf | ||
|
|
c9aca2a13d | ||
|
|
ed9362a98c | ||
|
|
6b86d834a9 | ||
|
|
a2c5e30011 | ||
|
|
e06647b54e | ||
|
|
0f7d36cfa0 | ||
|
|
9e27559bdb | ||
|
|
0a21ffbfec | ||
|
|
542e487b69 | ||
|
|
bfc6d95a7e | ||
|
|
65a26958f7 | ||
|
|
2dfb4d0c17 | ||
|
|
368ad332a0 | ||
|
|
bde32eb7df | ||
|
|
dc64556902 | ||
|
|
0315077daf | ||
|
|
7237bacec0 | ||
|
|
9bf8e89192 | ||
|
|
5fa6b07e1b | ||
|
|
6668fe02aa | ||
|
|
82d09c288d | ||
|
|
8029f56d1c | ||
|
|
0a6916e1b9 | ||
|
|
e419a034b7 | ||
|
|
cafa5217ed | ||
|
|
bc16a1bcc4 | ||
|
|
f5737a6354 | ||
|
|
2865ad5281 | ||
|
|
33d75ad7b0 | ||
|
|
1a3222d357 | ||
|
|
5a17f86f1a | ||
|
|
c989a94916 | ||
|
|
8b57add891 | ||
|
|
5833bb3bd4 | ||
|
|
d17abedc7d | ||
|
|
b407074281 | ||
|
|
c4d6189b55 | ||
|
|
07706b41f4 | ||
|
|
346a48d4c2 | ||
|
|
77db84b4c8 | ||
|
|
b90b9bb472 | ||
|
|
d019187895 | ||
|
|
b3963456c0 | ||
|
|
bccf371aa9 | ||
|
|
641e9ff508 | ||
|
|
abb045e1ff | ||
|
|
ae97afd806 | ||
|
|
c09ee7d714 | ||
|
|
4047e871e5 | ||
|
|
4c1701ca77 | ||
|
|
8ba5cbc2b9 | ||
|
|
fbf13dde21 | ||
|
|
bdd713413a | ||
|
|
e896592261 | ||
|
|
d9312dbefb | ||
|
|
5cb638bd41 | ||
|
|
df23ef36c7 | ||
|
|
e1ffacbe32 | ||
|
|
6d9fe04aa8 | ||
|
|
16e48a859c | ||
|
|
6346c00527 | ||
|
|
3f6fe4f2be | ||
|
|
bb7680dc51 | ||
|
|
161572b292 | ||
|
|
3b3da24823 | ||
|
|
1f91c2fe12 | ||
|
|
b98fbcce0c | ||
|
|
b12d4c03cb | ||
|
|
bd4bdab81c | ||
|
|
792527d456 | ||
|
|
1a103662e9 | ||
|
|
25ea754502 | ||
|
|
3152d039a5 | ||
|
|
a33a5771ed | ||
|
|
5bedf3618d | ||
|
|
153cd0a205 | ||
|
|
f5f1b9602a | ||
|
|
7347b72010 | ||
|
|
5aeb8305fc | ||
|
|
53c950b235 | ||
|
|
8e6ff32c97 | ||
|
|
23acd2738b | ||
|
|
6bcc039e01 | ||
|
|
e776e79c1e | ||
|
|
e2660eaad3 | ||
|
|
5b6e731f37 | ||
|
|
ce0ba8edbd | ||
|
|
ec97464007 | ||
|
|
1ff6e4db9d | ||
|
|
59aae20aea | ||
|
|
97f9dedaa6 | ||
|
|
7f730b81ff | ||
|
|
e793fc9973 | ||
|
|
73876e5774 | ||
|
|
97e70d62bf | ||
|
|
47a356ff52 | ||
|
|
4e6a9fb202 | ||
|
|
141b8495e2 | ||
|
|
de503bf5c4 | ||
|
|
c94fbe5eeb | ||
|
|
523f7652f2 | ||
|
|
6c5795b519 | ||
|
|
6552ccc477 | ||
|
|
adb9f31803 | ||
|
|
d7f655dfc5 | ||
|
|
83a4999dbe | ||
|
|
abf1d7da23 | ||
|
|
dfaf116449 | ||
|
|
41362e2b6e | ||
|
|
731b6ebfa7 | ||
|
|
3f838e1dbc | ||
|
|
c845eed114 | ||
|
|
5b09829959 | ||
|
|
2e5a993f88 | ||
|
|
1fe1194ef4 | ||
|
|
19d0919451 | ||
|
|
afffbb6487 | ||
|
|
4964a1519b | ||
|
|
53e4b55ea3 | ||
|
|
9b3c00e0b6 | ||
|
|
7b31e5918e | ||
|
|
50a8ba8c18 | ||
|
|
b32bce9be2 | ||
|
|
8c87f32b38 | ||
|
|
0cf6c6c132 | ||
|
|
d757dd4e17 | ||
|
|
175ae58563 | ||
|
|
f32f7d2308 | ||
|
|
36acd34874 | ||
|
|
3ed6d82367 | ||
|
|
793047919d | ||
|
|
6a786342f9 | ||
|
|
d184b3fa86 | ||
|
|
91e97468a0 | ||
|
|
4a9317db6e | ||
|
|
b66aeea384 | ||
|
|
90f3cc7328 | ||
|
|
f9b732482d | ||
|
|
924f796eb8 | ||
|
|
2528f35f00 | ||
|
|
683a09781a | ||
|
|
d8774cda8e | ||
|
|
1ce4eda0b9 | ||
|
|
5bcb373c00 | ||
|
|
678239424a | ||
|
|
369dc295b1 | ||
|
|
7470b1180e | ||
|
|
99a4bb63c7 | ||
|
|
713a34c68e | ||
|
|
165a6d34b2 | ||
|
|
d96ab7c867 | ||
|
|
7de4f1d96f | ||
|
|
68fd1c28b0 | ||
|
|
e7a4aeca6f | ||
|
|
86002a2f7b | ||
|
|
08a4bbb7d0 | ||
|
|
ae4cf98458 | ||
|
|
1596391a2e | ||
|
|
0ff24b6f21 | ||
|
|
6cf8ca5e43 | ||
|
|
4bb6b5a547 | ||
|
|
f14ef10e48 | ||
|
|
f76046b612 | ||
|
|
69e1f6e4ba | ||
|
|
2fce010f30 | ||
|
|
5ba8749a38 | ||
|
|
5c5d45f52b | ||
|
|
a6d47ca772 | ||
|
|
11b4d98f37 | ||
|
|
6e016c439c | ||
|
|
d1af4a5582 | ||
|
|
9b5e6a1f7a | ||
|
|
060982adb4 | ||
|
|
bc95b2fc77 | ||
|
|
f926915e56 | ||
|
|
69123590fb | ||
|
|
66a35e973c | ||
|
|
9d1443bbfe | ||
|
|
f4f3769225 | ||
|
|
38543ad202 | ||
|
|
dda2ea8fed | ||
|
|
2293f9dad6 | ||
|
|
abb3341030 | ||
|
|
81e51dcafd | ||
|
|
e84e2c7258 | ||
|
|
d9b46587fe | ||
|
|
36322acb6d | ||
|
|
12b39feba3 | ||
|
|
16281c626b | ||
|
|
d24e867603 | ||
|
|
d5c14a513d | ||
|
|
f9b836027d | ||
|
|
3147b7c62b | ||
|
|
0ceb75ea09 | ||
|
|
3cb138ea41 | ||
|
|
9016ba0d61 | ||
|
|
3b6248cb64 | ||
|
|
5a71984b38 | ||
|
|
1274889931 | ||
|
|
ed7e715812 | ||
|
|
4d12af8396 | ||
|
|
6f45fb6e14 | ||
|
|
9de15616a5 | ||
|
|
5c0ef950cc | ||
|
|
0b0e0f8f43 | ||
|
|
a444c860a4 | ||
|
|
20db8bbe2e | ||
|
|
154923ca7d | ||
|
|
a34d636366 | ||
|
|
89ad259050 | ||
|
|
db1ae80877 | ||
|
|
7aa712a481 | ||
|
|
748c894450 | ||
|
|
0e8b13841a | ||
|
|
d284b8e0a0 | ||
|
|
4ce1cccc4a | ||
|
|
91c803ff65 | ||
|
|
7a17ee9f8c | ||
|
|
1ad8f20bce | ||
|
|
de421d02ef | ||
|
|
da390ff573 | ||
|
|
14cfa90d63 | ||
|
|
90a97ae35f | ||
|
|
501bd814c3 | ||
|
|
0f5a166cce | ||
|
|
d59f450819 | ||
|
|
e0a702df76 | ||
|
|
e990a35a91 | ||
|
|
3e286f4f19 | ||
|
|
e0a83b4b94 | ||
|
|
b9728a96ce | ||
|
|
537510f081 | ||
|
|
dc411ca889 | ||
|
|
9055d0910c | ||
|
|
1985502894 | ||
|
|
c3e3c32bdc | ||
|
|
f5ad1dfbc5 | ||
|
|
9eab9512a3 | ||
|
|
078db2dd80 | ||
|
|
a3796f9baa | ||
|
|
bdc279a49b | ||
|
|
544330345b | ||
|
|
4bf1d0373d | ||
|
|
192df273cc | ||
|
|
cf5c803fe0 | ||
|
|
3c302bae5a | ||
|
|
103cd2b7a1 | ||
|
|
7763643f2e | ||
|
|
61d2bed019 | ||
|
|
52cbbed6a0 | ||
|
|
4b624ab5da | ||
|
|
640d15dba5 | ||
|
|
69509f2a2a | ||
|
|
da5b9d5c74 | ||
|
|
af11525338 | ||
|
|
98b71bc63a | ||
|
|
271244bb36 | ||
|
|
ebef7d6348 | ||
|
|
20497f1be3 | ||
|
|
74947d1c1c | ||
|
|
db3d230ad9 | ||
|
|
fabf278633 | ||
|
|
743cfa13fd | ||
|
|
127ed1b188 | ||
|
|
b80674bf2e | ||
|
|
f74f7d543e | ||
|
|
72caf2ef9d | ||
|
|
5ef05d3a63 | ||
|
|
26aaa62048 | ||
|
|
c427fe94da | ||
|
|
7cd7837e08 | ||
|
|
66f7437965 | ||
|
|
cb32640f70 | ||
|
|
66c07a8b33 | ||
|
|
b326ab78b3 | ||
|
|
8811ca9e9e | ||
|
|
471d88c1d2 | ||
|
|
4a738024cc | ||
|
|
8ac32cf4d6 | ||
|
|
b541351a0a | ||
|
|
92f5a2b6a6 | ||
|
|
ae092efb49 | ||
|
|
94065fde33 | ||
|
|
aab7bc5282 | ||
|
|
9e2ccbd2a7 | ||
|
|
6a6494d947 | ||
|
|
cb9e944de1 | ||
|
|
1f92c594c8 | ||
|
|
f91031bd65 | ||
|
|
5d3e04216d | ||
|
|
055d55b71b | ||
|
|
ca948d66a9 | ||
|
|
fa8cb40af0 | ||
|
|
b13fb1cca9 | ||
|
|
01b8ed97ed | ||
|
|
863ee9e6dd | ||
|
|
4ebd604ca9 | ||
|
|
581ef6e18d | ||
|
|
321a32050b | ||
|
|
db6a207afe | ||
|
|
9b42bc860d | ||
|
|
6174aa01e0 | ||
|
|
fb7692cf9c | ||
|
|
9279840860 | ||
|
|
9c05f37c0f | ||
|
|
b5c72611b4 | ||
|
|
2b3b5d2c8a | ||
|
|
d46fe20986 | ||
|
|
9e46409517 | ||
|
|
d42da529ec | ||
|
|
c1c96e01fa | ||
|
|
aee2742951 | ||
|
|
c3af36d33b | ||
|
|
3885aa1e8c | ||
|
|
33b1c57092 | ||
|
|
441d3bf1ed | ||
|
|
bd83936e5d | ||
|
|
88a68b941f | ||
|
|
084b41fc2c | ||
|
|
7b713e2576 | ||
|
|
25982f0475 | ||
|
|
2d2ac98b3d | ||
|
|
f1fc201862 | ||
|
|
681f45943b | ||
|
|
5dc8c54b8d | ||
|
|
20194bed42 | ||
|
|
06bbf494bb | ||
|
|
21b919a76b | ||
|
|
39f0707201 | ||
|
|
8d52a278a9 | ||
|
|
5fbba27d17 | ||
|
|
5c891bcfb5 | ||
|
|
547c700764 | ||
|
|
d30892ea60 | ||
|
|
0b5d550780 | ||
|
|
ac5ad0b9ce | ||
|
|
823c0ebb47 | ||
|
|
8fc87411fa | ||
|
|
5fb173149a | ||
|
|
02cf7274d2 | ||
|
|
43de0e7f16 | ||
|
|
f84530c285 | ||
|
|
6bf92979a2 | ||
|
|
c5dcac4dbb | ||
|
|
bb1b6c906d | ||
|
|
aa9fef7778 | ||
|
|
351f21c89f | ||
|
|
ca97130a29 | ||
|
|
9fea44cbc3 | ||
|
|
5e761a1068 | ||
|
|
afff751ff1 | ||
|
|
222186d5f7 | ||
|
|
632ad7d7f9 | ||
|
|
331412ddff | ||
|
|
04ac04e0ad | ||
|
|
29340152b6 | ||
|
|
8a34f7ca7b | ||
|
|
e2e3b81f32 | ||
|
|
b4b5eb5bab | ||
|
|
edde785219 | ||
|
|
b71e148cea | ||
|
|
0d939b5ab0 | ||
|
|
b983cf8b5f | ||
|
|
81f3a5cf94 | ||
|
|
3726b546d5 | ||
|
|
2702b82bc3 | ||
|
|
aee4f8d2fe | ||
|
|
c79c1b3913 | ||
|
|
3da72c1ff1 | ||
|
|
b926a4c67e | ||
|
|
29320f8aad | ||
|
|
2a59f45a3b | ||
|
|
2db7b2d948 | ||
|
|
d55fcd055d | ||
|
|
9e3032e919 | ||
|
|
c2e2994403 | ||
|
|
b92e3ca3ee | ||
|
|
2abea94f8e | ||
|
|
fcc648ecfd | ||
|
|
2e1046220a | ||
|
|
745515b11f | ||
|
|
17091bd38c | ||
|
|
437aa168d1 | ||
|
|
f31ef3420d | ||
|
|
b37184ae57 | ||
|
|
716a83d1f7 | ||
|
|
6c7972470b | ||
|
|
40ce6724a9 | ||
|
|
e46e3027fa | ||
|
|
5ea46444e9 | ||
|
|
47bfb681c0 | ||
|
|
3f7f5f9429 | ||
|
|
5d9cf6a6d7 | ||
|
|
47db3452f4 | ||
|
|
40e03a05be | ||
|
|
bd70e6ae6d | ||
|
|
b9eb74a705 | ||
|
|
daaefed61b | ||
|
|
7b41839ea8 | ||
|
|
6532972e61 | ||
|
|
48026efddf | ||
|
|
e314510005 | ||
|
|
facc6ee6b3 | ||
|
|
9a2f86e9ad | ||
|
|
513b8959f5 | ||
|
|
8a00b62cba | ||
|
|
9bb847bb07 | ||
|
|
40bfce463d | ||
|
|
fc7d29edd3 | ||
|
|
4f7d14dfb2 | ||
|
|
cfc61a69ef | ||
|
|
745ac240d7 | ||
|
|
73d67bb16a | ||
|
|
ae62d30811 | ||
|
|
f59a0192b4 | ||
|
|
f56b4773cb | ||
|
|
1a4a8f1ef7 | ||
|
|
03aacc35b3 | ||
|
|
d5cd6f9a51 | ||
|
|
6706bed676 | ||
|
|
c4debca11d | ||
|
|
c6eecb06d5 | ||
|
|
896b46d18e | ||
|
|
78c63c480a | ||
|
|
b2cc2e6765 | ||
|
|
af13e5fa4a | ||
|
|
8eac8132e3 | ||
|
|
50f579d301 | ||
|
|
02c72e59fa | ||
|
|
e7233c0c94 | ||
|
|
2bdf135cbc | ||
|
|
134b9fc466 | ||
|
|
10863a5949 | ||
|
|
bf02e04283 | ||
|
|
48f70e55aa | ||
|
|
3250d75320 | ||
|
|
87ee48bd84 | ||
|
|
24f9bb41df | ||
|
|
d0e9b4ce9f | ||
|
|
50c5f8c389 | ||
|
|
55c67c7870 | ||
|
|
26ea11c44f | ||
|
|
de1825e54b | ||
|
|
e259503933 | ||
|
|
4e07b4c0e8 | ||
|
|
ce6e81c682 | ||
|
|
c44acb3575 | ||
|
|
bad5057a74 | ||
|
|
fe7b7773ba | ||
|
|
cef1aa6d1b | ||
|
|
5b10db6f91 | ||
|
|
76c2de38ff | ||
|
|
816802774d | ||
|
|
b7559c1df6 | ||
|
|
bbf3d960b2 | ||
|
|
e1df151d9b | ||
|
|
a2ccfc1e50 |
23
.gitignore
vendored
23
.gitignore
vendored
@@ -19,14 +19,16 @@
|
|||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
|
||||||
|
|
||||||
## Ignore RedMatrix site specific files and folders
|
## Ignore site specific files and folders
|
||||||
.htconfig.php
|
.htconfig.php
|
||||||
favicon.*
|
favicon.*
|
||||||
addon/
|
addon/
|
||||||
|
widget/
|
||||||
custom/
|
custom/
|
||||||
/store/
|
/store/
|
||||||
# site apps
|
# site apps
|
||||||
apps/
|
apps/
|
||||||
|
!doc/context/*/apps
|
||||||
# default startpage
|
# default startpage
|
||||||
home.html
|
home.html
|
||||||
# page header plugin
|
# page header plugin
|
||||||
@@ -44,7 +46,8 @@ doc/html/
|
|||||||
.zotshrc
|
.zotshrc
|
||||||
# external repositories for themes/addons
|
# external repositories for themes/addons
|
||||||
extend/
|
extend/
|
||||||
|
# files generated by phpunit
|
||||||
|
tests/results/
|
||||||
|
|
||||||
## exclude IDE files
|
## exclude IDE files
|
||||||
# config files and folders from Eclipse
|
# config files and folders from Eclipse
|
||||||
@@ -60,11 +63,15 @@ nbproject/
|
|||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
|
|
||||||
# composer files (at the moment composer is not officially supported and only used to add SabreDAV, we should add these)
|
## composer
|
||||||
composer.*
|
# locally installed composer binary
|
||||||
|
composer.phar
|
||||||
# When we include composer we should exclude vendor/
|
# allow composer.lock, as it is required to have a common state
|
||||||
|
!composer.lock
|
||||||
|
# vendor/ is managed by composer, no need to include in our repository
|
||||||
|
# requires new deployment and needs discussion first
|
||||||
#vendor/
|
#vendor/
|
||||||
# Exclude at least some vendor test files, examples, etc.
|
# Exclude at least some vendor test files, examples, etc. so far
|
||||||
vendor/sabre/*/tests/
|
vendor/**/tests/
|
||||||
|
vendor/**/Test/
|
||||||
vendor/sabre/*/examples/
|
vendor/sabre/*/examples/
|
||||||
|
|||||||
@@ -2,10 +2,19 @@
|
|||||||
|
|
||||||
Run hubzilla-setup.sh for an unattended installation of hubzilla.
|
Run hubzilla-setup.sh for an unattended installation of hubzilla.
|
||||||
|
|
||||||
The script is known to work with Debian 8.3 stable (Jessie)
|
The script is known to work without adjustments with
|
||||||
|
|
||||||
+ Home-PC (Debian-8.3.0-amd64)
|
+ Hardware
|
||||||
+ DigitalOcean droplet (Debian 8.3 x64 / 512 MB Memory / 20 GB Disk / NYC3)
|
- Mini-PC with Debian-9.2-amd64, or
|
||||||
|
- Rapberry 3 with Raspbian, Debian-9.3
|
||||||
|
+ DynDNS
|
||||||
|
- selfHOST.de
|
||||||
|
- freedns.afraid.org
|
||||||
|
|
||||||
|
## Disclaimers
|
||||||
|
|
||||||
|
- This script does work with Debian 9 only.
|
||||||
|
- This script has to be used on a fresh debian install only (it does not take account for a possibly already installed and configured webserver or sql implementation).
|
||||||
|
|
||||||
# Step-by-Step Overwiew
|
# Step-by-Step Overwiew
|
||||||
|
|
||||||
@@ -14,13 +23,13 @@ The script is known to work with Debian 8.3 stable (Jessie)
|
|||||||
Hardware
|
Hardware
|
||||||
|
|
||||||
+ Internet connection and router at home
|
+ Internet connection and router at home
|
||||||
+ Mini-pc connected to your router
|
+ Mini-pc connected to your router (a Raspberry 3 will do for very small Hubs)
|
||||||
+ USB drive for backups
|
+ USB drive for backups
|
||||||
|
|
||||||
Software
|
Software
|
||||||
|
|
||||||
+ Fresh installation of Debian on your mini-pc
|
+ Fresh installation of Debian 9 (Stretch)
|
||||||
+ Router with open ports 80 and 443 for your Debian
|
+ Router with open ports 80 and 443 for your Hub
|
||||||
|
|
||||||
## The basic steps (quick overview)
|
## The basic steps (quick overview)
|
||||||
|
|
||||||
@@ -30,9 +39,12 @@ Software
|
|||||||
- mkdir -p /var/www
|
- mkdir -p /var/www
|
||||||
- cd /var/www
|
- cd /var/www
|
||||||
- git clone https://github.com/redmatrix/hubzilla.git html
|
- git clone https://github.com/redmatrix/hubzilla.git html
|
||||||
- cp .homeinstall/hubzilla-config.txt.template .homeinstall/hubzilla-config.txt
|
- cd /html/.homeinstall
|
||||||
- nano .homeinstall/hubzilla-config.txt
|
- cp hubzilla-config.txt.template hubzilla-config.txt
|
||||||
- Enter your values there: db pass, domain, values for dyn DNS
|
- nano hubzilla-config.txt
|
||||||
|
- Read the comments carefully
|
||||||
|
- Enter your values: db pass, domain, values for dyn DNS
|
||||||
|
- Make sure your your external drive (for backups) is mounted
|
||||||
- hubzilla-setup.sh as root
|
- hubzilla-setup.sh as root
|
||||||
- ... wait, wait, wait until the script is finised
|
- ... wait, wait, wait until the script is finised
|
||||||
- reboot
|
- reboot
|
||||||
@@ -46,23 +58,44 @@ Software
|
|||||||
|
|
||||||
### Recommended: USB Drive for Backups
|
### Recommended: USB Drive for Backups
|
||||||
|
|
||||||
The installation will create a daily backup.
|
The installation will create a daily backup written to an external drive.
|
||||||
|
|
||||||
If the backup process does not find an external device than the backup goes to
|
The USB drive must be compatible with the filesystems
|
||||||
the internal disk.
|
|
||||||
|
|
||||||
The USB drive must be compatible with an encrpyted filesystem LUKS + ext4.
|
- ext4 (if you do not want to encrypt the USB)
|
||||||
|
- LUKS + ext4 (if you want to encrypt the USB)
|
||||||
|
|
||||||
|
The backup includes
|
||||||
|
|
||||||
|
- Hubzilla DB
|
||||||
|
- Hubzilla installation /var/www/html
|
||||||
|
- Certificates for letsencrypt
|
||||||
|
|
||||||
## Preparations Software
|
## Preparations Software
|
||||||
|
|
||||||
### Install Debian Linux on the Mini-PC
|
### Install Debian Linux on the Mini-PC
|
||||||
|
|
||||||
Download the stable Debian at https://www.debian.org/
|
Download the stable Debian at https://www.debian.org/
|
||||||
|
(Debian 8 is no longer supported.)
|
||||||
|
|
||||||
Create bootable USB drive with Debian on it. You could use the programm
|
Create bootable USB drive with Debian on it.You could use
|
||||||
unetbootin, https://en.wikipedia.org/wiki/UNetbootin
|
|
||||||
|
|
||||||
Switch of your mini pc, plug in your USB drive and start the mini pc from the
|
- unetbootin, https://en.wikipedia.org/wiki/UNetbootin
|
||||||
|
- or simply the linux command "dd"
|
||||||
|
|
||||||
|
Example for command dd...
|
||||||
|
|
||||||
|
su -
|
||||||
|
dd if=2017-11-29-raspbian-stretch.img of=/dev/mmcblk0
|
||||||
|
|
||||||
|
Do not forget to unmount the SD card before and check if unmounted like in this example...
|
||||||
|
|
||||||
|
su -
|
||||||
|
umount /dev/mmcblk0*
|
||||||
|
df -h
|
||||||
|
|
||||||
|
|
||||||
|
Switch off your mini pc, plug in your USB drive and start the mini pc from the
|
||||||
stick. Install Debian. Follow the instructions of the installation.
|
stick. Install Debian. Follow the instructions of the installation.
|
||||||
|
|
||||||
### Configure your Router
|
### Configure your Router
|
||||||
@@ -79,28 +112,20 @@ You can use subdomains as well
|
|||||||
|
|
||||||
my.cooldomain.org
|
my.cooldomain.org
|
||||||
|
|
||||||
There are two way to get a domain
|
There are two ways to get a domain...
|
||||||
|
|
||||||
- buy a domain (recommended) or
|
### Method 1: Buy a Domain
|
||||||
- register a free subdomain
|
|
||||||
|
|
||||||
### Method 1: Get yourself an own Domain (recommended)
|
...for example buy at selfHOST.de
|
||||||
|
|
||||||
...for example at selfHOST.de
|
The cost are around 10,- € once and 1,50 € per month (2017).
|
||||||
|
|
||||||
### Method 2 Register a (free) Subdomain
|
The cost are around 10,- € once and 1,50 € per month (2017).
|
||||||
|
|
||||||
Register a free subdomain for example at
|
...for example register at freedns.afraid.org
|
||||||
|
|
||||||
- freeDNS
|
Follow the instructions in .homeinstall/hubzilla-config.txt.
|
||||||
- selfHOST
|
|
||||||
|
|
||||||
WATCH THIS: A free subdomain is not the prefered way to get a domain name. Why?
|
|
||||||
|
|
||||||
Let's encrpyt issues a limited number of certificates each
|
|
||||||
day. Possibly other users of this domain will try to issue a certificate
|
|
||||||
at the same day as you do. So make sure you choose a domain with as less subdomains as
|
|
||||||
possible.
|
|
||||||
|
|
||||||
## Install Hubzilla on your Debian
|
## Install Hubzilla on your Debian
|
||||||
|
|
||||||
@@ -135,10 +160,12 @@ Copy the template file
|
|||||||
|
|
||||||
cp hubzilla-config.txt.template hubzilla-config.txt
|
cp hubzilla-config.txt.template hubzilla-config.txt
|
||||||
|
|
||||||
Change the file "hubzilla-config.txt". Read the instructions there and enter your values.
|
Modify the file "hubzilla-config.txt". Read the instructions there carefully and enter your values.
|
||||||
|
|
||||||
nano hubzilla-config.txt
|
nano hubzilla-config.txt
|
||||||
|
|
||||||
|
Make sure your external drive (for backups) is plugged in and can be mounted as configured in "hubzilla-config.txt". Otherwise the daily backups will not work.
|
||||||
|
|
||||||
Run the script
|
Run the script
|
||||||
|
|
||||||
./hubzilla-setup.sh
|
./hubzilla-setup.sh
|
||||||
@@ -146,7 +173,7 @@ Run the script
|
|||||||
Wait... The script should not finish with an error message.
|
Wait... The script should not finish with an error message.
|
||||||
|
|
||||||
In a webbrowser open your domain.
|
In a webbrowser open your domain.
|
||||||
Expected: A test page of hubzilla is shown. All checks there shoulg be
|
Expected: A test page of hubzilla is shown. All checks there should be
|
||||||
successfull. Go on...
|
successfull. Go on...
|
||||||
Expected: A page for the Hubzilla server configuration shows up.
|
Expected: A page for the Hubzilla server configuration shows up.
|
||||||
|
|
||||||
@@ -162,3 +189,28 @@ Leave db type "MySQL" untouched.
|
|||||||
|
|
||||||
Follow the instructions in the next pages.
|
Follow the instructions in the next pages.
|
||||||
|
|
||||||
|
After the daily script was executed at 05:30 (am)
|
||||||
|
|
||||||
|
- look at var/www/html/hubzilla-daily.log
|
||||||
|
- check your backup on the external drive
|
||||||
|
- optionally view the daily log under yourdomain.org/admin/logs/
|
||||||
|
- set the logfile to var/www/html/hubzilla-daily.log
|
||||||
|
|
||||||
|
## Note for the Rasperry
|
||||||
|
|
||||||
|
The script was tested with an Raspberry 3 under Raspian (Debian 9.3, 2017-11-29-raspbian-stretch.img).
|
||||||
|
|
||||||
|
It is recommended to deinstall these programms to avoid endless updates. Use...
|
||||||
|
|
||||||
|
sudo apt-get purge wolfram-engine sonic-pi
|
||||||
|
sudo apt-get autoremove
|
||||||
|
|
||||||
|
It is recommended to run the Raspi without graphical frontend (X-Server). Use...
|
||||||
|
|
||||||
|
sudo raspi-config
|
||||||
|
|
||||||
|
to boot the Rapsi to the client console.
|
||||||
|
|
||||||
|
DO NOT FORGET TO CHANGE THE DEFAULT PASSWORD FOR USER PI!
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -70,15 +70,17 @@ selfhost_pass=
|
|||||||
# freedns_key=U1Z6aGt2R0NzMFNPNWRjbWxxZGpsd093OjE1Mzg5NDE5
|
# freedns_key=U1Z6aGt2R0NzMFNPNWRjbWxxZGpsd093OjE1Mzg5NDE5
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
#freedns_key=
|
freedns_key=
|
||||||
|
|
||||||
|
|
||||||
###############################################
|
###############################################
|
||||||
### OPTIONAL - Backup to external device ######
|
### OPTIONAL - Backup to external device ######
|
||||||
#
|
#
|
||||||
# The script can use an external device for the daily backup.
|
# The script can use an external device for the daily backup.
|
||||||
# The file system of the device (USB stick for example) must be compatible
|
# The file system of the device (USB stick for example) must be compatible with
|
||||||
# with encrypted LUKS + ext4
|
#
|
||||||
|
# - encrypted LUKS + ext4, or
|
||||||
|
# - ext4
|
||||||
#
|
#
|
||||||
# You should test to mount the device befor you run the script
|
# You should test to mount the device befor you run the script
|
||||||
# (hubzilla-setup.sh).
|
# (hubzilla-setup.sh).
|
||||||
@@ -113,27 +115,21 @@ selfhost_pass=
|
|||||||
# lsof /media/hubzilla_backup
|
# lsof /media/hubzilla_backup
|
||||||
#
|
#
|
||||||
# If you leave the following parameters
|
# If you leave the following parameters
|
||||||
|
#
|
||||||
# - "backup_device_name" and
|
# - "backup_device_name" and
|
||||||
# - "backup_device_pass"
|
# - "backup_device_pass"
|
||||||
|
#
|
||||||
# empty the script will create daily backups on the internal disk (which could
|
# empty the script will create daily backups on the internal disk (which could
|
||||||
# save you as well).
|
# save you as well).
|
||||||
#
|
#
|
||||||
# Example: backup_device_name=/dev/sdc1
|
# Example: backup_device_name=/dev/sdc1
|
||||||
#
|
#
|
||||||
|
# Leave "backup_device_pass=" empty if the external device is not encrypted.
|
||||||
|
#
|
||||||
backup_device_name=
|
backup_device_name=
|
||||||
backup_device_pass=
|
backup_device_pass=
|
||||||
|
|
||||||
|
|
||||||
###############################################
|
|
||||||
### OPTIONAL - Owncloud - deprecated ##########
|
|
||||||
#
|
|
||||||
# To install owncloud: owncloud=y
|
|
||||||
# Leave empty if you don't want to install owncloud
|
|
||||||
#
|
|
||||||
#owncloud=
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###############################################
|
###############################################
|
||||||
### OPTIONAL - do not mess with things below ##
|
### OPTIONAL - do not mess with things below ##
|
||||||
# (...if you are not certain)
|
# (...if you are not certain)
|
||||||
@@ -160,18 +156,3 @@ mysqlpass=$db_pass
|
|||||||
# Example: phpmyadminpass="aber hallo has blanks in it"
|
# Example: phpmyadminpass="aber hallo has blanks in it"
|
||||||
phpmyadminpass=$db_pass
|
phpmyadminpass=$db_pass
|
||||||
|
|
||||||
# TODO Prepare hubzilla for programmers
|
|
||||||
# - install eclipse and plugins
|
|
||||||
# - install xdebug to debug the php with eclipse
|
|
||||||
# - weaken permissions on /var/www/html
|
|
||||||
# - manual steps after this script
|
|
||||||
# * in eclipse: install plugins for php git hub
|
|
||||||
# * in eclipse: configure firefox (chrome,...) as browser to run with the php debuger
|
|
||||||
# * in eclipse: switch php debugger from zend to xdebug
|
|
||||||
# * in eclipse: add local hubzilla github repository
|
|
||||||
#
|
|
||||||
# Which user will use eclipse?
|
|
||||||
# Leave this empty if you do not want to prepare hubzilla for debugging
|
|
||||||
#
|
|
||||||
#developer_name=
|
|
||||||
|
|
||||||
|
|||||||
@@ -114,7 +114,11 @@ function check_sanity {
|
|||||||
fi
|
fi
|
||||||
if [ ! -f /etc/debian_version ]
|
if [ ! -f /etc/debian_version ]
|
||||||
then
|
then
|
||||||
die "Ubuntu is not supported"
|
die "Debian is supported only"
|
||||||
|
fi
|
||||||
|
if ! grep -q 'Linux 9' /etc/issue
|
||||||
|
then
|
||||||
|
die "Linux 9 (stretch) is supported only"x
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,11 +257,11 @@ function install_sendmail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function install_php {
|
function install_php {
|
||||||
# openssl and mbstring are included in libapache2-mod-php5
|
# openssl and mbstring are included in libapache2-mod-php
|
||||||
# to_to: php5-suhosin
|
|
||||||
print_info "installing php..."
|
print_info "installing php..."
|
||||||
nocheck_install "libapache2-mod-php5 php5 php-pear php5-xcache php5-curl php5-mcrypt php5-gd"
|
nocheck_install "libapache2-mod-php php php-pear php-curl php-mcrypt php-gd"
|
||||||
php5enmod mcrypt
|
sed -i "s/^upload_max_filesize =.*/upload_max_filesize = 100M/g" /etc/php/7.0/apache2/php.ini
|
||||||
|
sed -i "s/^post_max_size =.*/post_max_size = 100M/g" /etc/php/7.0/apache2/php.ini
|
||||||
}
|
}
|
||||||
|
|
||||||
function install_mysql {
|
function install_mysql {
|
||||||
@@ -277,18 +281,17 @@ function install_mysql {
|
|||||||
# want to be prompted for it then this can be arranged by preseeding the
|
# want to be prompted for it then this can be arranged by preseeding the
|
||||||
# DebConf database with the required information.
|
# DebConf database with the required information.
|
||||||
#
|
#
|
||||||
# echo mysql-server-5.5 mysql-server/root_password password xyzzy | debconf-set-selections
|
# echo mysql-server mysql-server/root_password password xyzzy | debconf-set-selections
|
||||||
# echo mysql-server-5.5 mysql-server/root_password_again password xyzzy | debconf-set-selections
|
# echo mysql-server mysql-server/root_password_again password xyzzy | debconf-set-selections
|
||||||
#
|
#
|
||||||
print_info "installing mysql..."
|
print_info "installing mysql..."
|
||||||
if [ -z "$mysqlpass" ]
|
if [ -z "$mysqlpass" ]
|
||||||
then
|
then
|
||||||
die "mysqlpass not set in $configfile"
|
die "mysqlpass not set in $configfile"
|
||||||
fi
|
fi
|
||||||
echo mysql-server-5.5 mysql-server/root_password password $mysqlpass | debconf-set-selections
|
echo mysql-server mysql-server/root_password password $mysqlpass | debconf-set-selections
|
||||||
echo mysql-server-5.5 mysql-server/root_password_again password $mysqlpass | debconf-set-selections
|
echo mysql-server mysql-server/root_password_again password $mysqlpass | debconf-set-selections
|
||||||
nocheck_install "php5-mysql mysql-server mysql-client"
|
nocheck_install "php-mysql mysql-server mysql-client"
|
||||||
php5enmod mcrypt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function install_phpmyadmin {
|
function install_phpmyadmin {
|
||||||
@@ -327,6 +330,7 @@ function install_phpmyadmin {
|
|||||||
echo "Include /etc/phpmyadmin/apache.conf" >> /etc/apache2/apache2.conf
|
echo "Include /etc/phpmyadmin/apache.conf" >> /etc/apache2/apache2.conf
|
||||||
fi
|
fi
|
||||||
service apache2 restart
|
service apache2 restart
|
||||||
|
/etc/init.d/mysql start
|
||||||
}
|
}
|
||||||
|
|
||||||
function create_hubzilla_db {
|
function create_hubzilla_db {
|
||||||
@@ -455,11 +459,6 @@ function configure_cron_selfhost {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function install_git {
|
|
||||||
print_info "installing git..."
|
|
||||||
nocheck_install "git"
|
|
||||||
}
|
|
||||||
|
|
||||||
function install_letsencrypt {
|
function install_letsencrypt {
|
||||||
print_info "installing let's encrypt ..."
|
print_info "installing let's encrypt ..."
|
||||||
# check if user gave domain
|
# check if user gave domain
|
||||||
@@ -491,7 +490,7 @@ END
|
|||||||
print_info "letsenrypt exists already (nothing downloaded > no certificate created and registered)"
|
print_info "letsenrypt exists already (nothing downloaded > no certificate created and registered)"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
git clone https://github.com/lukas2511/letsencrypt.sh $le_dir
|
git clone https://github.com/lukas2511/dehydrated $le_dir
|
||||||
cd $le_dir
|
cd $le_dir
|
||||||
# create config file for letsencrypt.sh
|
# create config file for letsencrypt.sh
|
||||||
echo "WELLKNOWN=$le_dir" > $le_dir/config.sh
|
echo "WELLKNOWN=$le_dir" > $le_dir/config.sh
|
||||||
@@ -511,9 +510,11 @@ END
|
|||||||
then
|
then
|
||||||
die "Failed to load $url_http"
|
die "Failed to load $url_http"
|
||||||
fi
|
fi
|
||||||
# run letsencrypt.sh
|
# accept terms of service of letsencrypt
|
||||||
|
./dehydrated --register --accept-terms
|
||||||
|
# run script dehydrated
|
||||||
#
|
#
|
||||||
./letsencrypt.sh --cron --config $le_dir/config.sh
|
./dehydrated --cron --config $le_dir/config.sh
|
||||||
}
|
}
|
||||||
|
|
||||||
function configure_apache_for_https {
|
function configure_apache_for_https {
|
||||||
@@ -564,17 +565,13 @@ function check_https {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function install_hubzilla {
|
function install_hubzilla {
|
||||||
print_info "installing hubzilla..."
|
print_info "installing hubzilla addons..."
|
||||||
# rm -R /var/www/html/ # for "stand alone" usage
|
cd /var/www/html/
|
||||||
cd /var/www/
|
util/add_addon_repo https://github.com/redmatrix/hubzilla-addons.git hzaddons
|
||||||
# git clone https://github.com/redmatrix/hubzilla html # for "stand alone" usage
|
|
||||||
cd html/
|
|
||||||
git clone https://github.com/redmatrix/hubzilla-addons addon
|
|
||||||
mkdir -p "store/[data]/smarty3"
|
mkdir -p "store/[data]/smarty3"
|
||||||
chmod -R 777 store
|
chmod -R 777 store
|
||||||
touch .htconfig.php
|
touch .htconfig.php
|
||||||
chmod ou+w .htconfig.php
|
chmod ou+w .htconfig.php
|
||||||
install_hubzilla_plugins
|
|
||||||
cd /var/www/
|
cd /var/www/
|
||||||
chown -R www-data:www-data html
|
chown -R www-data:www-data html
|
||||||
chown root:www-data /var/www/html/
|
chown root:www-data /var/www/html/
|
||||||
@@ -589,73 +586,6 @@ function install_hubzilla {
|
|||||||
print_info "installed hubzilla"
|
print_info "installed hubzilla"
|
||||||
}
|
}
|
||||||
|
|
||||||
function install_hubzilla_plugins {
|
|
||||||
print_info "installing hubzilla plugins..."
|
|
||||||
cd /var/www/html
|
|
||||||
plugin_install=.homeinstall/plugin_install.txt
|
|
||||||
theme_install=.homeinstall/theme_install.txt
|
|
||||||
# overwrite script to update the plugin and themes
|
|
||||||
rm -f $plugins_update
|
|
||||||
echo "cd /var/www/html" >> $plugins_update
|
|
||||||
###################
|
|
||||||
# write plugin file
|
|
||||||
if [ ! -f "$plugin_install" ]
|
|
||||||
then
|
|
||||||
echo "# To install a plugin" >> $plugin_install
|
|
||||||
echo "# 1. add the plugin in a new line and run" >> $plugin_install
|
|
||||||
echo "# 2. run" >> $plugin_install
|
|
||||||
echo "# cd /var/www/html/.homeinstall" >> $plugin_install
|
|
||||||
echo "# ./hubzilla-setup.sh" >> $plugin_install
|
|
||||||
echo "https://gitlab.com/zot/ownmapp.git ownMapp" >> $plugin_install
|
|
||||||
echo "https://gitlab.com/zot/hubzilla-chess.git chess" >> $plugin_install
|
|
||||||
fi
|
|
||||||
# install plugins
|
|
||||||
while read -r line; do
|
|
||||||
[[ "$line" =~ ^#.*$ ]] && continue
|
|
||||||
p_url=$(echo $line | awk -F' ' '{print $1}')
|
|
||||||
p_name=$(echo $line | awk -F' ' '{print $2}')
|
|
||||||
# basic check of format
|
|
||||||
if [ ${#p_url} -ge 1 ] && [ ${#p_name} -ge 1 ]
|
|
||||||
then
|
|
||||||
# install addon
|
|
||||||
util/add_addon_repo $line
|
|
||||||
util/update_addon_repo $p_name # not sure if this line is neccessary
|
|
||||||
echo "util/update_addon_repo $p_name" >> $plugins_update
|
|
||||||
else
|
|
||||||
print_info "skipping installation of a plugin from file $plugin_install - something wrong with format in line: $line"
|
|
||||||
fi
|
|
||||||
done < "$plugin_install"
|
|
||||||
###################
|
|
||||||
# write theme file
|
|
||||||
if [ ! -f "$theme_install" ]
|
|
||||||
then
|
|
||||||
echo "# To install a theme" >> $theme_install
|
|
||||||
echo "# 1. add the theme in a new line and run" >> $theme_install
|
|
||||||
echo "# 2. run" >> $theme_install
|
|
||||||
echo "# cd /var/www/html/.homeinstall" >> $theme_install
|
|
||||||
echo "# ./hubzilla-setup.sh" >> $theme_install
|
|
||||||
echo "https://github.com/DeadSuperHero/hubzilla-themes.git DeadSuperHeroThemes" >> $theme_install
|
|
||||||
|
|
||||||
fi
|
|
||||||
# install plugins
|
|
||||||
while read -r line; do
|
|
||||||
[[ "$line" =~ ^#.*$ ]] && continue
|
|
||||||
p_url=$(echo $line | awk -F' ' '{print $1}')
|
|
||||||
p_name=$(echo $line | awk -F' ' '{print $2}')
|
|
||||||
# basic check of format
|
|
||||||
if [ ${#p_url} -ge 1 ] && [ ${#p_name} -ge 1 ]
|
|
||||||
then
|
|
||||||
# install addon
|
|
||||||
util/add_theme_repo $line
|
|
||||||
util/update_theme_repo $p_name # not sure if this line is neccessary
|
|
||||||
echo "util/update_theme_repo $p_name" >> $plugins_update
|
|
||||||
else
|
|
||||||
print_info "skipping installation of a theme from file $theme_install - something wrong with format in line: $line"
|
|
||||||
fi
|
|
||||||
done < "$theme_install"
|
|
||||||
print_info "installed hubzilla plugins and themes"
|
|
||||||
}
|
|
||||||
|
|
||||||
function rewrite_to_https {
|
function rewrite_to_https {
|
||||||
print_info "configuring apache to redirect http to httpS ..."
|
print_info "configuring apache to redirect http to httpS ..."
|
||||||
htaccessfile=/var/www/html/.htaccess
|
htaccessfile=/var/www/html/.htaccess
|
||||||
@@ -675,25 +605,19 @@ function rewrite_to_https {
|
|||||||
function install_rsnapshot {
|
function install_rsnapshot {
|
||||||
print_info "installing rsnapshot..."
|
print_info "installing rsnapshot..."
|
||||||
nocheck_install "rsnapshot"
|
nocheck_install "rsnapshot"
|
||||||
# internal disk
|
# internal disk
|
||||||
cp -f /etc/rsnapshot.conf $snapshotconfig
|
cp -f /etc/rsnapshot.conf $snapshotconfig
|
||||||
sed -i "/hourly/s/retain/#retain/" $snapshotconfig
|
|
||||||
sed -i "/monthly/s/#retain/retain/" $snapshotconfig
|
|
||||||
sed -i "s/^cmd_cp/#cmd_cp/" $snapshotconfig
|
sed -i "s/^cmd_cp/#cmd_cp/" $snapshotconfig
|
||||||
sed -i "s/^backup/#backup/" $snapshotconfig
|
sed -i "s/^backup/#backup/" $snapshotconfig
|
||||||
if [ -z "`grep 'letsencrypt' $snapshotconfig`" ]
|
echo "backup /var/lib/mysql/ localhost/" >> $snapshotconfig
|
||||||
then
|
echo "backup /var/www/html/ localhost/" >> $snapshotconfig
|
||||||
echo "backup /var/lib/mysql/ localhost/" >> $snapshotconfig
|
echo "backup /var/www/letsencrypt/ localhost/" >> $snapshotconfig
|
||||||
echo "backup /var/www/html/ localhost/" >> $snapshotconfig
|
|
||||||
echo "backup /var/www/letsencrypt/ localhost/" >> $snapshotconfig
|
|
||||||
fi
|
|
||||||
# external disk
|
# external disk
|
||||||
if [ -n "$backup_device_name" ] && [ -n "$backup_device_pass" ]
|
if [ -n "$backup_device_name" ]
|
||||||
then
|
then
|
||||||
cp -f /etc/rsnapshot.conf $snapshotconfig_external_device
|
cp -f /etc/rsnapshot.conf $snapshotconfig_external_device
|
||||||
sed -i "s#snapshot_root.*#snapshot_root $backup_mount_point#" $snapshotconfig_external_device
|
sed -i "s#snapshot_root.*#snapshot_root $backup_mount_point#" $snapshotconfig_external_device
|
||||||
sed -i "/hourly/s/retain/#retain/" $snapshotconfig_external_device
|
sed -i "/alpha/s/6/30/" $snapshotconfig_external_device
|
||||||
sed -i "/monthly/s/#retain/retain/" $snapshotconfig_external_device
|
|
||||||
sed -i "s/^cmd_cp/#cmd_cp/" $snapshotconfig_external_device
|
sed -i "s/^cmd_cp/#cmd_cp/" $snapshotconfig_external_device
|
||||||
sed -i "s/^backup/#backup/" $snapshotconfig_external_device
|
sed -i "s/^backup/#backup/" $snapshotconfig_external_device
|
||||||
if [ -z "`grep 'letsencrypt' $snapshotconfig_external_device`" ]
|
if [ -z "`grep 'letsencrypt' $snapshotconfig_external_device`" ]
|
||||||
@@ -730,8 +654,8 @@ echo "#" >> /var/www/$hubzilladaily
|
|||||||
echo "echo \" \"" >> /var/www/$hubzilladaily
|
echo "echo \" \"" >> /var/www/$hubzilladaily
|
||||||
echo "echo \"+++ \$(date) +++\"" >> /var/www/$hubzilladaily
|
echo "echo \"+++ \$(date) +++\"" >> /var/www/$hubzilladaily
|
||||||
echo "echo \" \"" >> /var/www/$hubzilladaily
|
echo "echo \" \"" >> /var/www/$hubzilladaily
|
||||||
echo "echo \"\$(date) - renew certificat...\"" >> /var/www/$hubzilladaily
|
echo "echo \"\$(date) - renew certificate...\"" >> /var/www/$hubzilladaily
|
||||||
echo "bash $le_dir/letsencrypt.sh --cron --config $le_dir/config.sh" >> /var/www/$hubzilladaily
|
echo "bash $le_dir/dehydrated --cron --config $le_dir/config.sh" >> /var/www/$hubzilladaily
|
||||||
echo "#" >> /var/www/$hubzilladaily
|
echo "#" >> /var/www/$hubzilladaily
|
||||||
echo "# stop hubzilla" >> /var/www/$hubzilladaily
|
echo "# stop hubzilla" >> /var/www/$hubzilladaily
|
||||||
echo "echo \"\$(date) - stoping apache and mysql...\"" >> /var/www/$hubzilladaily
|
echo "echo \"\$(date) - stoping apache and mysql...\"" >> /var/www/$hubzilladaily
|
||||||
@@ -767,9 +691,7 @@ echo " if mount $backup_device_name $backup_mount_point" >> /var/www/$hub
|
|||||||
echo " then" >> /var/www/$hubzilladaily
|
echo " then" >> /var/www/$hubzilladaily
|
||||||
echo " device_mounted=1" >> /var/www/$hubzilladaily
|
echo " device_mounted=1" >> /var/www/$hubzilladaily
|
||||||
echo " echo \"device $backup_device_name is now mounted. Starting backup...\"" >> /var/www/$hubzilladaily
|
echo " echo \"device $backup_device_name is now mounted. Starting backup...\"" >> /var/www/$hubzilladaily
|
||||||
echo " rsnapshot -c $snapshotconfig_external_device daily" >> /var/www/$hubzilladaily
|
echo " rsnapshot -c $snapshotconfig_external_device alpha" >> /var/www/$hubzilladaily
|
||||||
echo " rsnapshot -c $snapshotconfig_external_device weekly" >> /var/www/$hubzilladaily
|
|
||||||
echo " rsnapshot -c $snapshotconfig_external_device monthly" >> /var/www/$hubzilladaily
|
|
||||||
echo " echo \"\$(date) - disk sizes...\"" >> /var/www/$hubzilladaily
|
echo " echo \"\$(date) - disk sizes...\"" >> /var/www/$hubzilladaily
|
||||||
echo " df -h" >> /var/www/$hubzilladaily
|
echo " df -h" >> /var/www/$hubzilladaily
|
||||||
echo " echo \"\$(date) - db size...\"" >> /var/www/$hubzilladaily
|
echo " echo \"\$(date) - db size...\"" >> /var/www/$hubzilladaily
|
||||||
@@ -788,28 +710,22 @@ echo " fi" >> /var/www/$hubzilladaily
|
|||||||
echo "fi" >> /var/www/$hubzilladaily
|
echo "fi" >> /var/www/$hubzilladaily
|
||||||
echo "if [ \$device_mounted == 0 ]" >> /var/www/$hubzilladaily
|
echo "if [ \$device_mounted == 0 ]" >> /var/www/$hubzilladaily
|
||||||
echo "then" >> /var/www/$hubzilladaily
|
echo "then" >> /var/www/$hubzilladaily
|
||||||
echo " echo \"device could not be mounted $backup_device_name. Using internal disk for backup...\"" >> /var/www/$hubzilladaily
|
echo " echo \"device could not be mounted $backup_device_name. No backup written.\"" >> /var/www/$hubzilladaily
|
||||||
echo " rsnapshot -c $snapshotconfig daily" >> /var/www/$hubzilladaily
|
|
||||||
echo " rsnapshot -c $snapshotconfig weekly" >> /var/www/$hubzilladaily
|
|
||||||
echo " rsnapshot -c $snapshotconfig monthly" >> /var/www/$hubzilladaily
|
|
||||||
echo "fi" >> /var/www/$hubzilladaily
|
echo "fi" >> /var/www/$hubzilladaily
|
||||||
echo "#" >> /var/www/$hubzilladaily
|
echo "#" >> /var/www/$hubzilladaily
|
||||||
echo "echo \"\$(date) - db size...\"" >> /var/www/$hubzilladaily
|
echo "echo \"\$(date) - db size...\"" >> /var/www/$hubzilladaily
|
||||||
echo "du -h /var/cache/rsnapshot/ | grep mysql/hubzilla" >> /var/www/$hubzilladaily
|
echo "du -h /var/lib/mysql/ | grep mysql/hubzilla" >> /var/www/$hubzilladaily
|
||||||
echo "#" >> /var/www/$hubzilladaily
|
echo "#" >> /var/www/$hubzilladaily
|
||||||
echo "# update" >> /var/www/$hubzilladaily
|
echo "# update" >> /var/www/$hubzilladaily
|
||||||
echo "echo \"\$(date) - updating letsencrypt.sh...\"" >> /var/www/$hubzilladaily
|
echo "echo \"\$(date) - updating dehydrated...\"" >> /var/www/$hubzilladaily
|
||||||
echo "git -C /var/www/letsencrypt/ pull" >> /var/www/$hubzilladaily
|
echo "git -C /var/www/letsencrypt/ pull" >> /var/www/$hubzilladaily
|
||||||
echo "echo \"\$(date) - updating hubhilla core...\"" >> /var/www/$hubzilladaily
|
echo "echo \"\$(date) - updating hubhilla core...\"" >> /var/www/$hubzilladaily
|
||||||
echo "git -C /var/www/html/ pull" >> /var/www/$hubzilladaily
|
echo "(cd /var/www/html/ ; util/udall)" >> /var/www/$hubzilladaily
|
||||||
echo "echo \"\$(date) - updating hubhilla addons...\"" >> /var/www/$hubzilladaily
|
|
||||||
echo "git -C /var/www/html/addon/ pull" >> /var/www/$hubzilladaily
|
|
||||||
echo "bash /var/www/html/$plugins_update" >> /var/www/$hubzilladaily
|
|
||||||
echo "chown -R www-data:www-data /var/www/html/ # make all accessable for the webserver" >> /var/www/$hubzilladaily
|
echo "chown -R www-data:www-data /var/www/html/ # make all accessable for the webserver" >> /var/www/$hubzilladaily
|
||||||
echo "chown root:www-data /var/www/html/.htaccess" >> /var/www/$hubzilladaily
|
echo "chown root:www-data /var/www/html/.htaccess" >> /var/www/$hubzilladaily
|
||||||
echo "chmod 0644 /var/www/html/.htaccess # www-data can read but not write it" >> /var/www/$hubzilladaily
|
echo "chmod 0644 /var/www/html/.htaccess # www-data can read but not write it" >> /var/www/$hubzilladaily
|
||||||
echo "echo \"\$(date) - updating linux...\"" >> /var/www/$hubzilladaily
|
echo "echo \"\$(date) - updating linux...\"" >> /var/www/$hubzilladaily
|
||||||
echo "apt-get -q -y update && apt-get -q -y dist-upgrade # update linux and upgrade" >> /var/www/$hubzilladaily
|
echo "apt-get -q -y update && apt-get -q -y dist-upgrade && apt-get -q -y autoremove # update linux and upgrade" >> /var/www/$hubzilladaily
|
||||||
echo "echo \"\$(date) - Backup hubzilla and update linux finished. Rebooting...\"" >> /var/www/$hubzilladaily
|
echo "echo \"\$(date) - Backup hubzilla and update linux finished. Rebooting...\"" >> /var/www/$hubzilladaily
|
||||||
echo "#" >> /var/www/$hubzilladaily
|
echo "#" >> /var/www/$hubzilladaily
|
||||||
echo "reboot" >> /var/www/$hubzilladaily
|
echo "reboot" >> /var/www/$hubzilladaily
|
||||||
@@ -894,7 +810,6 @@ install_run_selfhost
|
|||||||
ping_domain
|
ping_domain
|
||||||
configure_cron_freedns
|
configure_cron_freedns
|
||||||
configure_cron_selfhost
|
configure_cron_selfhost
|
||||||
install_git
|
|
||||||
install_letsencrypt
|
install_letsencrypt
|
||||||
configure_apache_for_https
|
configure_apache_for_https
|
||||||
check_https
|
check_https
|
||||||
|
|||||||
188
.travis.yml
188
.travis.yml
@@ -1,46 +1,178 @@
|
|||||||
|
#
|
||||||
|
# Travis-CI configuration file for Hubzilla
|
||||||
|
#
|
||||||
|
## configure things
|
||||||
|
#
|
||||||
|
|
||||||
# see http://about.travis-ci.org/docs/user/languages/php/ for more hints
|
# see http://about.travis-ci.org/docs/user/languages/php/ for more hints
|
||||||
language: php
|
language: php
|
||||||
|
|
||||||
# list any PHP version you want to test against
|
# use newer 'trusty' based distro, old one is 'precise'
|
||||||
|
dist: trusty
|
||||||
|
# use docker based containers
|
||||||
|
sudo: false
|
||||||
|
|
||||||
|
# Git branches whitelist to build on Travis CI
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
- dev
|
||||||
|
# whitelist our tags for release deployments e.g. 2.2
|
||||||
|
- /^\d+\.\d+(\.\d+)?(-\S*)?$/
|
||||||
|
|
||||||
|
# Install additional software
|
||||||
|
addons:
|
||||||
|
# Install dependencies for generating API documentation with doxygen
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- doxygen
|
||||||
|
- doxygen-latex
|
||||||
|
- graphviz
|
||||||
|
- ttf-liberation
|
||||||
|
|
||||||
|
# enable and start databases on a per job basis
|
||||||
|
#services:
|
||||||
|
# - mariadb
|
||||||
|
# - postgresql
|
||||||
|
|
||||||
|
# any PHP version we want to test against, current stable phpunit requires PHP >= 7.0
|
||||||
php:
|
php:
|
||||||
# using major version aliases
|
- '7.0'
|
||||||
|
- '7.1'
|
||||||
|
- '7.2'
|
||||||
|
# HHVM does not fulfil PHPUnit platform requirements as being compatible with PHP7 yet
|
||||||
|
#- 'hhvm'
|
||||||
|
|
||||||
# aliased to a recent 5.4.x version
|
# list of environments to test
|
||||||
- 5.4
|
env:
|
||||||
# aliased to a recent 5.5.x version
|
global:
|
||||||
- 5.5
|
# used for doxygen deployment script
|
||||||
# aliased to a recent 5.6.x version
|
- DOXYFILE: $TRAVIS_BUILD_DIR/util/Doxyfile
|
||||||
- 5.6
|
# Uncomment if a newer/specific version of Doxygen should be used
|
||||||
# aliased to a recent 7.x version
|
#- DOXY_VER: 1.8.12
|
||||||
- 7.0
|
# Code Coverage is slow, no need to have it in every build
|
||||||
# aliased to a recent hhvm version
|
- PHPUCOV: "--no-coverage"
|
||||||
- hhvm
|
# use matrix only for PHP and MySQL, all other combinations added through includes
|
||||||
|
matrix:
|
||||||
|
# trusty default MySQL 5.6
|
||||||
|
- DB=mysql MYSQL_VERSION=5.6
|
||||||
|
|
||||||
# optionally specify a list of environments, for example to test different RDBMS
|
# Matrix configuration details
|
||||||
#env:
|
|
||||||
# - DB=mysql
|
|
||||||
# - DB=pgsql
|
|
||||||
|
|
||||||
# optionally set up exclutions and allowed failures in the matrix
|
|
||||||
matrix:
|
matrix:
|
||||||
|
fast_finish: true
|
||||||
|
# Additional check combinations
|
||||||
|
include:
|
||||||
|
# PHP7.1, mariadb 10.1
|
||||||
|
- php: '7.1'
|
||||||
|
env: DB=mariadb MARIADB_VERSION=10.1 CODECOV=1
|
||||||
|
# use mariadb instead of MySQL
|
||||||
|
addons:
|
||||||
|
mariadb: '10.1'
|
||||||
|
# PHP7.1, PostgreSQL 9.6
|
||||||
|
- php: '7.1'
|
||||||
|
env: DB=pgsql POSTGRESQL_VERSION=9.6 PHPUNITFILE=phpunit-pgsql.xml
|
||||||
|
# Use newer postgres than 9.2 default
|
||||||
|
addons:
|
||||||
|
postgresql: '9.6'
|
||||||
|
services:
|
||||||
|
- postgresql
|
||||||
|
# PHP7.1, old precise distribution with MySQL 5.5
|
||||||
|
- php: '7.1'
|
||||||
|
env: DB=mysql MYSQL_VERSION=5.5
|
||||||
|
dist: precise
|
||||||
|
services:
|
||||||
|
- mysql
|
||||||
|
# MySQL 5.7 with Docker container
|
||||||
|
- php: '7.1'
|
||||||
|
env: DB=mysql MYSQL_VERSION=5.7
|
||||||
|
sudo: required
|
||||||
|
services:
|
||||||
|
- docker
|
||||||
|
# Excludes from default matrix combinations
|
||||||
# exclude:
|
# exclude:
|
||||||
# - php: hhvm
|
# - php: hhvm
|
||||||
# env: DB=pgsql # PDO driver for pgsql is unsupported by HHVM (3rd party install for support)
|
# env: DB=pgsql # PDO driver for pgsql is unsupported by HHVM (3rd party install for support)
|
||||||
allow_failures:
|
|
||||||
- php: 7.0
|
# cache composer downloads between runs
|
||||||
- php: hhvm
|
cache:
|
||||||
|
directories:
|
||||||
|
- $HOME/.composer/cache
|
||||||
|
#- $HOME/doxygen/doxygen-$DOXY_VER/bin
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
## execute things
|
||||||
|
#
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- travis_retry composer self-update
|
||||||
|
# Start MySQL 5.7 Docker container, needs some time to come up
|
||||||
|
- if [[ "$MYSQL_VERSION" == "5.7" ]]; then sudo service mysql stop; docker run -d -p 3306:3306 -e MYSQL_ALLOW_EMPTY_PASSWORD=yes mysql:5.7 && sleep 25 && docker ps; fi
|
||||||
|
|
||||||
|
# Install composer dev libs
|
||||||
|
install:
|
||||||
|
- travis_retry composer install --optimize-autoloader --no-progress
|
||||||
|
|
||||||
# execute any number of scripts before the test run, custom env's are available as variables
|
# execute any number of scripts before the test run, custom env's are available as variables
|
||||||
#before_script:
|
before_script:
|
||||||
# - if [[ "$DB" == "pgsql" ]]; then psql -c "DROP DATABASE IF EXISTS hello_world_test;" -U postgres; fi
|
# Use code coverage config for phpunit
|
||||||
# - if [[ "$DB" == "pgsql" ]]; then psql -c "create database hello_world_test;" -U postgres; fi
|
- if [[ ! -z $CODECOV ]]; then export PHPUCOV=""; fi
|
||||||
# - if [[ "$DB" == "mysql" ]]; then mysql -e "create database IF NOT EXISTS hello_world_test;" -uroot; fi
|
# Some preparation tasks of environment
|
||||||
|
- ./tests/travis/prepare.sh
|
||||||
|
# DB specific prepare scripts
|
||||||
|
- if [[ "$DB" == "mysql" ]]; then ./tests/travis/prepare_mysql.sh; fi
|
||||||
|
- if [[ "$DB" == "mariadb" ]]; then ./tests/travis/prepare_mysql.sh; fi
|
||||||
|
- if [[ "$DB" == "pgsql" ]]; then ./tests/travis/prepare_pgsql.sh; fi
|
||||||
|
|
||||||
# omitting "script:" will default to phpunit
|
# omitting "script:" will default to phpunit
|
||||||
# use the $DB env variable to determine the phpunit.xml to use
|
script:
|
||||||
script: phpunit tests/*php
|
- ./vendor/bin/phpunit $PHPUCOV -c tests/$PHPUNITFILE
|
||||||
|
|
||||||
|
after_success:
|
||||||
|
- cat tests/results/testdox.txt
|
||||||
|
# Generate API documentation and prepare for deployment
|
||||||
|
- ./tests/travis/gen_apidocs.sh
|
||||||
|
after_failure:
|
||||||
|
- cat tests/results/testdox.txt
|
||||||
|
|
||||||
|
# Deploying release and API documentation to GitHub
|
||||||
|
before_deploy:
|
||||||
|
- if [[ "$CODECOV" == "1" ]]; then zip -9 -r -q tests/hubzilla-testresults.zip tests/results; fi
|
||||||
|
deploy:
|
||||||
|
- provider: pages
|
||||||
|
skip_cleanup: true
|
||||||
|
local_dir: $TRAVIS_BUILD_DIR/doc/html
|
||||||
|
github_token: $GH_TOKEN
|
||||||
|
on:
|
||||||
|
repo: redmatrix/hubzilla
|
||||||
|
branch: master
|
||||||
|
condition: '(-n "$GH_TOKEN") && ("$TRAVIS_JOB_NUMBER" == "${TRAVIS_BUILD_NUMBER}.1")'
|
||||||
|
# add API documentation to release, could also be used to provide full packages if we want to drop vendor from our repo
|
||||||
|
- provider: releases
|
||||||
|
skip_cleanup: true
|
||||||
|
api_key: $GH_TOKEN
|
||||||
|
file: 'doc/hubzilla-api-documentation.zip'
|
||||||
|
on:
|
||||||
|
repo: redmatrix/hubzilla
|
||||||
|
tags: true
|
||||||
|
condition: '(-n "$GH_TOKEN") && ("$TRAVIS_JOB_NUMBER" == "${TRAVIS_BUILD_NUMBER}.1")'
|
||||||
|
# add code coverage and test results to release
|
||||||
|
- provider: releases
|
||||||
|
skip_cleanup: true
|
||||||
|
api_key: $GH_TOKEN
|
||||||
|
file: 'tests/hubzilla-testresults.zip'
|
||||||
|
on:
|
||||||
|
repo: redmatrix/hubzilla
|
||||||
|
tags: true
|
||||||
|
condition: '(-n "$GH_TOKEN") && ("$CODECOV" == "1")'
|
||||||
|
#after_deploy:
|
||||||
|
|
||||||
|
#after_script:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# configure notifications (email, IRC, campfire etc)
|
# configure notifications (email, IRC, campfire etc)
|
||||||
notifications:
|
#notifications:
|
||||||
# irc: "irc.freenode.org#yourfavouriteroomfortravis"
|
# irc: "irc.freenode.org#yourfavouriteroomfortravis"
|
||||||
# a plugin/script to post to a hubzilla channel would be neat here
|
# a plugin/script to post to a hubzilla channel would be neat here
|
||||||
670
CHANGELOG
670
CHANGELOG
@@ -1,3 +1,673 @@
|
|||||||
|
Hubzilla 3.0 (2018-01-09)
|
||||||
|
- Updated homeinstall script
|
||||||
|
- Sort cloud directory by 1. is_dir and 2. name
|
||||||
|
- Document that imagick calls/execs ffmpeg for mp4 video thumbnails
|
||||||
|
- Use pipe_stream() instead of file_{get, put}_contents() in attach_store()
|
||||||
|
- Make homeinstall script ready for Debian 9
|
||||||
|
- Add url and headings to bbco_autocomplete()
|
||||||
|
- Remove additional linebreaks after headings
|
||||||
|
- html2bbcode: use headings bbcode for headings
|
||||||
|
- Don't zidify all permalinks, only zot permalinks
|
||||||
|
- Make remote homelink link to the home host and not to the home channel
|
||||||
|
- Auto promote beginner (techlevel 0) accounts to level 1 after they show signs of active participation.
|
||||||
|
- Go back to including the photo thumbnail data in the export file.
|
||||||
|
- Improvements to file import/export
|
||||||
|
- Default value for xlink_rating_text
|
||||||
|
- Implement IMoveTarget and recursive file/directory move/rename - github issue #680
|
||||||
|
- Synchronise an attach_move operation to clones
|
||||||
|
- Provide a themed page with an error notification on errors instead of an obtuse XML error structure in mod cloud
|
||||||
|
- Disallow backslashes in wiki and wiki-page names
|
||||||
|
- We only require one update module. The rest are superfluous.
|
||||||
|
- Render installable elements as buttons instead of links
|
||||||
|
- Implement chunked uploads for photos page
|
||||||
|
- Remove warning for large files on cloud upload
|
||||||
|
- Add a filter for notification to show new posts only
|
||||||
|
- Implement chunked uploads for cloud
|
||||||
|
- Use httpsig auth for getfile
|
||||||
|
- Load the profile images in the custom acl selector only if we actually need them
|
||||||
|
- Rework liveUpdate() and notificationsUpdate() (aka ping) to first do the liveUpdate and when this is done only do the ping once.
|
||||||
|
- Don't include invisible "update activities" in category widget
|
||||||
|
- Default profile assign
|
||||||
|
- Provide system config option for minimum registration age.
|
||||||
|
- Remove deprecated $a argument from advanced_profile()
|
||||||
|
- Change to bbcode calling parameters
|
||||||
|
- Extra checking of server headers in upload functions
|
||||||
|
- Provide a handler for chunked uploads in mod file_upload
|
||||||
|
- Optional divider between item header and body
|
||||||
|
- Allow toggle to SMBC scaling mode.
|
||||||
|
- Add thumbnail hook
|
||||||
|
- Implement SVG thumbnails and expose security setting
|
||||||
|
- Implement video thumbnail generator
|
||||||
|
- Implement pdf thumbnails
|
||||||
|
- Implement thumbnail generator for epubs
|
||||||
|
- Make browser history buttons work with ajax calls in mod display and hq
|
||||||
|
- Implement tile view for mod cloud (read only)
|
||||||
|
- Add mp3 audio thumbnail generator
|
||||||
|
- Set display_path for photo_upload from the DAV File interface
|
||||||
|
- Provide a generalised interface for thumbnail generators to support various content types
|
||||||
|
- Add ID3Parser library.
|
||||||
|
- Text thumbnails in cloud tile mode
|
||||||
|
- Revisit media breakpoints - do not switch to mobile view to early.
|
||||||
|
- Add French to help pages language dropdown selector
|
||||||
|
- Inroduce the HQ module - an alternative landing page for hubzilla
|
||||||
|
- Strip author name from notify messages in notifications - github issue #911
|
||||||
|
- Remove column item.diaspora_meta
|
||||||
|
- Provide ability to pin apps to navbar from mod apps
|
||||||
|
- Add private forums to forum widget
|
||||||
|
- Move notifications style to widgets.css
|
||||||
|
- Sort out a few more large image upload issues
|
||||||
|
- Move notifications full-screen handling to notifications widget
|
||||||
|
- Move mailhost settings from plugin to core
|
||||||
|
- Sort combined private mail conversations by latest updated conversation instead of created parent
|
||||||
|
- Filter atokens on acl search
|
||||||
|
- Allow a site to block (public) the directory separately from other resources.
|
||||||
|
- Improve removed_channel final cleanup - github issue #386
|
||||||
|
- Cleanup of upload_to_comments(
|
||||||
|
- Dedicate the first click to slideup the cover again but make sure the nav buttons remain functional
|
||||||
|
- Set os_syspath in DAV file put operation so that photos will scale correctly.
|
||||||
|
- Unit tests for Zotlabs\Access classes
|
||||||
|
- Bring back tabindex to submit comments
|
||||||
|
- attach.php minor cleanup and doc
|
||||||
|
- Allow cloud filenames to include ampersands without messing up auth tokens (zid, owt, and zat, and the constant placeholder 'f=')
|
||||||
|
- Provide short localised summary for likes that will end up in displayed notifications
|
||||||
|
- Improving Doxygen documentation.
|
||||||
|
- Update item_normal() to not include ACTIVITY_OBJ_FILE obj_type
|
||||||
|
- Sort out issues with pubstream item interactions
|
||||||
|
- Don't perform zot_refresh on dead sites unless $force is set
|
||||||
|
- Do not send message_list responses to dead sites (this delivery method bypassed the notifier)
|
||||||
|
- Support for netselect query
|
||||||
|
- Add another delivery control parameter (queue threshold)
|
||||||
|
- Add some documentation about shareable widgets
|
||||||
|
- Allow plugin class widgets
|
||||||
|
- Some more work on unit tests
|
||||||
|
- Encrypt the owa token
|
||||||
|
- Bring back the markdown post feature
|
||||||
|
- We call Theme:url() statically, make it also static.
|
||||||
|
- Table structure for pseudo or proxy channels (pchan)
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
- Fix sync non-default profile photo changes to clones - github issue #113
|
||||||
|
- Fix prev/next buttons on connedit can show deleted connections - github issue #673
|
||||||
|
- Fix affinity widget settings
|
||||||
|
- Fix dupe bug in content hooks - github issue #943
|
||||||
|
- Fix directory keywords returned from dir_tagadelic() in standalone mode
|
||||||
|
- Fix argument warning when arguments are correct in util/dcp
|
||||||
|
- Fix issue with long filenames in mod cloud
|
||||||
|
- Fix misc. issues with new 'insert photo from photo album' github issue #475
|
||||||
|
- Fix regression in channel sources delivery
|
||||||
|
- Fix loading of theme-specific widgets
|
||||||
|
- Fix unable to add wiki pages with spaces
|
||||||
|
- Fix mod display and others that require a non-zero profile_uid for updates
|
||||||
|
- Fix various PHP 7.2 issues
|
||||||
|
- Fix typo in HTTPSig
|
||||||
|
- Fix pagetitle lost importing a pdl element from conversation
|
||||||
|
- Fix js warning - getelementbyid (id doesn't exist)
|
||||||
|
- Fix some pubstream on/off weirdness
|
||||||
|
- Fix default addressbook has no name - github issue #921
|
||||||
|
- Fix double html ids in caldav widget if more than one sharee
|
||||||
|
- Fix regression in cdav calendar widget
|
||||||
|
- Fix sync packet not generated when deleting a file using the web browser interface
|
||||||
|
- Fix album cover thumb generator
|
||||||
|
- Fix like-button for images - github issue #826
|
||||||
|
- Fix typo - github issue #910
|
||||||
|
- Fix issue with group_rmv()
|
||||||
|
- Fix php warnings on photo delete
|
||||||
|
- Fix some conflicts between private tags and forum tags
|
||||||
|
- Fix some schema issues
|
||||||
|
- Fix wiki pages not updating after creating new page
|
||||||
|
- Fix a PHP warning in Permissions::FilledPerms()
|
||||||
|
- Fix unicode characters in urls tripping up url regexes - github issue #901
|
||||||
|
- Fix second half of github issue #893
|
||||||
|
- Fix common connections on suggestion page showing wildly different results than remote profile, and is consistently off by one
|
||||||
|
- Fix cloud redirects with owt tokens
|
||||||
|
- Fix issues with diaspora xchans
|
||||||
|
- Fix memory overflow trying to delete a connection with a very high noise to signal ratio
|
||||||
|
- Fix sql error in page module
|
||||||
|
- Fix unstar
|
||||||
|
|
||||||
|
Plugins/Addon
|
||||||
|
Diaspora: fix 'view full size' photo link - core github issue #947
|
||||||
|
Diaspora: implement recent changes in diaspora account_migration spec
|
||||||
|
GNU-Social: fix uploading a photo to a post results in double post - github issue 75
|
||||||
|
GNU-Social: fix gnusoc plugin not respecting delayed delivery - github issue 74
|
||||||
|
Pubcrawl: fix PHP warning
|
||||||
|
Diaspora: remove garbage from magic envelope
|
||||||
|
Diaspora: fix permalinks for zot reshares
|
||||||
|
New addon: hzfiles - sync files across hubzilla servers
|
||||||
|
Fix various PHP 7.2 issues
|
||||||
|
Remove Firefox social plugin - it was deprecated and removed in firefox version 57
|
||||||
|
Diaspora: unset id and parent for local comments
|
||||||
|
Pubsubhubbub: set interactive flag to avoid delivery killing if block_public is enabled
|
||||||
|
Mailhost addon moved to core
|
||||||
|
Remove js_upload addon
|
||||||
|
|
||||||
|
|
||||||
|
Hubzilla 2.8.1 (2017-11-11)
|
||||||
|
- Rename channel app events to calendar and add nav_set_selected() to /cal
|
||||||
|
- Load notifications links to /display via ajax if we are already in /display
|
||||||
|
- Add location info to the navbar for remote visitors
|
||||||
|
- Bring back tabindex to submit comments
|
||||||
|
- Add spanish translations for context help
|
||||||
|
- Added mode to portfolio widget
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
- Fix os_syspath in DAV file put operation so that photos will scale correctly
|
||||||
|
- Fix unicode characters in urls tripping up url regexes - github issue #901
|
||||||
|
- Fix wiki pages not updating after creating new page
|
||||||
|
- Fix notifications covered by cover photo on medium size screens - github issue #906
|
||||||
|
- Fix unable to change permissions on wiki with space in name
|
||||||
|
- Fix only show nav app link if we have a selected app
|
||||||
|
- Fix unable to mark all messages read
|
||||||
|
- Fix imagedata not set correctly if large photo and imagick is not installed
|
||||||
|
- Fix issues with diaspora xchans
|
||||||
|
- Fix profile photo issue triggered by a previous bug
|
||||||
|
|
||||||
|
Plugins/Addon
|
||||||
|
N-S-F-W: improve the undocumented n-s-f-w author::word feature
|
||||||
|
Diaspora: update the import_diaspora tool for the version 2.0 account export files
|
||||||
|
Diaspora: fix comments are partly containing "diaspora_handle" instead of "author" - github issue #69
|
||||||
|
Pubcrawl: provide feature setting for downgrade_media option
|
||||||
|
Pubcrawl: fix issue where replies to replies did not find its parent
|
||||||
|
Diaspora: fix friendica likes on comments
|
||||||
|
Diaspora: fix private mail
|
||||||
|
Diaspora: fix third party deletes/retractions not propagating
|
||||||
|
Diaspora: likes not working - github issue #895 in core
|
||||||
|
Diaspora: fix comments from unknown persons not accepted if allow public comments is enabled - github issue #68
|
||||||
|
XMPP: fix php warning
|
||||||
|
|
||||||
|
Hubzilla 2.8 (2017-10-25)
|
||||||
|
- Redirect to be moderated items to /moderate
|
||||||
|
- Update notifications if notifications area remains open
|
||||||
|
- Create an actual logout module instead of relying on internal variables
|
||||||
|
- Add local_channel as a comanche condition variable
|
||||||
|
- Implement possibility to pin app-tray apps in the navbar via app category navbar_default
|
||||||
|
- Introduce custom navbars
|
||||||
|
- Re-implement single delivery
|
||||||
|
- Pdledit usability improvements
|
||||||
|
- Implement next generation notifications in right aside
|
||||||
|
- Implement single post view for /pubstream
|
||||||
|
- Make anonymous comments work in mod display
|
||||||
|
- Introduce notifications for unseen public stream posts (off by default)
|
||||||
|
- Preperatory work on Zot VI
|
||||||
|
- Add app for site admin
|
||||||
|
- Introduce experimental alternate channel_menu navigation (off by default)
|
||||||
|
- Introduce notifications for shared files
|
||||||
|
- Bring back notifications for account approvals
|
||||||
|
- Urlencode hashes from mod_acl
|
||||||
|
- Don't use chanlink_url() for feed mentions
|
||||||
|
- Design common friends widget to fit better in the app and move it to left aside
|
||||||
|
- Allow navbar to be used when cover photo is displayed in mod channel
|
||||||
|
- Implement admin setting to use imagick converter for large photos
|
||||||
|
- Process activity deletes from OStatus which for whatever reason do not use the industry standard tombstone mechanism
|
||||||
|
- Implement new css based spinner
|
||||||
|
- Move the link header initialisation from Router to Webserver
|
||||||
|
⁻ Extend activity_match() to work with arrays
|
||||||
|
- Updated the trusted CA cert database
|
||||||
|
- Ostatus - support likes of comments
|
||||||
|
- Provide ability to mention a forum by using !forumname as well as the traditional red style (@forumname+)
|
||||||
|
- Encrypt delivery reports (not backward compatible)
|
||||||
|
- Provide a space between link header params (draft-cavage-http-signatures-08)
|
||||||
|
- Turn common_friends into a widget
|
||||||
|
- Update to jquery-3.2.1
|
||||||
|
- Wiki pages sorted by name
|
||||||
|
- Create new hooks for permissions_accept and permissions_reject
|
||||||
|
- Provide rel=alternate link if no reshare content in post
|
||||||
|
- Add remote login button to login page
|
||||||
|
- DB update to add index to item.resource_id
|
||||||
|
- Implement wiki editing (name and acl)
|
||||||
|
- Provide a hook for importing a channel photo at channel creation time
|
||||||
|
- Implement wiki mimetype lock
|
||||||
|
- Bring back wiki downloads
|
||||||
|
- Add text/plain mimetype to wiki
|
||||||
|
- Implement per page mimetype selection for wikis
|
||||||
|
- Added english context help for apps and appman
|
||||||
|
- Implement owa (open web auth)
|
||||||
|
- Ignore diaspora_meta column on item import
|
||||||
|
- Check code permissions on cloud files
|
||||||
|
- Remove period from characters allowed in username
|
||||||
|
- Make comment highlighting more reliable
|
||||||
|
- Sign zot-info packets with httpsignatures
|
||||||
|
- Implement server to server magic auth
|
||||||
|
- Provide support for json-ld signatures
|
||||||
|
- Rewrite comment form open/close handling to be more reliable
|
||||||
|
- Radically reduce code duplication in updateConvItems()
|
||||||
|
- Remove discover tab in favour of the public stream app
|
||||||
|
- Apply autotime to all autotime classed elements when static loading a page
|
||||||
|
- Implement cards feature
|
||||||
|
- Extended support for help page translations including table of contents files at the top level
|
||||||
|
- Introduce util/dmkdir - a mkdir tool for DAV
|
||||||
|
- Various doco improvements
|
||||||
|
- Introduce util/dcp (DAV-copy) - copy file or directory from local system to Hubzilla
|
||||||
|
- Provide support for HTTPsig
|
||||||
|
- Implement mechanism for selective network following in protocol connectors (diaspora, ostatus, activitypub, zot, rss)
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
- Fix w2w posts not removed in contact_remove() - github issue #837
|
||||||
|
- Fix guests not having a unique (non-existent) url
|
||||||
|
- Fix mod register re-using the password
|
||||||
|
- Fix write_storage permission not checked in /display
|
||||||
|
- Fix discovery of moderated items in enotify
|
||||||
|
- Fix profile thing image not deleted when thing deleted - github issue #868
|
||||||
|
- Fix deletions to comments not synced on wall posts
|
||||||
|
- Fix community tags not preserved on post edit - github issue #865
|
||||||
|
- Fix profile photo propagation issue if the local xchan_photo_[l|m|s] fields were changed from the /photo/profile/l/n form to photo/[hash] form by a clone operation
|
||||||
|
- Fix lockstate and current permissions not handed over to editor in mod card_edit
|
||||||
|
- Fix profile edit dropdown for multiple profiles
|
||||||
|
- Fix affinity slider spinner
|
||||||
|
- Fix mod pubsites broken
|
||||||
|
- Fix directory server admin selection includes known dead sites
|
||||||
|
- Fix sticky-kit issue where the bottom of left aside was not visible when section content was short
|
||||||
|
- Fix possibility to set bogus my_address
|
||||||
|
- Fix deleting of wiki pages
|
||||||
|
- Fix selected theme not appearing selected after change - github issue #855
|
||||||
|
- Fix an issue where some encoded mids were not found in /display
|
||||||
|
- Fix issue with mentions and xchans with @ or /
|
||||||
|
- Fix webfinger returns invalid XML - github issue #851
|
||||||
|
- Fix last remaining task in tasklist was not removed from view when completed
|
||||||
|
|
||||||
|
Plugins/Addon
|
||||||
|
Hubwall: Remove errant $1 string in sender name
|
||||||
|
Map federation protocols for zotinfo
|
||||||
|
Gnusoc: force ostatus profile photos to get refreshed monthly
|
||||||
|
Gnusoc: fix ostatus mention notifications
|
||||||
|
Gnusoc: unsubscribe to gnusoc feeds if connector is disabled
|
||||||
|
Phpmailer: not using load/unload
|
||||||
|
Gnusoc: don't provide some information if gnusoc is disabled by the channel
|
||||||
|
Diaspora: add a predelivery interval
|
||||||
|
Diaspora: support for likes on comments
|
||||||
|
Introduce the pubcrawl plugin - an unapologetically non-compliant ActivityPub Protocol implemention
|
||||||
|
Introduce gravatar plugin
|
||||||
|
Pubsubhubbub: produce much more compact PuSH feeds
|
||||||
|
Diaspora: support text comments on reshare posts
|
||||||
|
Diaspora: changes to delivery scenarios for the special handling of profile messages
|
||||||
|
Diaspora: put diaspora seed_location in json webfinger
|
||||||
|
Gnusoc: fix mis-attributed comments from mastodon
|
||||||
|
Gnusoc: allow discovery by url (not just reddress) and permit upgrade from 'unknown' network to gnusoc
|
||||||
|
Implement mechanism for selective network following in protocol connectors
|
||||||
|
|
||||||
|
|
||||||
|
Hubzilla 2.6.3 (2017-09-18)
|
||||||
|
- Fix anonymous comments/likes on photos - this is not yet implemented
|
||||||
|
- Fix favicon not displayed on certain pages
|
||||||
|
- Fix hubzilla logo icon for favicon and email notifications
|
||||||
|
- Fix an issue with displaying selected theme in settings/display
|
||||||
|
- [SECURITY] Restrict the input characters we accept in token verification strings to hex digits
|
||||||
|
- Remove hubzilla.nl from fallback directory servers
|
||||||
|
|
||||||
|
Hubzilla 2.6.2 (2017-08-31)
|
||||||
|
- Fix webfinger returns invalid XML (github issue #851)
|
||||||
|
|
||||||
|
|
||||||
|
Hubzilla 2.6.1 (2017-08-18)
|
||||||
|
- Fix a regression with dav clients
|
||||||
|
- Raise install requirements
|
||||||
|
|
||||||
|
Plugins/Addon
|
||||||
|
- Diaspora: fix PHP warning
|
||||||
|
- GNU-Social: fix PHP warning
|
||||||
|
|
||||||
|
|
||||||
|
Hubzilla 2.6 (2017-08-16)
|
||||||
|
- Upgrade to bootstrap-4 beta
|
||||||
|
- Consolidate disable_discover_tab config
|
||||||
|
- Fix some bbcode to markdown conversion issues
|
||||||
|
- Improved finding of recursive attachment permissions
|
||||||
|
- Smaller line-height for notification badges
|
||||||
|
- Bluegrid schema removed - will be added again if someone is willing to maintain it
|
||||||
|
- Improved file_activity()
|
||||||
|
- DB - add index for item.obj_type
|
||||||
|
- Add options flag to bb_to_markdown() so we can distinguish between diaspora use and other use and therefore filter and adjust content selectively
|
||||||
|
- Close the apps-menu if the notifications-menu is open and vice versa
|
||||||
|
- Remove redundant call to jquery ready function in photo albums view
|
||||||
|
- Remove borders from navbar toggler in mobile view
|
||||||
|
- Improve the formatting of shares when converting from bbcode to markdown
|
||||||
|
- Suppress fopen errors from dav
|
||||||
|
- Make local channel (not our own) nav menus appear similar to what we are used from remote channels
|
||||||
|
- Indicate the selected channel in the dropdown menu if the feature is enabled
|
||||||
|
- Provide a mechanism to mark apps active in the app tray
|
||||||
|
- Allow wildcard tag and category searches
|
||||||
|
- Improved installer
|
||||||
|
- Update some addon docs and ensure we only generate statistics once a day
|
||||||
|
- Turn url requests where argv[0] is something.xyz into module='something' and $_REQUEST['module_format'] = 'xyz'; But leave modules beginning with . (like .well_known) alone (convert the initial . to _ and then strip it)
|
||||||
|
- Turn platform name and std_version into config variables
|
||||||
|
- Implement chunked uploads on the wall
|
||||||
|
- Prevent expiration of conversations you are involved with
|
||||||
|
- Update htmlpurifier to version 4.9.3
|
||||||
|
- Update sabre/http to version 4.2.3
|
||||||
|
- Add optimize-autoloader to composer config
|
||||||
|
- Missing abook_{my,their}_perms in pg schema and missing keys in mysql schema
|
||||||
|
- Provide a gender icon on the profile sidebar within reason
|
||||||
|
- Provide more comprehensible information on the admin summary page
|
||||||
|
- Upgrade blueimp from 9.8 to 9.18
|
||||||
|
- Chanview - if already connected, bypass the chanview intermediary page and go straight to the remote profile.
|
||||||
|
- Allow poke by xchan_hash
|
||||||
|
- guess_image_type() - ignore scheme when checking for urls
|
||||||
|
- Remove unused page_widgets.php include and provide a general function for loading sql from file
|
||||||
|
- Migrate cdav from addons to core
|
||||||
|
- Address several mail issues
|
||||||
|
- Add files and photos to featured apps by default
|
||||||
|
- import_author_zot() fixes
|
||||||
|
- Remove deprecated app parameter from conversation()
|
||||||
|
- Implement anonymous comments (like wordpress)
|
||||||
|
- Add rel=noopener to all external target _blank links
|
||||||
|
- Add 'can_comment_on_post' hook so we can better deal with the complications of Diaspora policy
|
||||||
|
- Added Portfolio widget (requires foundation)
|
||||||
|
- Convert schema_mysql engine to InnoDB and charset utf8mb4
|
||||||
|
- Put unreachable federated connections in the archived tab of the connections list page
|
||||||
|
- Indicate on connections page if a federated connection from another network is unavailable from the current location
|
||||||
|
- Make authenticated oembeds optional, default to false.
|
||||||
|
- Remove text_highlight css load from core
|
||||||
|
- Numerous ostatus feed improvements (mastodon, gnu-social)
|
||||||
|
- Provide hook when deleting a connection - we need this to clean up dangling PuSH subscriptions
|
||||||
|
- Move code syntax highlighting to plugin
|
||||||
|
- Oembed: ensure that width and height are returned as type int and not float
|
||||||
|
- Rewrite wiki pages widget - no need for ajax on pageload, show the pages to not authenticated people.
|
||||||
|
- Convert randprof to use chanlink_hash() instead of chanlink_url() and filter sys channels by xchan.xchan_system instead of xchan_addr != sys@%
|
||||||
|
- Update Sabre libraries
|
||||||
|
- Only provide "connected apps" on the settings menu if techlevel > 0.
|
||||||
|
- Provide ability to search webpage
|
||||||
|
- Move disapora xrd stuff to plugin
|
||||||
|
- Deprecate server_role
|
||||||
|
- Introduce automatic language selection for help, webpages, and wiki content
|
||||||
|
- Provide ability to order apps in app-tray
|
||||||
|
- Replace Markdownify library with html-to-markdown library
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
- Fix channel manager and nav channel select visible if in a delegate session
|
||||||
|
- Fix wrong wiki pages in the sidebar github issue #841
|
||||||
|
- Fix a bug where if multiple channels uploaded the same file to the same folder, the uploaded file would end up with an incremental number added to the filename for each upload even if the file did not exist yet in the channels folder
|
||||||
|
- Fix privacy groups not syncing across clones properly (github issue #832)
|
||||||
|
- Fix an issue where the ability to use a portion of the message-id to display a message wasn't honoured in all cases
|
||||||
|
- Fix minor issues in the bs-default schema
|
||||||
|
- Fix backward compatibility for album links generated in earlier times before the ambiguity of photo album names was solved (github issue #827)
|
||||||
|
- Fix photo item comments not ported to bs4
|
||||||
|
- Fix incorrect album link
|
||||||
|
- Fix incorrect follow url in webfinger
|
||||||
|
- Fix regression - allow position attributes in oembedable zcards
|
||||||
|
- Fix affinitiy slider settings were being updated on any submit of of settings/featured
|
||||||
|
- Fix minor weirdness in zot finger results after deleting a clone from a channel that was on a site which was previously migrated from http to https and still had the old hubloc
|
||||||
|
- Fix cloud headers already sent issue
|
||||||
|
- Partial fix for failure to sync photos - appears to be memory exhaustion and dependent on filesize although an unrelated issue was found with directory creation during file sync (we didn't check ownership when looking for duplicates)
|
||||||
|
- Fix github issue #810
|
||||||
|
- Don't allow negative age in directory listings
|
||||||
|
- Fix allow setting a default schema for the hub (github issue #797) and allow selecting of focus (hubzilla default) schema if a default is set
|
||||||
|
- Fix update_r1189() for mysql and postgres
|
||||||
|
|
||||||
|
Plugins/Addon
|
||||||
|
Diaspora: Rewrite the addon to implemented Diaspora Version 2 federation protocol
|
||||||
|
GNU-Social: GNU-Social and Mastodon compatibility was greatly increased and a "fetch conversations" feature added to try and locate missing contextual references and maintain conversations in posts from those networks
|
||||||
|
Rename statistics_json to statistics and implement nodeinfo v2
|
||||||
|
New authchoose addon to restrict what sites you authenticate to by default
|
||||||
|
Cdav addon moved to core
|
||||||
|
head_add_css() needs a preceding '/' to find files in the addons dir
|
||||||
|
New addon code syntax highlighting (moved from core to addon)
|
||||||
|
Pubsubhubbub: specify a minimum number of records - otherwise it defaults to zero
|
||||||
|
|
||||||
|
|
||||||
|
Hubzilla 2.4 (2017-05-31)
|
||||||
|
- Silence php warning during install
|
||||||
|
- Implemented switch statement logic in Comanche layout parser
|
||||||
|
- Don't allow html in plugin comment blocks
|
||||||
|
- Handle Mastodon urls in markdown/bbcode conversion
|
||||||
|
- Get rid of edit activities
|
||||||
|
- Collapse sysapps if viewing a remote channel
|
||||||
|
- Various Doxygen fixes
|
||||||
|
- Update SimplePie library to version 1.5
|
||||||
|
- Add check for PHP zip extension during install
|
||||||
|
- Add unit tests for AccessList class
|
||||||
|
- Authenticate onepoll so we can receive private posts/comments in zotfeed
|
||||||
|
- Various postgres fixes
|
||||||
|
- Some work on preparing clientside e2ee
|
||||||
|
- Allow to set a default channel for the rare case where a default channel is not selected but channels actually exist
|
||||||
|
- Support reverse magic-auth in oembed requests
|
||||||
|
- Improved handling of Mastodon feeds
|
||||||
|
- When template "none" is used in a webpage layout, then the contents of the page should be the sole output, with no other code before or after the page element content
|
||||||
|
- If there is no site record, site_dead won't be 0, in a left join it will in fact be null. As long as it isn't 1, we should attempt delivery
|
||||||
|
- Order wiki pages by creation date
|
||||||
|
- Backend infrastructure for channel protection password; which will be used to optionally encrypt export files and resolve channel/identity ownership/hijacking disputes
|
||||||
|
- Don't allow any null fields in notify creation
|
||||||
|
- Webfinger cleanup
|
||||||
|
- Envelope privacy
|
||||||
|
- We do not parse the body in discover_by_url(), so no need to preserve iframes in SimplePie
|
||||||
|
- Correct the mastodon "boost" (aka 'share') author attribution by checking for share activities and pulling the original author info from the activity:object
|
||||||
|
- Only log zot_refresh content if json decode was successful
|
||||||
|
- Revisit the import_author_zot algorithm yet again. There was one bug that we weren't returning necessary information in the first SQL query - and performance/loading problem if one tries to refresh a dead site
|
||||||
|
- Import_author_xchan - since we rarely refresh zot-info for non-connections, force a cache reload once a week to catch things like profile photo updates and location changes
|
||||||
|
- Create site_store_lowlevel() to initialise data structures for the site table
|
||||||
|
- Change hook for perm_is_allowed while retaining backwards compatibility
|
||||||
|
- import_author_zot() - check for both hubloc and xchan entries. This should catch and repair entries which were subject to transient storage failures
|
||||||
|
- Import authors from any unrecognised network as network 'unknown'
|
||||||
|
- Crypto update - default is now aes-256-ctr
|
||||||
|
- Get rid of get_app()
|
||||||
|
- Add 'author_is_pmable()' function with plugin hooks to control whether or not to display a 'send mail' link in the thread author menu
|
||||||
|
- Provide platform specific install script
|
||||||
|
- Allow for project specific DB updates
|
||||||
|
- Get rid of davguest
|
||||||
|
- Move db_upgrade to zlib
|
||||||
|
- Add CSRF protection for import and import_items
|
||||||
|
- Add some documentation for import functions
|
||||||
|
- Do not allow creating two wikis with the same name
|
||||||
|
- Update textcomplete library to version 1.8.0
|
||||||
|
- Create channel_store_lowlevel()
|
||||||
|
- Allow setting the system email name/address/reply
|
||||||
|
- Use the same host macro for sender address as for reply_to address
|
||||||
|
- Use the relevant attach directory/path for photo albums instead of an album basename which may not be unique. Created an 'ellipsify()' function to shorten long names and keep the beginning and end intact
|
||||||
|
- Simplify the message signing spaghetti
|
||||||
|
- Class MarkdownSoap to safely store markdown by purifying and preserving (escaped) what may be unsafe code in codeblocks. The stored item needs to be unescaped just prior to calling the markdown-to-html processor
|
||||||
|
- Remove the unimplemented upload limit site settings from UI
|
||||||
|
- Cleanup code_allowed
|
||||||
|
- Move widgets to standalone classes
|
||||||
|
- Upgrade redbasic to bootstrap 4
|
||||||
|
- Updated HTML Purifier from 4.6.0 to 4.9.2 with better PHP7 compatibility
|
||||||
|
- Remove redundant and non-functional/broken check for successfully cloned channel record which was left over from an earlier method of creating the table; which was deprecated a few months back
|
||||||
|
- Update bshaffer/oauth2-server-php library
|
||||||
|
- Add unit test for purify_html()
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
- Fix website export tool creating invalid zip file - issue #790
|
||||||
|
- Fix files not synced correctly - issue #769
|
||||||
|
- Fix empty ACL should not result in no ACL when uploading a file
|
||||||
|
- Fix cover photo was unintentionally disabled when block_public in effect
|
||||||
|
- Fix markdown autolinks - issue 752
|
||||||
|
- Fix connectDefaultShare generated js function, though it isn't obvious if we still use it
|
||||||
|
- Fix a couple more instances where we were still calling mail() directly for site critical messages
|
||||||
|
- Fix when clicking a notification to view a private mail message, actually view that message instead of the most recent
|
||||||
|
- Fix group by item query
|
||||||
|
|
||||||
|
Plugins/Addon
|
||||||
|
- smileybutton: do not load emojis
|
||||||
|
- pubsubhubbub: fixes associated with recent compatibility feed mods
|
||||||
|
- gnusoc: mastodon follow_activity compatibility issues
|
||||||
|
- gnusoc: add profile photo to feed meta
|
||||||
|
- gnusoc: add salmon link information to the public feed when GNU-Social is enabled
|
||||||
|
- chess: fix bugs when deleting games
|
||||||
|
|
||||||
|
Hubzilla 2.2 (2017-03-08)
|
||||||
|
- Provide version compatibility check for themes (minversion, maxversion)
|
||||||
|
- Use chanlink_hash() instead of chanlink_url() where appropriate
|
||||||
|
- Use head_add_link() for feed discovery
|
||||||
|
- Provide HTTP header parser which honours continuation lines
|
||||||
|
- Numerous doco improvements
|
||||||
|
- Implement virtual privacy groups from restricted profile access list
|
||||||
|
- Implement permission roles
|
||||||
|
- Implement app-tray
|
||||||
|
- Default to manual conversation updates
|
||||||
|
- Implement channel move for all server roles
|
||||||
|
- Implement nav login modal
|
||||||
|
- Rename bb2diaspora.php to markdown.php
|
||||||
|
- Remove obsolete module 'match'
|
||||||
|
- Move firefox social api configuration to plugin
|
||||||
|
- Move rsd service to twitter_api plugin
|
||||||
|
- Add build_pagehead hook
|
||||||
|
- Move opensearch to plugins
|
||||||
|
- Move dreamhost hack to plugin
|
||||||
|
- Add wiki permissions
|
||||||
|
- Introduce hubloc_store_lowlevel() and xchan_store_lowlevel()
|
||||||
|
- Move diaspora account import to the diaspora plugin
|
||||||
|
- Allow export of single data sets instead of always exporting everything we know about in channel export
|
||||||
|
- Queue optimisations for sites that have lingered in the queue for more than a couple of days
|
||||||
|
- Add affinity slider tool settings for min and max defaults in settings/featured
|
||||||
|
- Provide lowlevel xchan storage function to ensure that all non-null rows are initialised
|
||||||
|
- Implement native wiki
|
||||||
|
- Block well-known from oembed
|
||||||
|
- Implement observer.language bbcode and observer.language comanche conditional
|
||||||
|
- Implement daemon_addon hook to let plugins create custom background processes
|
||||||
|
- Implement profile vcards
|
||||||
|
- Implement connection vcards
|
||||||
|
- Implement 'click to call' in address book
|
||||||
|
- Default cover photo
|
||||||
|
- Remove fullscreen functionality in photo album view
|
||||||
|
- Update fontawesome lib to version 4.7.0
|
||||||
|
- Implement a menu to select a section to be open by default in connedit
|
||||||
|
- Improve comanche conditionals
|
||||||
|
- Add enclosures and categories to atom feed parsing
|
||||||
|
- Allow the atom_entry hook to change the results
|
||||||
|
- Set 'adjust for viewer timezone' as the default for new events
|
||||||
|
- Allow event creation in other timezones than your own
|
||||||
|
- Update fullcalendar lib to version 3.1
|
||||||
|
- Move api version call back to core
|
||||||
|
- Create first webpage as 'home' if none exist
|
||||||
|
- Show webpages link to visitors if a 'home' page exists
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
- Fix schema not saved if session theme != selected theme and schema select display issue
|
||||||
|
- Fix no acl not detected in post_activity_item()
|
||||||
|
- Fix find_folder_hash_by_path() was not safe against multiple attach structures with the same filename but in different directories
|
||||||
|
- Fix don't search on empty filename - we shouldn't find it. The reason why this change is being made is because we actually did find it due to a development glitch
|
||||||
|
- Fix several places where head_add_(css|js) functions have been used incorrectly.
|
||||||
|
- Fix webpage import tool
|
||||||
|
- Fix numerous bugs with the addon repo management GUI
|
||||||
|
- Fix attach_delete() to remove photo resources even if the attach table row wasn't found
|
||||||
|
- Fix choking if photo_factory() returns null
|
||||||
|
- Fix embedimage if an albumname contains quotes
|
||||||
|
- Fix chat member list when one or more members are connected via access tokens
|
||||||
|
- Fix issue #636 - some localised (e.g. Italian) strings have single quotes which throw JS errors when used in single quoted template constructs
|
||||||
|
- Fix issues #629 and #635 - edited post arriving from downstream source was not being rejected
|
||||||
|
- Fix peoplefind widget not honouring directory option settings
|
||||||
|
- Fix issue with HTML in code blocks in markdown in wiki
|
||||||
|
- Fix issue with post signatures if posted from api and logged in locally with a different identity
|
||||||
|
|
||||||
|
Plugins/Addon
|
||||||
|
- Add experimental webmention plugin
|
||||||
|
- NSFW: Use button instead of text link
|
||||||
|
- Diaspora: gracefully handle multiple photos per post
|
||||||
|
- Diaspora: change profile photo permission call
|
||||||
|
- Logrotate: don't throw an error if another server process renamed the logfile before we got to it
|
||||||
|
- Chess: the channel owner must be one of the players, so only require selecting one connection for an opponent
|
||||||
|
- Move firefox social api configuration to plugin from core
|
||||||
|
- Move rsd service to twitter_api plugin from core
|
||||||
|
- Move opensearch to plugins from core
|
||||||
|
- Move dreamhost hack to plugin from
|
||||||
|
- Move diaspora account import to addon from core
|
||||||
|
- Reflect hubloc store changes in plugins
|
||||||
|
- Reflect xchan store changes in plugins
|
||||||
|
- Rendezvous: Fixed marker creation bug
|
||||||
|
- Rendezvous: Center on marker if specified in URL, and update browser address bar with shareable link when selecting markers on the map
|
||||||
|
- Rendezvous: Set default value of 0 for priximity alert when making new markers
|
||||||
|
- Move gitwiki to plugins from core which has been replaced by native wiki
|
||||||
|
- Openclipatar: reflect changes to files and photos which were unified in core some time ago
|
||||||
|
- Reintroduce gnusocial plugin after security/functionality review
|
||||||
|
- Twitter_api: hubzilla core issue 638 - unsupported message-id field not available in all twitter api functions
|
||||||
|
- Superblock: update to reflect core changes
|
||||||
|
- Rendezvous: implement static marker proximity alert
|
||||||
|
- Phpmailer: security update
|
||||||
|
|
||||||
|
Hubzilla 2.0 (2016-12-23)
|
||||||
|
- Deprecate bb_iframe
|
||||||
|
- Note widget: resize the textarea to reveal full content
|
||||||
|
- Implement fixed left aside
|
||||||
|
- Implement lockview for wikilist
|
||||||
|
- Simplify wikilist widget
|
||||||
|
- Router error reporting
|
||||||
|
- Setup changes to check for shell_exec and exec functions
|
||||||
|
- Extensible permissions upgrade handling for channels with custom permission roles
|
||||||
|
- Allow plugins to cancel item_store() and item_store_update()
|
||||||
|
- ZOT version 1.2 provides negotiation of cryptographic algorithms
|
||||||
|
- Provide a fresh new look and cleaner layout and more relevant information to siteinfo
|
||||||
|
- Introduce highlight bbcode [hl]
|
||||||
|
- Implement wiki mimetypes markdown or bbcode
|
||||||
|
- Doc pages refactoring
|
||||||
|
- Update webpages and wiki context help
|
||||||
|
- Make a git commit when a new wiki page is created
|
||||||
|
- Prev-next navigation for mod_connedit to ease bulk connection edits
|
||||||
|
- Move the remote user homebutton to the user menu
|
||||||
|
- Do not render maps/locations for Diaspora destinations
|
||||||
|
- Provide 'per-page' caching for is_matrix_url() results to reduce duplicate queries
|
||||||
|
- Don't send notification for posts/comments on old conversations that were refetched after having expired
|
||||||
|
- Numerous wiki UI improvements
|
||||||
|
- Move twitter api to addon
|
||||||
|
- Cleanup and re-organise the voting and attendance buttons
|
||||||
|
- Reorganise emoticons
|
||||||
|
- Collapse navbar-collapse-1 if avatar menu is clicked.
|
||||||
|
- New display setting: static page update as opposed to live update
|
||||||
|
- Command line administrative channel connect utility
|
||||||
|
- Modernise chanview
|
||||||
|
- Implement edit activities to share post/comment edits with protocols which do not support them (e.g. Diaspora)
|
||||||
|
- Wiki export
|
||||||
|
- Numerous postgres compatibility fixes
|
||||||
|
- Remove requirement that imported profile photos be in the profile photos album
|
||||||
|
- Change event behaviour - share by default.
|
||||||
|
- Use PDO database driver exclusively (deprecate drivers that are separately maintained)
|
||||||
|
- Zot API re-write and extended
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
- Fix z_fetch_url() incorrect variable
|
||||||
|
- Fix SQL error with app categories
|
||||||
|
- Fix do not show revert buttons if we do not have write perms
|
||||||
|
- Fix dropdown positions
|
||||||
|
- Fix do not increase opacity to more than 1
|
||||||
|
- Fix clone sync missing for some item delete operations
|
||||||
|
- Fix embed-image for fullscreen mode
|
||||||
|
- Fix attach_list_files()
|
||||||
|
- Fix full screen for embedded videos
|
||||||
|
- Fix the forum widget for forums with custom perms
|
||||||
|
- Fix issue #607 parens not recognised inside urls
|
||||||
|
- Fix pubsites: don't list dead sites
|
||||||
|
- Fix issue #596 silence headers already sent warning
|
||||||
|
- Fix missing plugins in zot-info
|
||||||
|
- Fix notification issue
|
||||||
|
- Fix issue #594 like of thing appears as profile owner like
|
||||||
|
- Fix export issue
|
||||||
|
- Fix checklist bbcode - only turn [] and [x] into checkboxes if it is found inside a checklist
|
||||||
|
- Fix wiki permissions issues
|
||||||
|
- Fix public calendar leaks connection information (birthdays) when view_contacts is not allowed
|
||||||
|
- Fix attach_rename: flaw in duplicate filename detection resulted in filename(1)(1)(1).ext
|
||||||
|
- Fix a fatal error with incorrect DB object access
|
||||||
|
- Provide /locs link on settings page if there is more than one hubloc for this channnel *that isn't deleted*.
|
||||||
|
- Fix issue #577 if connecting to a channel that is already pending, undo the pending and set connect permissions accordingly
|
||||||
|
- Fix issue #575, when 'nofinish' is set on an event, invalid date was generated/stored
|
||||||
|
- Fix bbcode event formatting issue
|
||||||
|
- Fix zot_finger from navbar people search looping
|
||||||
|
- Fix fromStandalonePermission()
|
||||||
|
|
||||||
|
Plugins
|
||||||
|
- GNU Social: removed from addons for security reasons - it might be re-implemented once it is properly reviewed
|
||||||
|
- Diaspora: missing item author when diaspora public comment received from relay
|
||||||
|
- Superblock: refactoring
|
||||||
|
- New addon: tripleaes for pro
|
||||||
|
- Cdav: "if not exists" only supported starting with postgresql v. 9.5 debian stable has 9.4
|
||||||
|
- Rendezvous: added markers and members export tool at /rendezvous/[group_id]/export/{markers,members}
|
||||||
|
- Twitter: move twitter api to addon
|
||||||
|
- New addon: b2tbtn (back to top button)
|
||||||
|
- Diaspora: import public diaspora messages to sys if applicable
|
||||||
|
- Diaspora: try and handle singletons better and simplify the associated notifier decisions
|
||||||
|
- Rendezvous: add proximity alert feature to members to issue notification when member is within a specified distance.
|
||||||
|
- New addon: diaspora_reconnect to refriend diaspora/friendica connections from a clone or channel move
|
||||||
|
- Diaspora: change the logic for deciding between upstream and downstream message flow for notifier plugins
|
||||||
|
- Rendezvous: prompt member to share their location by activating the GPS control using a tooltip and pulsing visibility
|
||||||
|
- statistics_json: fix nodeinfo
|
||||||
|
- Rendezvous: restored the lost gps-icon.png and corrected the OpenStreetMap tile server URL to avoid insecure content warnings
|
||||||
|
- Rendezvous: use observer name if available
|
||||||
|
- std_embeds: missing backslash
|
||||||
|
- Diaspora: postgres fixes issue #31
|
||||||
|
- Rendezvous: added marker list with centering buttons and popup open.
|
||||||
|
- Rendezvous: added control to see list of members sharing their location, with buttons to pan the map to center them
|
||||||
|
- Diaspora: system level diaspora toggle
|
||||||
|
- Rendezvous: added control that displays members.
|
||||||
|
- Diaspora: rename diaspora2bb() to markdown_to_bb() in core
|
||||||
|
- Hubwall: remove illegal unescaped angle chars
|
||||||
|
- Rendezvous: Add control to delete member if not updated in over 14 minutes
|
||||||
|
|
||||||
Hubzilla 1.14 (2016-10-13)
|
Hubzilla 1.14 (2016-10-13)
|
||||||
- New hook bbcode_filter
|
- New hook bbcode_filter
|
||||||
- Unify the various mail sending instance to enotify::send() and z_mail()
|
- Unify the various mail sending instance to enotify::send() and z_mail()
|
||||||
|
|||||||
37
DEVELOPERS
Normal file
37
DEVELOPERS
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
Developer Certificate of Origin
|
||||||
|
Version 1.1
|
||||||
|
|
||||||
|
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||||
|
1 Letterman Drive
|
||||||
|
Suite D4700
|
||||||
|
San Francisco, CA, 94129
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies of this
|
||||||
|
license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
|
||||||
|
Developer's Certificate of Origin 1.1
|
||||||
|
|
||||||
|
By making a contribution to this project, I certify that:
|
||||||
|
|
||||||
|
(a) The contribution was created in whole or in part by me and I
|
||||||
|
have the right to submit it under the open source license
|
||||||
|
indicated in the file; or
|
||||||
|
|
||||||
|
(b) The contribution is based upon previous work that, to the best
|
||||||
|
of my knowledge, is covered under an appropriate open source
|
||||||
|
license and I have the right under that license to submit that
|
||||||
|
work with modifications, whether created in whole or in part
|
||||||
|
by me, under the same open source license (unless I am
|
||||||
|
permitted to submit under a different license), as indicated
|
||||||
|
in the file; or
|
||||||
|
|
||||||
|
(c) The contribution was provided directly to me by some other
|
||||||
|
person who certified (a), (b) or (c) and I have not modified
|
||||||
|
it.
|
||||||
|
|
||||||
|
(d) I understand and agree that this project and the contribution
|
||||||
|
are public and that a record of the contribution (including all
|
||||||
|
personal information I submit with it, including my sign-off) is
|
||||||
|
maintained indefinitely and may be redistributed consistent with
|
||||||
|
this project or the open source license(s) involved.
|
||||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2010-2016 the Hubzilla Community
|
Copyright (c) 2010-2017 the Hubzilla Community
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
|||||||
49
README.md
49
README.md
@@ -3,60 +3,27 @@
|
|||||||
Hubzilla - Community Server
|
Hubzilla - Community Server
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
Groupware re-imagined and re-invented.
|
|
||||||
--------------------------------------
|
|
||||||
|
|
||||||
Connect and link decentralised web communities.
|
|
||||||
-----------------------------------------------
|
|
||||||
|
|
||||||
<p align="center" markdown="1">
|
<p align="center" markdown="1">
|
||||||
<em><a href="https://github.com/redmatrix/hubzilla/blob/master/install/INSTALL.txt">Installing Hubzilla</a></em>
|
<em><a href="https://github.com/redmatrix/hubzilla/blob/master/install/INSTALL.txt">Installing Hubzilla</a></em>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
**What are Hubz?**
|
|
||||||
|
|
||||||
Hubz are independent general-purpose websites that not only connect with their associated members and viewers, but also connect together to exchange personal communications and other information with each other.
|
**What is Hubzilla?**
|
||||||
This allows hub members on any hub to securely and privately share anything; with anybody, on any hub - anywhere; or share stuff publicly with anybody on the internet if desired.
|
|
||||||
|
|
||||||
**Hubzilla** is the server software which makes this possible. It is a sophisticated and unique combination of an open source content management system and a decentralised identity, communications, and permissions framework and protocol suite, built using common webserver technology (PHP/MySQL/Apache and popular variants). The end result is a level of systems integration, privacy control, and communications features that you wouldn't think are possible in either a content management system or a decentralised communications network. It also brings a new level of cooperation and privacy to the web and introduces the concept of personally owned "single sign-on" to web services across the entire internet.
|
Hubzilla is a general purpose communication server integrated with a web publishing system and a decentralised permission system. If this sounds like a bunch of technical mumbo-jumbo to you, just think of it as an independent platform for sharing stuff online.
|
||||||
|
|
||||||
Hubzilla hubz are
|
Hubzilla contains some social network bits, some cloud storage bits, some blog and forum bits, and some content management bits. These are all integrated within a common privacy framework - and it is all decentralised.
|
||||||
|
|
||||||
* decentralised
|
Everything you publish or share can be restricted to those channels and people you wish to share them with; and these permissions work completely invisibly - even with channels on different servers or other communications services.
|
||||||
* inherently social
|
|
||||||
* optionally inter-networked with other hubz
|
|
||||||
* privacy-enabled (privacy exclusions work across the entire internet to any registered identity on any compatible hubz)
|
|
||||||
|
|
||||||
Possible website applications include
|
Migration and live backups of your connections, settings, and everything you publish are built-in, so you never need worry about server failure.
|
||||||
|
|
||||||
* decentralised social networking nodes
|
Hubzilla is completely decentralised and open source, for you modify or adapt to your needs and desires. Plugins, themes, and numerous configuration options extend the overall capabilities to do anything you can imagine.
|
||||||
* personal cloud storage
|
|
||||||
* file dropboxes
|
|
||||||
* managing organisational communications and activities
|
|
||||||
* collaboration and community decision-making
|
|
||||||
* small business websites
|
|
||||||
* public and private media/file libraries
|
|
||||||
* blogs
|
|
||||||
* event promotion
|
|
||||||
* feed aggregation and republishing
|
|
||||||
* forums
|
|
||||||
* dating websites
|
|
||||||
* pretty much anything you can do on a traditional blog or community website, but that you could do better if you could easily connect it with other websites or privately share things across website boundaries.
|
|
||||||
|
|
||||||
<p align="center" markdown="1">
|
|
||||||
<em><a href="https://github.com/redmatrix/hubzilla/blob/master/install/INSTALL.txt">Installing Hubzilla</a></em>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
**Who Are We and What Are Our Principles?**
|
**Who Are We?**
|
||||||
|
|
||||||
The Hubzilla community is powered by passionate volunteers creating an open source **commons** of decentralised services which are highly integrated and can rival the feature set of centralised providers. We are open to sponsorship and donations to cover expenses and compensate for our time and energy, however the project core is basically non-profit and is not designed for the purpose of commercial gain or exploitation.
|
|
||||||
|
|
||||||
Some sites may include monetisation strategies such as subscriptions and *freemium* models where members pay for resources they consume beyond a basic level. The project community supports such monetisation initiatives (nobody should be forced to pay "out of pocket" to provide a service to others), but we maintain the **commons** to provide open and free access of the software to all.
|
|
||||||
|
|
||||||
The software is not designed for data collection of its members or providing advertising. We don't have a need or desire for these things and feel that software built around these goals is poorly designed and represents compromised principles and ethics.
|
|
||||||
|
|
||||||
As a project, we are inclusive of all beliefs and cultures and do what we are able to provide an environment that is free from hostility and harrassment. Whether or not we succeed in this endaevour requires constant vigilance and help from all members of the community, working together to build an inter-networking tool with amazing potential.
|
|
||||||
|
|
||||||
|
The Hubzilla community consists of passionate volunteers creating an open source commons of decentralised services which are highly integrated and can rival the feature set of large centralised providers. We do our best to provide ethical software which places you in control of your online communications and privacy expectations.
|
||||||
|
|
||||||
|
|
||||||
[](https://travis-ci.org/redmatrix/hubzilla)
|
[](https://travis-ci.org/redmatrix/hubzilla)
|
||||||
|
|||||||
@@ -2,20 +2,54 @@
|
|||||||
|
|
||||||
namespace Zotlabs\Access;
|
namespace Zotlabs\Access;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AccessList class.
|
||||||
|
*
|
||||||
|
* A class to hold an AccessList object with allowed and denied contacts and
|
||||||
|
* groups.
|
||||||
|
*/
|
||||||
class AccessList {
|
class AccessList {
|
||||||
|
/**
|
||||||
|
* @brief Allow contacts
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
private $allow_cid;
|
private $allow_cid;
|
||||||
|
/**
|
||||||
|
* @brief Allow groups
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
private $allow_gid;
|
private $allow_gid;
|
||||||
|
/**
|
||||||
|
* @brief Deny contacts
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
private $deny_cid;
|
private $deny_cid;
|
||||||
|
/**
|
||||||
|
* @brief Deny groups
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
private $deny_gid;
|
private $deny_gid;
|
||||||
|
/**
|
||||||
/* indicates if we are using the default constructor values or values that have been set explicitly. */
|
* @brief Indicates if we are using the default constructor values or
|
||||||
|
* values that have been set explicitly.
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
private $explicit;
|
private $explicit;
|
||||||
|
|
||||||
function __construct($channel) {
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor for AccessList class.
|
||||||
|
*
|
||||||
|
* @note The array to pass to the constructor is different from the array
|
||||||
|
* that you provide to the set() or set_from_array() functions.
|
||||||
|
*
|
||||||
|
* @param array $channel A channel array, where these entries are evaluated:
|
||||||
|
* * \e string \b channel_allow_cid => string of allowed cids
|
||||||
|
* * \e string \b channel_allow_gid => string of allowed gids
|
||||||
|
* * \e string \b channel_deny_cid => string of denied cids
|
||||||
|
* * \e string \b channel_deny_gid => string of denied gids
|
||||||
|
*/
|
||||||
|
function __construct($channel) {
|
||||||
if($channel) {
|
if($channel) {
|
||||||
$this->allow_cid = $channel['channel_allow_cid'];
|
$this->allow_cid = $channel['channel_allow_cid'];
|
||||||
$this->allow_gid = $channel['channel_allow_gid'];
|
$this->allow_gid = $channel['channel_allow_gid'];
|
||||||
@@ -32,61 +66,95 @@ class AccessList {
|
|||||||
$this->explicit = false;
|
$this->explicit = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get if we are using the default constructor values
|
||||||
|
* or values that have been set explicitly.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
function get_explicit() {
|
function get_explicit() {
|
||||||
return $this->explicit;
|
return $this->explicit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set AccessList from strings such as those in already
|
* @brief Set access list from strings such as those in already
|
||||||
* existing stored data items
|
* existing stored data items.
|
||||||
|
*
|
||||||
|
* @note The array to pass to this set function is different from the array
|
||||||
|
* that you provide to the constructor or set_from_array().
|
||||||
|
*
|
||||||
|
* @param array $arr
|
||||||
|
* * \e string \b allow_cid => string of allowed cids
|
||||||
|
* * \e string \b allow_gid => string of allowed gids
|
||||||
|
* * \e string \b deny_cid => string of denied cids
|
||||||
|
* * \e string \b deny_gid => string of denied gids
|
||||||
|
* @param boolean $explicit (optional) default true
|
||||||
*/
|
*/
|
||||||
|
function set($arr, $explicit = true) {
|
||||||
function set($arr,$explicit = true) {
|
|
||||||
$this->allow_cid = $arr['allow_cid'];
|
$this->allow_cid = $arr['allow_cid'];
|
||||||
$this->allow_gid = $arr['allow_gid'];
|
$this->allow_gid = $arr['allow_gid'];
|
||||||
$this->deny_cid = $arr['deny_cid'];
|
$this->deny_cid = $arr['deny_cid'];
|
||||||
$this->deny_gid = $arr['deny_gid'];
|
$this->deny_gid = $arr['deny_gid'];
|
||||||
|
|
||||||
$this->explicit = $explicit;
|
$this->explicit = $explicit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return an array consisting of the current
|
* @brief Return an array consisting of the current access list components
|
||||||
* access list components where the elements
|
* where the elements are directly storable.
|
||||||
* are directly storable.
|
*
|
||||||
|
* @return Associative array with:
|
||||||
|
* * \e string \b allow_cid => string of allowed cids
|
||||||
|
* * \e string \b allow_gid => string of allowed gids
|
||||||
|
* * \e string \b deny_cid => string of denied cids
|
||||||
|
* * \e string \b deny_gid => string of denied gids
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
return array(
|
return [
|
||||||
'allow_cid' => $this->allow_cid,
|
'allow_cid' => $this->allow_cid,
|
||||||
'allow_gid' => $this->allow_gid,
|
'allow_gid' => $this->allow_gid,
|
||||||
'deny_cid' => $this->deny_cid,
|
'deny_cid' => $this->deny_cid,
|
||||||
'deny_gid' => $this->deny_gid,
|
'deny_gid' => $this->deny_gid,
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set AccessList from arrays, such as those provided by
|
* @brief Set access list components from arrays, such as those provided by
|
||||||
* acl_selector(). For convenience, a string (or non-array) input is
|
* acl_selector().
|
||||||
* assumed to be a comma-separated list and auto-converted into an array.
|
*
|
||||||
|
* For convenience, a string (or non-array) input is assumed to be a
|
||||||
|
* comma-separated list and auto-converted into an array.
|
||||||
|
*
|
||||||
|
* @note The array to pass to this set function is different from the array
|
||||||
|
* that you provide to the constructor or set().
|
||||||
|
*
|
||||||
|
* @param array $arr An associative array with:
|
||||||
|
* * \e array|string \b contact_allow => array with cids or comma-seperated string
|
||||||
|
* * \e array|string \b group_allow => array with gids or comma-seperated string
|
||||||
|
* * \e array|string \b contact_deny => array with cids or comma-seperated string
|
||||||
|
* * \e array|string \b group_deny => array with gids or comma-seperated string
|
||||||
|
* @param boolean $explicit (optional) default true
|
||||||
*/
|
*/
|
||||||
|
function set_from_array($arr, $explicit = true) {
|
||||||
function set_from_array($arr,$explicit = true) {
|
|
||||||
$this->allow_cid = perms2str((is_array($arr['contact_allow']))
|
$this->allow_cid = perms2str((is_array($arr['contact_allow']))
|
||||||
? $arr['contact_allow'] : explode(',',$arr['contact_allow']));
|
? $arr['contact_allow'] : explode(',', $arr['contact_allow']));
|
||||||
$this->allow_gid = perms2str((is_array($arr['group_allow']))
|
$this->allow_gid = perms2str((is_array($arr['group_allow']))
|
||||||
? $arr['group_allow'] : explode(',',$arr['group_allow']));
|
? $arr['group_allow'] : explode(',', $arr['group_allow']));
|
||||||
$this->deny_cid = perms2str((is_array($arr['contact_deny']))
|
$this->deny_cid = perms2str((is_array($arr['contact_deny']))
|
||||||
? $arr['contact_deny'] : explode(',',$arr['contact_deny']));
|
? $arr['contact_deny'] : explode(',', $arr['contact_deny']));
|
||||||
$this->deny_gid = perms2str((is_array($arr['group_deny']))
|
$this->deny_gid = perms2str((is_array($arr['group_deny']))
|
||||||
? $arr['group_deny'] : explode(',',$arr['group_deny']));
|
? $arr['group_deny'] : explode(',', $arr['group_deny']));
|
||||||
|
|
||||||
$this->explicit = $explicit;
|
$this->explicit = $explicit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns true if any access lists component is set.
|
||||||
|
*
|
||||||
|
* @return boolean Return true if any of allow_* deny_* values is set.
|
||||||
|
*/
|
||||||
function is_private() {
|
function is_private() {
|
||||||
return (($this->allow_cid || $this->allow_gid || $this->deny_cid || $this->deny_gid) ? true : false);
|
return (($this->allow_cid || $this->allow_gid || $this->deny_cid || $this->deny_gid) ? true : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class PermissionLimits {
|
|||||||
$perms = Permissions::Perms();
|
$perms = Permissions::Perms();
|
||||||
$limits = array();
|
$limits = array();
|
||||||
foreach($perms as $k => $v) {
|
foreach($perms as $k => $v) {
|
||||||
if(strstr($k,'view'))
|
if(strstr($k,'view') || $k === 'post_comments')
|
||||||
$limits[$k] = PERMS_PUBLIC;
|
$limits[$k] = PERMS_PUBLIC;
|
||||||
else
|
else
|
||||||
$limits[$k] = PERMS_SPECIFIC;
|
$limits[$k] = PERMS_SPECIFIC;
|
||||||
|
|||||||
@@ -1,12 +1,24 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
namespace Zotlabs\Access;
|
namespace Zotlabs\Access;
|
||||||
|
|
||||||
use Zotlabs\Lib as Zlib;
|
/**
|
||||||
|
* @brief PermissionRoles class.
|
||||||
|
*
|
||||||
|
* @see Permissions
|
||||||
|
*/
|
||||||
class PermissionRoles {
|
class PermissionRoles {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PermissionRoles version.
|
||||||
|
*
|
||||||
|
* This must match the version in Permissions.php before permission updates can run.
|
||||||
|
*
|
||||||
|
* @return number
|
||||||
|
*/
|
||||||
|
static public function version() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
static function role_perms($role) {
|
static function role_perms($role) {
|
||||||
|
|
||||||
@@ -22,10 +34,11 @@ class PermissionRoles {
|
|||||||
$ret['online'] = true;
|
$ret['online'] = true;
|
||||||
$ret['perms_connect'] = [
|
$ret['perms_connect'] = [
|
||||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||||
'view_pages', 'send_stream', 'post_wall', 'post_comments',
|
'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
|
||||||
'post_mail', 'chat', 'post_like', 'republish' ];
|
'post_mail', 'chat', 'post_like', 'republish'
|
||||||
|
];
|
||||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'social_restricted':
|
case 'social_restricted':
|
||||||
@@ -35,9 +48,9 @@ class PermissionRoles {
|
|||||||
$ret['online'] = true;
|
$ret['online'] = true;
|
||||||
$ret['perms_connect'] = [
|
$ret['perms_connect'] = [
|
||||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||||
'view_pages', 'send_stream', 'post_wall', 'post_comments',
|
'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
|
||||||
'post_mail', 'chat', 'post_like' ];
|
'post_mail', 'chat', 'post_like'
|
||||||
|
];
|
||||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -49,8 +62,9 @@ class PermissionRoles {
|
|||||||
$ret['online'] = false;
|
$ret['online'] = false;
|
||||||
$ret['perms_connect'] = [
|
$ret['perms_connect'] = [
|
||||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||||
'view_pages', 'send_stream', 'post_wall', 'post_comments',
|
'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
|
||||||
'post_mail', 'post_like' ];
|
'post_mail', 'post_like'
|
||||||
|
];
|
||||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||||
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
|
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
|
||||||
$ret['limits']['view_storage'] = PERMS_SPECIFIC;
|
$ret['limits']['view_storage'] = PERMS_SPECIFIC;
|
||||||
@@ -64,10 +78,11 @@ class PermissionRoles {
|
|||||||
$ret['online'] = false;
|
$ret['online'] = false;
|
||||||
$ret['perms_connect'] = [
|
$ret['perms_connect'] = [
|
||||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||||
'view_pages', 'post_wall', 'post_comments', 'tag_deliver',
|
'view_pages', 'view_wiki', 'post_wall', 'post_comments', 'tag_deliver',
|
||||||
'post_mail', 'post_like' , 'republish', 'chat' ];
|
'post_mail', 'post_like' , 'republish', 'chat'
|
||||||
|
];
|
||||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'forum_restricted':
|
case 'forum_restricted':
|
||||||
@@ -77,9 +92,8 @@ class PermissionRoles {
|
|||||||
$ret['online'] = false;
|
$ret['online'] = false;
|
||||||
$ret['perms_connect'] = [
|
$ret['perms_connect'] = [
|
||||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||||
'view_pages', 'post_wall', 'post_comments', 'tag_deliver',
|
'view_pages', 'view_wiki', 'post_wall', 'post_comments', 'tag_deliver',
|
||||||
'post_mail', 'post_like' , 'chat' ];
|
'post_mail', 'post_like' , 'chat' ];
|
||||||
|
|
||||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -89,17 +103,17 @@ class PermissionRoles {
|
|||||||
$ret['default_collection'] = true;
|
$ret['default_collection'] = true;
|
||||||
$ret['directory_publish'] = false;
|
$ret['directory_publish'] = false;
|
||||||
$ret['online'] = false;
|
$ret['online'] = false;
|
||||||
|
|
||||||
$ret['perms_connect'] = [
|
$ret['perms_connect'] = [
|
||||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||||
'view_pages', 'post_wall', 'post_comments',
|
'view_pages', 'view_wiki', 'post_wall', 'post_comments',
|
||||||
'post_mail', 'post_like' , 'chat' ];
|
'post_mail', 'post_like' , 'chat'
|
||||||
|
];
|
||||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||||
$ret['limits']['view_profile'] = PERMS_SPECIFIC;
|
$ret['limits']['view_profile'] = PERMS_SPECIFIC;
|
||||||
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
|
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
|
||||||
$ret['limits']['view_storage'] = PERMS_SPECIFIC;
|
$ret['limits']['view_storage'] = PERMS_SPECIFIC;
|
||||||
$ret['limits']['view_pages'] = PERMS_SPECIFIC;
|
$ret['limits']['view_pages'] = PERMS_SPECIFIC;
|
||||||
|
$ret['limits']['view_wiki'] = PERMS_SPECIFIC;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -108,12 +122,11 @@ class PermissionRoles {
|
|||||||
$ret['default_collection'] = false;
|
$ret['default_collection'] = false;
|
||||||
$ret['directory_publish'] = true;
|
$ret['directory_publish'] = true;
|
||||||
$ret['online'] = false;
|
$ret['online'] = false;
|
||||||
|
|
||||||
$ret['perms_connect'] = [
|
$ret['perms_connect'] = [
|
||||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||||
'view_pages', 'send_stream', 'post_wall', 'post_comments',
|
'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
|
||||||
'post_mail', 'post_like' , 'republish' ];
|
'post_mail', 'post_like' , 'republish'
|
||||||
|
];
|
||||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -125,9 +138,9 @@ class PermissionRoles {
|
|||||||
$ret['online'] = false;
|
$ret['online'] = false;
|
||||||
$ret['perms_connect'] = [
|
$ret['perms_connect'] = [
|
||||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||||
'view_pages', 'send_stream', 'post_wall', 'post_comments',
|
'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
|
||||||
'post_mail', 'post_like' , 'republish' ];
|
'post_mail', 'post_like' , 'republish'
|
||||||
|
];
|
||||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -137,11 +150,10 @@ class PermissionRoles {
|
|||||||
$ret['default_collection'] = false;
|
$ret['default_collection'] = false;
|
||||||
$ret['directory_publish'] = true;
|
$ret['directory_publish'] = true;
|
||||||
$ret['online'] = false;
|
$ret['online'] = false;
|
||||||
|
|
||||||
$ret['perms_connect'] = [
|
$ret['perms_connect'] = [
|
||||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||||
'view_pages', 'post_like' , 'republish' ];
|
'view_pages', 'view_wiki', 'post_like' , 'republish'
|
||||||
|
];
|
||||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -151,15 +163,16 @@ class PermissionRoles {
|
|||||||
$ret['default_collection'] = false;
|
$ret['default_collection'] = false;
|
||||||
$ret['directory_publish'] = true;
|
$ret['directory_publish'] = true;
|
||||||
$ret['online'] = false;
|
$ret['online'] = false;
|
||||||
|
|
||||||
$ret['perms_connect'] = [
|
$ret['perms_connect'] = [
|
||||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||||
'view_pages', 'write_storage', 'write_pages', 'post_wall', 'post_comments', 'tag_deliver',
|
'view_pages', 'view_wiki', 'write_storage', 'write_pages', 'post_wall', 'post_comments', 'tag_deliver',
|
||||||
'post_mail', 'post_like' , 'republish', 'chat' ];
|
'post_mail', 'post_like' , 'republish', 'chat', 'write_wiki'
|
||||||
|
];
|
||||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'custom':
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -169,16 +182,86 @@ class PermissionRoles {
|
|||||||
if($x && is_array($x) && array_key_exists($role,$x))
|
if($x && is_array($x) && array_key_exists($role,$x))
|
||||||
$ret = array_merge($ret,$x[$role]);
|
$ret = array_merge($ret,$x[$role]);
|
||||||
|
|
||||||
call_hooks('get_role_perms',$ret);
|
/**
|
||||||
|
* @hooks get_role_perms
|
||||||
|
* * \e array
|
||||||
|
*/
|
||||||
|
call_hooks('get_role_perms', $ret);
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static public function new_custom_perms($uid,$perm,$abooks) {
|
||||||
|
|
||||||
|
// set permissionlimits for this permission here, for example:
|
||||||
|
|
||||||
|
// if($perm === 'mynewperm')
|
||||||
|
// \Zotlabs\Access\PermissionLimits::Set($uid,$perm,1);
|
||||||
|
|
||||||
|
if($perm === 'view_wiki')
|
||||||
|
\Zotlabs\Access\PermissionLimits::Set($uid, $perm, PERMS_PUBLIC);
|
||||||
|
|
||||||
|
if($perm === 'write_wiki')
|
||||||
|
\Zotlabs\Access\PermissionLimits::Set($uid, $perm, PERMS_SPECIFIC);
|
||||||
|
|
||||||
|
|
||||||
|
// set autoperms here if applicable
|
||||||
|
// choices are to set to 0, 1, or the value of an existing perm
|
||||||
|
|
||||||
|
if(get_pconfig($uid,'system','autoperms')) {
|
||||||
|
|
||||||
|
$c = channelx_by_n($uid);
|
||||||
|
$value = 0;
|
||||||
|
|
||||||
|
// if($perm === 'mynewperm')
|
||||||
|
// $value = get_abconfig($uid,$c['channel_hash'],'autoperms','someexistingperm');
|
||||||
|
|
||||||
|
if($perm === 'view_wiki')
|
||||||
|
$value = get_abconfig($uid,$c['channel_hash'],'autoperms','view_pages');
|
||||||
|
|
||||||
|
if($perm === 'write_wiki')
|
||||||
|
$value = get_abconfig($uid,$c['channel_hash'],'autoperms','write_pages');
|
||||||
|
|
||||||
|
if($c) {
|
||||||
|
set_abconfig($uid,$c['channel_hash'],'autoperms',$perm,$value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now set something for all existing connections.
|
||||||
|
|
||||||
|
if($abooks) {
|
||||||
|
foreach($abooks as $ab) {
|
||||||
|
switch($perm) {
|
||||||
|
// case 'mynewperm':
|
||||||
|
// choices are to set to 1, set to 0, or clone an existing perm
|
||||||
|
// set_abconfig($uid,$ab['abook_xchan'],'my_perms',$perm,
|
||||||
|
// intval(get_abconfig($uid,$ab['abook_xchan'],'my_perms','someexistingperm')));
|
||||||
|
|
||||||
|
case 'view_wiki':
|
||||||
|
set_abconfig($uid,$ab['abook_xchan'],'my_perms',$perm,
|
||||||
|
intval(get_abconfig($uid,$ab['abook_xchan'],'my_perms','view_pages')));
|
||||||
|
|
||||||
|
case 'write_wiki':
|
||||||
|
set_abconfig($uid,$ab['abook_xchan'],'my_perms',$perm,
|
||||||
|
intval(get_abconfig($uid,$ab['abook_xchan'],'my_perms','write_pages')));
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Array with translated role names and grouping.
|
||||||
|
*
|
||||||
|
* Return an associative array with grouped role names that can be used
|
||||||
|
* to create select groups like in \e field_select_grouped.tpl.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
static public function roles() {
|
static public function roles() {
|
||||||
$roles = [
|
$roles = [
|
||||||
t('Social Networking') => [
|
t('Social Networking') => [
|
||||||
'social' => t('Social - Mostly Public'),
|
'social' => t('Social - Mostly Public'),
|
||||||
'social_restricted' => t('Social - Restricted'),
|
'social_restricted' => t('Social - Restricted'),
|
||||||
@@ -204,12 +287,9 @@ class PermissionRoles {
|
|||||||
t('Other') => [
|
t('Other') => [
|
||||||
'custom' => t('Custom/Expert Mode')
|
'custom' => t('Custom/Expert Mode')
|
||||||
]
|
]
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
return $roles;
|
return $roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,29 +1,55 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
namespace Zotlabs\Access;
|
namespace Zotlabs\Access;
|
||||||
|
|
||||||
use Zotlabs\Lib as Zlib;
|
use Zotlabs\Lib as Zlib;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Extensible permissions.
|
||||||
|
*
|
||||||
|
* To add new permissions, add to the list of $perms below, with a simple description.
|
||||||
|
*
|
||||||
|
* Also visit PermissionRoles.php and add to the $ret['perms_connect'] property for any role
|
||||||
|
* if this permission should be granted to new connections.
|
||||||
|
*
|
||||||
|
* Next look at PermissionRoles::new_custom_perms() and provide a handler for updating custom
|
||||||
|
* permission roles. You will want to set a default PermissionLimit for each channel and also
|
||||||
|
* provide a sane default for any existing connections. You may or may not wish to provide a
|
||||||
|
* default auto permission. If in doubt, leave this alone as custom permissions by definition
|
||||||
|
* are the responsibility of the channel owner to manage. You just don't want to create any
|
||||||
|
* suprises or break things so you have an opportunity to provide sane settings.
|
||||||
|
*
|
||||||
|
* Update the version here and in PermissionRoles.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Permissions with 'view' in the name are considered read permissions. Anything
|
||||||
|
* else requires authentication. Read permission limits are PERMS_PUBLIC and anything else
|
||||||
|
* is given PERMS_SPECIFIC.
|
||||||
|
*
|
||||||
|
* PermissionLimits::Std_limits() retrieves the standard limits. A permission role
|
||||||
|
* MAY alter an individual setting after retrieving the Std_limits if you require
|
||||||
|
* something different for a specific permission within the given role.
|
||||||
|
*
|
||||||
|
*/
|
||||||
class Permissions {
|
class Permissions {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extensible permissions.
|
* @brief Permissions version.
|
||||||
* To add new permissions, add to the list of $perms below, with a simple description.
|
|
||||||
* Also visit PermissionRoles.php and add to the $ret['perms_connect'] property for any role
|
|
||||||
* if this permission should be granted to new connections.
|
|
||||||
*
|
*
|
||||||
* Permissions with 'view' in the name are considered read permissions. Anything
|
* This must match the version in PermissionRoles.php before permission updates can run.
|
||||||
* else requires authentication. Read permission limits are PERMS_PUBLIC and anything else
|
|
||||||
* is given PERMS_SPECIFIC.
|
|
||||||
*
|
|
||||||
* PermissionLimits::Std_limits() retrieves the standard limits. A permission role
|
|
||||||
* MAY alter an individual setting after retrieving the Std_limits if you require
|
|
||||||
* something different for a specific permission within the given role.
|
|
||||||
*
|
*
|
||||||
|
* @return number
|
||||||
*/
|
*/
|
||||||
|
static public function version() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return an array with Permissions.
|
||||||
|
*
|
||||||
|
* @param string $filter (optional) only passed to hook permissions_list
|
||||||
|
* @return array Associative array with permissions and short description.
|
||||||
|
*/
|
||||||
static public function Perms($filter = '') {
|
static public function Perms($filter = '') {
|
||||||
|
|
||||||
$perms = [
|
$perms = [
|
||||||
@@ -34,7 +60,9 @@ class Permissions {
|
|||||||
'view_storage' => t('Can view my file storage and photos'),
|
'view_storage' => t('Can view my file storage and photos'),
|
||||||
'write_storage' => t('Can upload/modify my file storage and photos'),
|
'write_storage' => t('Can upload/modify my file storage and photos'),
|
||||||
'view_pages' => t('Can view my channel webpages'),
|
'view_pages' => t('Can view my channel webpages'),
|
||||||
|
'view_wiki' => t('Can view my wiki pages'),
|
||||||
'write_pages' => t('Can create/edit my channel webpages'),
|
'write_pages' => t('Can create/edit my channel webpages'),
|
||||||
|
'write_wiki' => t('Can write to my wiki pages'),
|
||||||
'post_wall' => t('Can post on my channel (wall) page'),
|
'post_wall' => t('Can post on my channel (wall) page'),
|
||||||
'post_comments' => t('Can comment on or like my posts'),
|
'post_comments' => t('Can comment on or like my posts'),
|
||||||
'post_mail' => t('Can send me private mail messages'),
|
'post_mail' => t('Can send me private mail messages'),
|
||||||
@@ -45,18 +73,30 @@ class Permissions {
|
|||||||
'delegate' => t('Can administer my channel')
|
'delegate' => t('Can administer my channel')
|
||||||
];
|
];
|
||||||
|
|
||||||
$x = array('permissions' => $perms, 'filter' => $filter);
|
$x = [
|
||||||
call_hooks('permissions_list',$x);
|
'permissions' => $perms,
|
||||||
return($x['permissions']);
|
'filter' => $filter
|
||||||
|
];
|
||||||
|
/**
|
||||||
|
* @hooks permissions_list
|
||||||
|
* * \e array \b permissions
|
||||||
|
* * \e string \b filter
|
||||||
|
*/
|
||||||
|
call_hooks('permissions_list', $x);
|
||||||
|
|
||||||
|
return($x['permissions']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Perms from the above list that are blocked from anonymous observers.
|
||||||
|
*
|
||||||
|
* e.g. you must be authenticated.
|
||||||
|
*
|
||||||
|
* @return array Associative array with permissions and short description.
|
||||||
|
*/
|
||||||
static public function BlockedAnonPerms() {
|
static public function BlockedAnonPerms() {
|
||||||
|
|
||||||
// Perms from the above list that are blocked from anonymous observers.
|
$res = [];
|
||||||
// e.g. you must be authenticated.
|
|
||||||
|
|
||||||
$res = array();
|
|
||||||
$perms = PermissionLimits::Std_limits();
|
$perms = PermissionLimits::Std_limits();
|
||||||
foreach($perms as $perm => $limit) {
|
foreach($perms as $perm => $limit) {
|
||||||
if($limit != PERMS_PUBLIC) {
|
if($limit != PERMS_PUBLIC) {
|
||||||
@@ -64,30 +104,71 @@ class Permissions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$x = array('permissions' => $res);
|
$x = ['permissions' => $res];
|
||||||
call_hooks('write_perms',$x);
|
/**
|
||||||
return($x['permissions']);
|
* @hooks write_perms
|
||||||
|
* * \e array \b permissions
|
||||||
|
*/
|
||||||
|
call_hooks('write_perms', $x);
|
||||||
|
|
||||||
|
return($x['permissions']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// converts [ 0 => 'view_stream', ... ]
|
/**
|
||||||
// to [ 'view_stream' => 1 ]
|
* @brief Converts indexed perms array to associative perms array.
|
||||||
// for any permissions in $arr;
|
*
|
||||||
// Undeclared permissions are set to 0
|
* Converts [ 0 => 'view_stream', ... ]
|
||||||
|
* to [ 'view_stream' => 1 ] for any permissions in $arr;
|
||||||
|
* Undeclared permissions which exist in Perms() are added and set to 0.
|
||||||
|
*
|
||||||
|
* @param array $arr
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
static public function FilledPerms($arr) {
|
static public function FilledPerms($arr) {
|
||||||
|
if(is_null($arr)) {
|
||||||
|
btlogger('FilledPerms: null');
|
||||||
|
$arr = [];
|
||||||
|
}
|
||||||
|
|
||||||
$everything = self::Perms();
|
$everything = self::Perms();
|
||||||
$ret = [];
|
$ret = [];
|
||||||
foreach($everything as $k => $v) {
|
foreach($everything as $k => $v) {
|
||||||
if(in_array($k,$arr))
|
if(in_array($k, $arr))
|
||||||
$ret[$k] = 1;
|
$ret[$k] = 1;
|
||||||
else
|
else
|
||||||
$ret[$k] = 0;
|
$ret[$k] = 0;
|
||||||
}
|
}
|
||||||
return $ret;
|
|
||||||
|
|
||||||
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert perms array to indexed array.
|
||||||
|
*
|
||||||
|
* Converts [ 'view_stream' => 1 ] for any permissions in $arr
|
||||||
|
* to [ 0 => ['name' => 'view_stream', 'value' => 1], ... ]
|
||||||
|
*
|
||||||
|
* @param array $arr associative perms array 'view_stream' => 1
|
||||||
|
* @return array Indexed array with elements that look like
|
||||||
|
* * \e string \b name the perm name (e.g. view_stream)
|
||||||
|
* * \e int \b value the value of the perm (e.g. 1)
|
||||||
|
*/
|
||||||
|
static public function OPerms($arr) {
|
||||||
|
$ret = [];
|
||||||
|
if($arr) {
|
||||||
|
foreach($arr as $k => $v) {
|
||||||
|
$ret[] = [ 'name' => $k, 'value' => $v ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param int $channel_id
|
||||||
|
* @return boolean|array
|
||||||
|
*/
|
||||||
static public function FilledAutoperms($channel_id) {
|
static public function FilledAutoperms($channel_id) {
|
||||||
if(! intval(get_pconfig($channel_id,'system','autoperms')))
|
if(! intval(get_pconfig($channel_id,'system','autoperms')))
|
||||||
return false;
|
return false;
|
||||||
@@ -98,19 +179,108 @@ class Permissions {
|
|||||||
);
|
);
|
||||||
if($r) {
|
if($r) {
|
||||||
foreach($r as $rr) {
|
foreach($r as $rr) {
|
||||||
$arr[$rr['k']] = $arr[$rr['v']];
|
$arr[$rr['k']] = intval($rr['v']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $arr;
|
return $arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function PermsCompare($p1,$p2) {
|
/**
|
||||||
|
* @brief Compares that all Permissions from $p1 exist also in $p2.
|
||||||
|
*
|
||||||
|
* @param array $p1 The perms that have to exist in $p2
|
||||||
|
* @param array $p2 The perms to compare against
|
||||||
|
* @return boolean true if all perms from $p1 exist also in $p2
|
||||||
|
*/
|
||||||
|
static public function PermsCompare($p1, $p2) {
|
||||||
foreach($p1 as $k => $v) {
|
foreach($p1 as $k => $v) {
|
||||||
if(! array_key_exists($k,$p2))
|
if(! array_key_exists($k, $p2))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if($p1[$k] != $p2[$k])
|
if($p1[$k] != $p2[$k])
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param int $channel_id A channel id
|
||||||
|
* @return array Associative array with
|
||||||
|
* * \e array \b perms Permission array
|
||||||
|
* * \e int \b automatic 0 or 1
|
||||||
|
*/
|
||||||
|
static public function connect_perms($channel_id) {
|
||||||
|
|
||||||
|
$my_perms = [];
|
||||||
|
$permcat = null;
|
||||||
|
$automatic = 0;
|
||||||
|
|
||||||
|
// 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'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
if($xx['perms_auto'])
|
||||||
|
$automatic = 1;
|
||||||
|
|
||||||
|
if((! $my_perms) && ($xx['perms_connect'])) {
|
||||||
|
$default_perms = $xx['perms_connect'];
|
||||||
|
$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) {
|
||||||
|
$automatic = 1;
|
||||||
|
$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)
|
||||||
|
);
|
||||||
|
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) {
|
||||||
|
$my_perms[$xv['k']] = intval($xv['v']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( [ 'perms' => $my_perms, 'automatic' => $automatic ] );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
14
Zotlabs/Daemon/Addon.php
Normal file
14
Zotlabs/Daemon/Addon.php
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zotlabs\Daemon;
|
||||||
|
|
||||||
|
require_once('include/zot.php');
|
||||||
|
|
||||||
|
class Addon {
|
||||||
|
|
||||||
|
static public function run($argc,$argv) {
|
||||||
|
|
||||||
|
call_hooks('daemon_addon',$argv);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
namespace Zotlabs\Daemon;
|
namespace Zotlabs\Daemon;
|
||||||
|
|
||||||
require_once('include/zot.php');
|
require_once('include/zot.php');
|
||||||
require_once('include/hubloc.php');
|
|
||||||
|
|
||||||
|
|
||||||
class Checksites {
|
class Checksites {
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ class Cron {
|
|||||||
// channels and sites that quietly vanished and prevent the directory from accumulating stale
|
// channels and sites that quietly vanished and prevent the directory from accumulating stale
|
||||||
// or dead entries.
|
// or dead entries.
|
||||||
|
|
||||||
$r = q("select channel_id from channel where channel_dirdate < %s - INTERVAL %s",
|
$r = q("select channel_id from channel where channel_dirdate < %s - INTERVAL %s and channel_removed = 0",
|
||||||
db_utcnow(),
|
db_utcnow(),
|
||||||
db_quoteinterval('30 DAY')
|
db_quoteinterval('30 DAY')
|
||||||
);
|
);
|
||||||
@@ -121,6 +121,9 @@ class Cron {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
require_once('include/attach.php');
|
||||||
|
attach_upgrade();
|
||||||
|
|
||||||
$abandon_days = intval(get_config('system','account_abandon_days'));
|
$abandon_days = intval(get_config('system','account_abandon_days'));
|
||||||
if($abandon_days < 1)
|
if($abandon_days < 1)
|
||||||
$abandon_days = 0;
|
$abandon_days = 0;
|
||||||
@@ -171,7 +174,8 @@ class Cron {
|
|||||||
|
|
||||||
// pull in some public posts
|
// pull in some public posts
|
||||||
|
|
||||||
if(! get_config('system','disable_discover_tab'))
|
$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(array('Externals'));
|
||||||
|
|
||||||
$generation = 0;
|
$generation = 0;
|
||||||
|
|||||||
@@ -38,12 +38,20 @@ class Cron_daily {
|
|||||||
db_utcnow(), db_quoteinterval('30 DAY')
|
db_utcnow(), db_quoteinterval('30 DAY')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// expire any unread notifications over a year old
|
||||||
|
|
||||||
|
q("delete from notify where seen = 0 and created < %s - INTERVAL %s",
|
||||||
|
db_utcnow(), db_quoteinterval('1 YEAR')
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
//update statistics in config
|
//update statistics in config
|
||||||
require_once('include/statistics_fns.php');
|
require_once('include/statistics_fns.php');
|
||||||
update_channels_total_stat();
|
update_channels_total_stat();
|
||||||
update_channels_active_halfyear_stat();
|
update_channels_active_halfyear_stat();
|
||||||
update_channels_active_monthly_stat();
|
update_channels_active_monthly_stat();
|
||||||
update_local_posts_stat();
|
update_local_posts_stat();
|
||||||
|
update_local_comments_stat();
|
||||||
|
|
||||||
|
|
||||||
// expire old delivery reports
|
// expire old delivery reports
|
||||||
@@ -76,12 +84,11 @@ class Cron_daily {
|
|||||||
Master::Summon(array('Expire'));
|
Master::Summon(array('Expire'));
|
||||||
Master::Summon(array('Cli_suggest'));
|
Master::Summon(array('Cli_suggest'));
|
||||||
|
|
||||||
require_once('include/hubloc.php');
|
|
||||||
remove_obsolete_hublocs();
|
remove_obsolete_hublocs();
|
||||||
|
|
||||||
call_hooks('cron_daily',datetime_convert());
|
call_hooks('cron_daily',datetime_convert());
|
||||||
|
|
||||||
set_config('system','last_expire_day',$d2);
|
set_config('system','last_expire_day',intval(datetime_convert('UTC','UTC','now','d')));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* End Cron Daily
|
* End Cron Daily
|
||||||
|
|||||||
@@ -17,11 +17,25 @@ class Cron_weekly {
|
|||||||
|
|
||||||
z_check_cert();
|
z_check_cert();
|
||||||
|
|
||||||
require_once('include/hubloc.php');
|
|
||||||
prune_hub_reinstalls();
|
prune_hub_reinstalls();
|
||||||
|
|
||||||
mark_orphan_hubsxchans();
|
mark_orphan_hubsxchans();
|
||||||
|
|
||||||
|
// Find channels that were removed in the last three weeks, but
|
||||||
|
// haven't been finally cleaned up. These should be older than 10
|
||||||
|
// days to ensure that "purgeall" messages have gone out or bounced
|
||||||
|
// or timed out.
|
||||||
|
|
||||||
|
$r = q("select channel_id from channel where channel_removed = 1 and
|
||||||
|
channel_deleted > %s - INTERVAL %s and channel_deleted < %s - INTERVAL %s",
|
||||||
|
db_utcnow(), db_quoteinterval('21 DAY'),
|
||||||
|
db_utcnow(), db_quoteinterval('10 DAY')
|
||||||
|
);
|
||||||
|
if($r) {
|
||||||
|
foreach($r as $rv) {
|
||||||
|
channel_remove_final($rv['channel_id']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// get rid of really old poco records
|
// get rid of really old poco records
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ class Deliver {
|
|||||||
remove_queue_item($r[0]['outq_hash']);
|
remove_queue_item($r[0]['outq_hash']);
|
||||||
|
|
||||||
if($dresult && is_array($dresult)) {
|
if($dresult && is_array($dresult)) {
|
||||||
|
|
||||||
|
// delivery reports for local deliveries do not require encryption
|
||||||
|
|
||||||
foreach($dresult as $xx) {
|
foreach($dresult as $xx) {
|
||||||
if(is_array($xx) && array_key_exists('message_id',$xx)) {
|
if(is_array($xx) && array_key_exists('message_id',$xx)) {
|
||||||
if(delivery_report_is_storable($xx)) {
|
if(delivery_report_is_storable($xx)) {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class Gprobe {
|
|||||||
if(! strpos($url,'@'))
|
if(! strpos($url,'@'))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
$r = q("select * from xchan where xchan_addr = '%s' limit 1",
|
$r = q("select * from hubloc where hubloc_addr = '%s' limit 1",
|
||||||
dbesc($url)
|
dbesc($url)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -21,12 +21,18 @@ class Importdoc {
|
|||||||
$files = glob("$d/$f");
|
$files = glob("$d/$f");
|
||||||
if($files) {
|
if($files) {
|
||||||
foreach($files as $fi) {
|
foreach($files as $fi) {
|
||||||
if($fi === 'doc/html')
|
if($fi === 'doc/html') {
|
||||||
continue;
|
continue;
|
||||||
if(is_dir($fi))
|
}
|
||||||
|
if(is_dir($fi)) {
|
||||||
self::update_docs_dir("$fi/*");
|
self::update_docs_dir("$fi/*");
|
||||||
else
|
}
|
||||||
store_doc_file($fi);
|
else {
|
||||||
|
// don't update media content
|
||||||
|
if(strpos(z_mime_content_type($fi),'text') === 0) {
|
||||||
|
store_doc_file($fi);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
47
Zotlabs/Daemon/Importfile.php
Normal file
47
Zotlabs/Daemon/Importfile.php
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?php /** @file */
|
||||||
|
|
||||||
|
namespace Zotlabs\Daemon;
|
||||||
|
|
||||||
|
class Importfile {
|
||||||
|
|
||||||
|
static public function run($argc,$argv){
|
||||||
|
|
||||||
|
logger('Importfile: ' . print_r($argv,true));
|
||||||
|
|
||||||
|
if($argc < 3)
|
||||||
|
return;
|
||||||
|
|
||||||
|
$channel = channelx_by_n($argv[1]);
|
||||||
|
if(! $channel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
$srcfile = $argv[2];
|
||||||
|
$folder = (($argc > 3) ? $argv[3] : '');
|
||||||
|
$dstname = (($argc > 4) ? $argv[4] : '');
|
||||||
|
|
||||||
|
$hash = random_string();
|
||||||
|
|
||||||
|
$arr = [
|
||||||
|
'src' => $srcfile,
|
||||||
|
'filename' => (($dstname) ? $dstname : basename($srcfile)),
|
||||||
|
'hash' => $hash,
|
||||||
|
'allow_cid' => $channel['channel_allow_cid'],
|
||||||
|
'allow_gid' => $channel['channel_allow_gid'],
|
||||||
|
'deny_cid' => $channel['channel_deny_cid'],
|
||||||
|
'deny_gid' => $channel['channel_deny_gid'],
|
||||||
|
'preserve_original' => true,
|
||||||
|
'replace' => true
|
||||||
|
];
|
||||||
|
|
||||||
|
if($folder)
|
||||||
|
$arr['folder'] = $folder;
|
||||||
|
|
||||||
|
attach_store($channel,$channel['channel_hash'],'import',$arr);
|
||||||
|
|
||||||
|
$sync = attach_export_data($channel,$hash);
|
||||||
|
if($sync)
|
||||||
|
build_sync_packet($channel['channel_id'],array('file' => array($sync)));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,7 +24,6 @@ class Master {
|
|||||||
static public function Release($argc,$argv) {
|
static public function Release($argc,$argv) {
|
||||||
cli_startup();
|
cli_startup();
|
||||||
logger('Master: release: ' . print_r($argv,true), LOGGER_ALL,LOG_DEBUG);
|
logger('Master: release: ' . print_r($argv,true), LOGGER_ALL,LOG_DEBUG);
|
||||||
require_once('Zotlabs/Daemon/' . $argv[0] . '.php');
|
|
||||||
$cls = '\\Zotlabs\\Daemon\\' . $argv[0];
|
$cls = '\\Zotlabs\\Daemon\\' . $argv[0];
|
||||||
$cls::run($argc,$argv);
|
$cls::run($argc,$argv);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,12 @@ namespace Zotlabs\Daemon;
|
|||||||
|
|
||||||
require_once('include/queue_fn.php');
|
require_once('include/queue_fn.php');
|
||||||
require_once('include/html2plain.php');
|
require_once('include/html2plain.php');
|
||||||
|
require_once('include/conversation.php');
|
||||||
|
require_once('include/zot.php');
|
||||||
|
require_once('include/items.php');
|
||||||
|
require_once('include/bbcode.php');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file was at one time responsible for doing all deliveries, but this caused
|
* This file was at one time responsible for doing all deliveries, but this caused
|
||||||
@@ -53,6 +59,8 @@ require_once('include/html2plain.php');
|
|||||||
*
|
*
|
||||||
* ZOT
|
* ZOT
|
||||||
* permission_create abook_id
|
* permission_create abook_id
|
||||||
|
* permission_accept abook_id
|
||||||
|
* permission_reject abook_id
|
||||||
* permission_update abook_id
|
* permission_update abook_id
|
||||||
* refresh_all channel_id
|
* refresh_all channel_id
|
||||||
* purge_all channel_id
|
* purge_all channel_id
|
||||||
@@ -63,17 +71,11 @@ require_once('include/html2plain.php');
|
|||||||
* location channel_id
|
* location channel_id
|
||||||
* request channel_id xchan_hash message_id
|
* request channel_id xchan_hash message_id
|
||||||
* rating xlink_id
|
* rating xlink_id
|
||||||
|
* keychange channel_id
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
require_once('include/zot.php');
|
|
||||||
require_once('include/queue_fn.php');
|
|
||||||
require_once('include/datetime.php');
|
|
||||||
require_once('include/items.php');
|
|
||||||
require_once('include/bbcode.php');
|
|
||||||
require_once('include/channel.php');
|
|
||||||
|
|
||||||
|
|
||||||
class Notifier {
|
class Notifier {
|
||||||
|
|
||||||
@@ -97,16 +99,6 @@ class Notifier {
|
|||||||
|
|
||||||
$deliveries = array();
|
$deliveries = array();
|
||||||
|
|
||||||
$dead_hubs = array();
|
|
||||||
|
|
||||||
$dh = q("select site_url from site where site_dead = 1");
|
|
||||||
if($dh) {
|
|
||||||
foreach($dh as $dead) {
|
|
||||||
$dead_hubs[] = $dead['site_url'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$request = false;
|
$request = false;
|
||||||
$mail = false;
|
$mail = false;
|
||||||
$top_level = false;
|
$top_level = false;
|
||||||
@@ -120,7 +112,7 @@ class Notifier {
|
|||||||
$normal_mode = false;
|
$normal_mode = false;
|
||||||
$mail = true;
|
$mail = true;
|
||||||
$private = true;
|
$private = true;
|
||||||
$message = q("SELECT * FROM `mail` WHERE `id` = %d LIMIT 1",
|
$message = q("SELECT * FROM mail WHERE id = %d LIMIT 1",
|
||||||
intval($item_id)
|
intval($item_id)
|
||||||
);
|
);
|
||||||
if(! $message) {
|
if(! $message) {
|
||||||
@@ -157,7 +149,21 @@ class Notifier {
|
|||||||
$packet_type = 'request';
|
$packet_type = 'request';
|
||||||
$normal_mode = false;
|
$normal_mode = false;
|
||||||
}
|
}
|
||||||
elseif($cmd == 'permission_update' || $cmd == 'permission_create') {
|
elseif($cmd === 'keychange') {
|
||||||
|
$channel = channelx_by_n($item_id);
|
||||||
|
$r = q("select abook_xchan from abook where abook_channel = %d",
|
||||||
|
intval($item_id)
|
||||||
|
);
|
||||||
|
if($r) {
|
||||||
|
foreach($r as $rr) {
|
||||||
|
$recipients[] = $rr['abook_xchan'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$private = false;
|
||||||
|
$packet_type = 'keychange';
|
||||||
|
$normal_mode = false;
|
||||||
|
}
|
||||||
|
elseif(in_array($cmd, [ 'permission_update', 'permission_reject', 'permission_accept', 'permission_create' ])) {
|
||||||
// Get the (single) recipient
|
// Get the (single) recipient
|
||||||
$r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_self = 0",
|
$r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_self = 0",
|
||||||
intval($item_id)
|
intval($item_id)
|
||||||
@@ -169,8 +175,12 @@ class Notifier {
|
|||||||
if($channel) {
|
if($channel) {
|
||||||
$perm_update = array('sender' => $channel, 'recipient' => $r[0], 'success' => false, 'deliveries' => '');
|
$perm_update = array('sender' => $channel, 'recipient' => $r[0], 'success' => false, 'deliveries' => '');
|
||||||
|
|
||||||
if($cmd == 'permission_create')
|
if($cmd === 'permission_create')
|
||||||
call_hooks('permissions_create',$perm_update);
|
call_hooks('permissions_create',$perm_update);
|
||||||
|
elseif($cmd === 'permission_accept')
|
||||||
|
call_hooks('permissions_accept',$perm_update);
|
||||||
|
elseif($cmd === 'permission_reject')
|
||||||
|
call_hooks('permissions_reject',$perm_update);
|
||||||
else
|
else
|
||||||
call_hooks('permissions_update',$perm_update);
|
call_hooks('permissions_update',$perm_update);
|
||||||
|
|
||||||
@@ -274,7 +284,7 @@ class Notifier {
|
|||||||
$deleted_item = true;
|
$deleted_item = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(intval($target_item['item_type']) != ITEM_TYPE_POST) {
|
if(! in_array(intval($target_item['item_type']), [ ITEM_TYPE_POST ] )) {
|
||||||
logger('notifier: target item not forwardable: type ' . $target_item['item_type'], LOGGER_DEBUG);
|
logger('notifier: target item not forwardable: type ' . $target_item['item_type'], LOGGER_DEBUG);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -282,6 +292,7 @@ class Notifier {
|
|||||||
// Check for non published items, but allow an exclusion for transmitting hidden file activities
|
// Check for non published items, but allow an exclusion for transmitting hidden file activities
|
||||||
|
|
||||||
if(intval($target_item['item_unpublished']) || intval($target_item['item_delayed']) ||
|
if(intval($target_item['item_unpublished']) || intval($target_item['item_delayed']) ||
|
||||||
|
intval($target_item['item_blocked']) ||
|
||||||
( intval($target_item['item_hidden']) && ($target_item['obj_type'] !== ACTIVITY_OBJ_FILE))) {
|
( intval($target_item['item_hidden']) && ($target_item['obj_type'] !== ACTIVITY_OBJ_FILE))) {
|
||||||
logger('notifier: target item not published, so not forwardable', LOGGER_DEBUG);
|
logger('notifier: target item not published, so not forwardable', LOGGER_DEBUG);
|
||||||
return;
|
return;
|
||||||
@@ -371,12 +382,13 @@ class Notifier {
|
|||||||
if(! $encoded_item['flags'])
|
if(! $encoded_item['flags'])
|
||||||
$encoded_item['flags'] = array();
|
$encoded_item['flags'] = array();
|
||||||
$encoded_item['flags'][] = 'relay';
|
$encoded_item['flags'][] = 'relay';
|
||||||
|
$upstream = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logger('notifier: normal distribution', LOGGER_DEBUG);
|
logger('notifier: normal distribution', LOGGER_DEBUG);
|
||||||
if($cmd === 'relay')
|
if($cmd === 'relay')
|
||||||
logger('notifier: owner relay');
|
logger('notifier: owner relay');
|
||||||
|
$upstream = false;
|
||||||
// if our parent is a tag_delivery recipient, uplink to the original author causing
|
// if our parent is a tag_delivery recipient, uplink to the original author causing
|
||||||
// a delivery fork.
|
// a delivery fork.
|
||||||
|
|
||||||
@@ -401,7 +413,6 @@ class Notifier {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$walltowall = (($top_level_post && $channel['xchan_hash'] === $target_item['author_xchan']) ? true : false);
|
$walltowall = (($top_level_post && $channel['xchan_hash'] === $target_item['author_xchan']) ? true : false);
|
||||||
@@ -415,14 +426,16 @@ class Notifier {
|
|||||||
logger('notifier: encoded item: ' . print_r($x,true), LOGGER_DATA, LOG_DEBUG);
|
logger('notifier: encoded item: ' . print_r($x,true), LOGGER_DATA, LOG_DEBUG);
|
||||||
|
|
||||||
stringify_array_elms($recipients);
|
stringify_array_elms($recipients);
|
||||||
if(! $recipients)
|
if(! $recipients) {
|
||||||
|
logger('no recipients');
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// logger('notifier: recipients: ' . print_r($recipients,true), LOGGER_NORMAL, LOG_DEBUG);
|
// logger('notifier: recipients: ' . print_r($recipients,true), LOGGER_NORMAL, LOG_DEBUG);
|
||||||
|
|
||||||
$env_recips = (($private) ? array() : null);
|
$env_recips = (($private) ? array() : null);
|
||||||
|
|
||||||
$details = q("select xchan_hash, xchan_instance_url, xchan_network, xchan_addr, xchan_guid, xchan_guid_sig from xchan where xchan_hash in (" . implode(',',$recipients) . ")");
|
$details = q("select xchan_hash, xchan_instance_url, xchan_network, xchan_addr, xchan_guid, xchan_guid_sig from xchan where xchan_hash in (" . protect_sprintf(implode(',',$recipients)) . ")");
|
||||||
|
|
||||||
|
|
||||||
$recip_list = array();
|
$recip_list = array();
|
||||||
@@ -431,39 +444,40 @@ class Notifier {
|
|||||||
foreach($details as $d) {
|
foreach($details as $d) {
|
||||||
|
|
||||||
$recip_list[] = $d['xchan_addr'] . ' (' . $d['xchan_hash'] . ')';
|
$recip_list[] = $d['xchan_addr'] . ' (' . $d['xchan_hash'] . ')';
|
||||||
if($private)
|
if($private) {
|
||||||
$env_recips[] = array('guid' => $d['xchan_guid'],'guid_sig' => $d['xchan_guid_sig'],'hash' => $d['xchan_hash']);
|
$env_recips[] = [
|
||||||
|
'guid' => $d['xchan_guid'],
|
||||||
if($d['xchan_network'] === 'mail' && $normal_mode) {
|
'guid_sig' => $d['xchan_guid_sig'],
|
||||||
$delivery_options = get_xconfig($d['xchan_hash'],'system','delivery_mode');
|
'hash' => $d['xchan_hash']
|
||||||
if(! $delivery_options)
|
];
|
||||||
format_and_send_email($channel,$d,$target_item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$narr = array(
|
$narr = [
|
||||||
'channel' => $channel,
|
'channel' => $channel,
|
||||||
'env_recips' => $env_recips,
|
'upstream' => $upstream,
|
||||||
'packet_recips' => $packet_recips,
|
'env_recips' => $env_recips,
|
||||||
'recipients' => $recipients,
|
'packet_recips' => $packet_recips,
|
||||||
'item' => $item,
|
'recipients' => $recipients,
|
||||||
'target_item' => $target_item,
|
'item' => $item,
|
||||||
|
'target_item' => $target_item,
|
||||||
|
'parent_item' => $parent_item,
|
||||||
'top_level_post' => $top_level_post,
|
'top_level_post' => $top_level_post,
|
||||||
'private' => $private,
|
'private' => $private,
|
||||||
'relay_to_owner' => $relay_to_owner,
|
'relay_to_owner' => $relay_to_owner,
|
||||||
'uplink' => $uplink,
|
'uplink' => $uplink,
|
||||||
'cmd' => $cmd,
|
'cmd' => $cmd,
|
||||||
'mail' => $mail,
|
'mail' => $mail,
|
||||||
'single' => (($cmd === 'single_mail' || $cmd === 'single_activity') ? true : false),
|
'single' => (($cmd === 'single_mail' || $cmd === 'single_activity') ? true : false),
|
||||||
'location' => $location,
|
'location' => $location,
|
||||||
'request' => $request,
|
'request' => $request,
|
||||||
'normal_mode' => $normal_mode,
|
'normal_mode' => $normal_mode,
|
||||||
'packet_type' => $packet_type,
|
'packet_type' => $packet_type,
|
||||||
'walltowall' => $walltowall,
|
'walltowall' => $walltowall,
|
||||||
'queued' => array()
|
'queued' => []
|
||||||
);
|
];
|
||||||
|
|
||||||
call_hooks('notifier_process', $narr);
|
call_hooks('notifier_process', $narr);
|
||||||
if($narr['queued']) {
|
if($narr['queued']) {
|
||||||
@@ -486,10 +500,10 @@ class Notifier {
|
|||||||
|
|
||||||
|
|
||||||
// Now we have collected recipients (except for external mentions, FIXME)
|
// Now we have collected recipients (except for external mentions, FIXME)
|
||||||
// Let's reduce this to a set of hubs.
|
// Let's reduce this to a set of hubs; checking that the site is not dead.
|
||||||
|
|
||||||
$r = q("select * from hubloc where hubloc_hash in (" . implode(',',$recipients) . ")
|
$r = q("select hubloc.*, site.site_crypto, site.site_flags from hubloc left join site on site_url = hubloc_url where hubloc_hash in (" . protect_sprintf(implode(',',$recipients)) . ")
|
||||||
and hubloc_error = 0 and hubloc_deleted = 0"
|
and hubloc_error = 0 and hubloc_deleted = 0 and ( site_dead = 0 OR site_dead is null ) "
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@@ -500,72 +514,78 @@ class Notifier {
|
|||||||
|
|
||||||
$hubs = $r;
|
$hubs = $r;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reduce the hubs to those that are unique. For zot hubs, we need to verify uniqueness by the sitekey, since it may have been
|
* Reduce the hubs to those that are unique. For zot hubs, we need to verify uniqueness by the sitekey,
|
||||||
* a re-install which has not yet been detected and pruned.
|
* since it may have been a re-install which has not yet been detected and pruned.
|
||||||
* For other networks which don't have or require sitekeys, we'll have to use the URL
|
* For other networks which don't have or require sitekeys, we'll have to use the URL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
$hublist = array(); // this provides an easily printable list for the logs
|
$hublist = []; // this provides an easily printable list for the logs
|
||||||
$dhubs = array(); // delivery hubs where we store our resulting unique array
|
$dhubs = []; // delivery hubs where we store our resulting unique array
|
||||||
$keys = array(); // array of keys to check uniquness for zot hubs
|
$keys = []; // array of keys to check uniquness for zot hubs
|
||||||
$urls = array(); // array of urls to check uniqueness of hubs from other networks
|
$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
|
||||||
|
|
||||||
foreach($hubs as $hub) {
|
foreach($hubs as $hub) {
|
||||||
if(in_array($hub['hubloc_url'],$dead_hubs)) {
|
|
||||||
logger('skipping dead hub: ' . $hub['hubloc_url'], LOGGER_DEBUG, LOG_INFO);
|
if($env_recips) {
|
||||||
continue;
|
foreach($env_recips as $er) {
|
||||||
|
if($hub['hubloc_hash'] === $er['hash']) {
|
||||||
|
if(! array_key_exists($hub['hubloc_host'] . $hub['hubloc_sitekey'], $hub_env)) {
|
||||||
|
$hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']] = [];
|
||||||
|
}
|
||||||
|
$hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']][] = $er;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if($hub['hubloc_network'] == 'zot') {
|
if($hub['hubloc_network'] == 'zot') {
|
||||||
if(! in_array($hub['hubloc_sitekey'],$keys)) {
|
if(! in_array($hub['hubloc_sitekey'],$keys)) {
|
||||||
$hublist[] = $hub['hubloc_host'];
|
$hublist[] = $hub['hubloc_host'] . ' ' . $hub['hubloc_network'];
|
||||||
$dhubs[] = $hub;
|
$dhubs[] = $hub;
|
||||||
$keys[] = $hub['hubloc_sitekey'];
|
$keys[] = $hub['hubloc_sitekey'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(! in_array($hub['hubloc_url'],$urls)) {
|
if(! in_array($hub['hubloc_url'],$urls)) {
|
||||||
$hublist[] = $hub['hubloc_host'];
|
$hublist[] = $hub['hubloc_host'] . ' ' . $hub['hubloc_network'];
|
||||||
$dhubs[] = $hub;
|
$dhubs[] = $hub;
|
||||||
$urls[] = $hub['hubloc_url'];
|
$urls[] = $hub['hubloc_url'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger('notifier: will notify/deliver to these hubs: ' . print_r($hublist,true), LOGGER_DEBUG, LOG_DEBUG);
|
logger('notifier: will notify/deliver to these hubs: ' . print_r($hublist,true), LOGGER_DEBUG, LOG_DEBUG);
|
||||||
|
|
||||||
|
|
||||||
foreach($dhubs as $hub) {
|
foreach($dhubs as $hub) {
|
||||||
|
|
||||||
if($hub['hubloc_network'] !== 'zot') {
|
if($hub['hubloc_network'] !== 'zot') {
|
||||||
|
$narr = [
|
||||||
$narr = array(
|
'channel' => $channel,
|
||||||
'channel' => $channel,
|
'upstream' => $upstream,
|
||||||
'env_recips' => $env_recips,
|
'env_recips' => $env_recips,
|
||||||
'packet_recips' => $packet_recips,
|
'packet_recips' => $packet_recips,
|
||||||
'recipients' => $recipients,
|
'recipients' => $recipients,
|
||||||
'item' => $item,
|
'item' => $item,
|
||||||
'target_item' => $target_item,
|
'target_item' => $target_item,
|
||||||
'hub' => $hub,
|
'parent_item' => $parent_item,
|
||||||
|
'hub' => $hub,
|
||||||
'top_level_post' => $top_level_post,
|
'top_level_post' => $top_level_post,
|
||||||
'private' => $private,
|
'private' => $private,
|
||||||
'relay_to_owner' => $relay_to_owner,
|
'relay_to_owner' => $relay_to_owner,
|
||||||
'uplink' => $uplink,
|
'uplink' => $uplink,
|
||||||
'cmd' => $cmd,
|
'cmd' => $cmd,
|
||||||
'mail' => $mail,
|
'mail' => $mail,
|
||||||
'single' => (($cmd === 'single_mail' || $cmd === 'single_activity') ? true : false),
|
'single' => (($cmd === 'single_mail' || $cmd === 'single_activity') ? true : false),
|
||||||
'location' => $location,
|
'location' => $location,
|
||||||
'request' => $request,
|
'request' => $request,
|
||||||
'normal_mode' => $normal_mode,
|
'normal_mode' => $normal_mode,
|
||||||
'packet_type' => $packet_type,
|
'packet_type' => $packet_type,
|
||||||
'walltowall' => $walltowall,
|
'walltowall' => $walltowall,
|
||||||
'queued' => array()
|
'queued' => []
|
||||||
);
|
];
|
||||||
|
|
||||||
|
|
||||||
call_hooks('notifier_hub',$narr);
|
call_hooks('notifier_hub',$narr);
|
||||||
@@ -578,7 +598,7 @@ class Notifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// singleton deliveries by definition 'not got zot'.
|
// singleton deliveries by definition 'not got zot'.
|
||||||
// Single deliveries are other federated networks (plugins) and we're essentially
|
// Single deliveries are other federated networks (plugins) and we're essentially
|
||||||
// delivering only to those that have this site url in their abook_instance
|
// delivering only to those that have this site url in their abook_instance
|
||||||
// and only from within a sync operation. This means if you post from a clone,
|
// and only from within a sync operation. This means if you post from a clone,
|
||||||
// and a connection is connected to one of your other clones; assuming that hub
|
// and a connection is connected to one of your other clones; assuming that hub
|
||||||
@@ -592,15 +612,21 @@ class Notifier {
|
|||||||
|
|
||||||
// default: zot protocol
|
// default: zot protocol
|
||||||
|
|
||||||
$hash = random_string();
|
$hash = random_string();
|
||||||
$packet = null;
|
$packet = null;
|
||||||
|
$pmsg = '';
|
||||||
|
|
||||||
if($packet_type === 'refresh' || $packet_type === 'purge') {
|
if($packet_type === 'refresh' || $packet_type === 'purge') {
|
||||||
$packet = zot_build_packet($channel,$packet_type,(($packet_recips) ? $packet_recips : null));
|
$packet = zot_build_packet($channel,$packet_type,(($packet_recips) ? $packet_recips : null));
|
||||||
}
|
}
|
||||||
|
if($packet_type === 'keychange') {
|
||||||
|
$packet = zot_build_packet($channel,$packet_type,(($packet_recips) ? $packet_recips : null));
|
||||||
|
$pmsg = get_pconfig($channel['channel_id'],'system','keychange');
|
||||||
|
}
|
||||||
elseif($packet_type === 'request') {
|
elseif($packet_type === 'request') {
|
||||||
$packet = zot_build_packet($channel,$packet_type,$env_recips,$hub['hubloc_sitekey'],$hash,
|
$env = (($hub_env && $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']]) ? $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']] : '');
|
||||||
array('message_id' => $request_message_id)
|
$packet = zot_build_packet($channel,$packet_type,$env,$hub['hubloc_sitekey'],$hub['site_crypto'],
|
||||||
|
$hash, array('message_id' => $request_message_id)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -610,19 +636,23 @@ class Notifier {
|
|||||||
'account_id' => $channel['channel_account_id'],
|
'account_id' => $channel['channel_account_id'],
|
||||||
'channel_id' => $channel['channel_id'],
|
'channel_id' => $channel['channel_id'],
|
||||||
'posturl' => $hub['hubloc_callback'],
|
'posturl' => $hub['hubloc_callback'],
|
||||||
'notify' => $packet
|
'notify' => $packet,
|
||||||
|
'msg' => (($pmsg) ? json_encode($pmsg) : '')
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$packet = zot_build_packet($channel,'notify',$env_recips,(($private) ? $hub['hubloc_sitekey'] : null),$hash);
|
$env = (($hub_env && $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']]) ? $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']] : '');
|
||||||
queue_insert(array(
|
$packet = zot_build_packet($channel,'notify',$env,(($private) ? $hub['hubloc_sitekey'] : null), $hub['site_crypto'],$hash);
|
||||||
'hash' => $hash,
|
queue_insert(
|
||||||
'account_id' => $target_item['aid'],
|
[
|
||||||
'channel_id' => $target_item['uid'],
|
'hash' => $hash,
|
||||||
'posturl' => $hub['hubloc_callback'],
|
'account_id' => $target_item['aid'],
|
||||||
'notify' => $packet,
|
'channel_id' => $target_item['uid'],
|
||||||
'msg' => json_encode($encoded_item)
|
'posturl' => $hub['hubloc_callback'],
|
||||||
));
|
'notify' => $packet,
|
||||||
|
'msg' => json_encode($encoded_item)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
// only create delivery reports for normal undeleted items
|
// only create delivery reports for normal undeleted items
|
||||||
if(is_array($target_item) && array_key_exists('postopts',$target_item) && (! $target_item['item_deleted']) && (! get_config('system','disable_dreport'))) {
|
if(is_array($target_item) && array_key_exists('postopts',$target_item) && (! $target_item['item_deleted']) && (! get_config('system','disable_dreport'))) {
|
||||||
@@ -643,9 +673,9 @@ class Notifier {
|
|||||||
|
|
||||||
if($normal_mode) {
|
if($normal_mode) {
|
||||||
$x = q("select * from hook where hook = 'notifier_normal'");
|
$x = q("select * from hook where hook = 'notifier_normal'");
|
||||||
if($x)
|
if($x) {
|
||||||
Master::Summon(array('Deliver_hooks',$target_item['id']));
|
Master::Summon( [ 'Deliver_hooks', $target_item['id'] ] );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($deliveries)
|
if($deliveries)
|
||||||
|
|||||||
@@ -118,13 +118,29 @@ class Onepoll {
|
|||||||
|
|
||||||
if($fetch_feed) {
|
if($fetch_feed) {
|
||||||
|
|
||||||
$feedurl = str_replace('/poco/','/zotfeed/',$contact['xchan_connurl']);
|
if(strpos($contact['xchan_connurl'],z_root()) === 0) {
|
||||||
$feedurl .= '?f=&mindate=' . urlencode($last_update);
|
// local channel - save a network fetch
|
||||||
|
$c = channelx_by_hash($contact['xchan_hash']);
|
||||||
|
if($c) {
|
||||||
|
$x = [
|
||||||
|
'success' => true,
|
||||||
|
'body' => json_encode( [
|
||||||
|
'success' => true,
|
||||||
|
'messages' => zot_feed($c['channel_id'], $importer['xchan_hash'], [ 'mindate' => $last_update ])
|
||||||
|
])
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// remote fetch
|
||||||
|
|
||||||
$x = z_fetch_url($feedurl);
|
$feedurl = str_replace('/poco/','/zotfeed/',$contact['xchan_connurl']);
|
||||||
|
$feedurl .= '?f=&mindate=' . urlencode($last_update) . '&zid=' . $importer['channel_address'] . '@' . \App::get_hostname();
|
||||||
|
$recurse = 0;
|
||||||
|
$x = z_fetch_url($feedurl, false, $recurse, [ 'session' => true ]);
|
||||||
|
}
|
||||||
|
|
||||||
logger('feed_update: ' . print_r($x,true), LOGGER_DATA);
|
logger('feed_update: ' . print_r($x,true), LOGGER_DATA);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(($x) && ($x['success'])) {
|
if(($x) && ($x['success'])) {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ class Queue {
|
|||||||
require_once('include/items.php');
|
require_once('include/items.php');
|
||||||
require_once('include/bbcode.php');
|
require_once('include/bbcode.php');
|
||||||
|
|
||||||
|
|
||||||
if(argc() > 1)
|
if(argc() > 1)
|
||||||
$queue_id = argv(1);
|
$queue_id = argv(1);
|
||||||
else
|
else
|
||||||
@@ -61,30 +62,15 @@ class Queue {
|
|||||||
// the site is permanently down, there's no reason to attempt delivery at all, or at most not more than once
|
// the site is permanently down, there's no reason to attempt delivery at all, or at most not more than once
|
||||||
// or twice a day.
|
// or twice a day.
|
||||||
|
|
||||||
// FIXME: can we sort postgres on outq_priority and maintain the 'distinct' ?
|
$r = q("SELECT * FROM outq WHERE outq_delivered = 0 and outq_scheduled < %s ",
|
||||||
// The order by max(outq_priority) might be a dodgy query because of the group by.
|
db_utcnow()
|
||||||
// The desired result is to return a sequence in the order most likely to be delivered in this run.
|
|
||||||
// If a hub has already been sitting in the queue for a few days, they should be delivered last;
|
|
||||||
// hence every failure should drop them further down the priority list.
|
|
||||||
|
|
||||||
if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
|
|
||||||
$prefix = 'DISTINCT ON (outq_posturl)';
|
|
||||||
$suffix = 'ORDER BY outq_posturl';
|
|
||||||
} else {
|
|
||||||
$prefix = '';
|
|
||||||
$suffix = 'GROUP BY outq_posturl ORDER BY max(outq_priority)';
|
|
||||||
}
|
|
||||||
$r = q("SELECT $prefix * FROM outq WHERE outq_delivered = 0 and (( outq_created > %s - INTERVAL %s and outq_updated < %s - INTERVAL %s ) OR ( outq_updated < %s - INTERVAL %s )) $suffix",
|
|
||||||
db_utcnow(), db_quoteinterval('12 HOUR'),
|
|
||||||
db_utcnow(), db_quoteinterval('15 MINUTE'),
|
|
||||||
db_utcnow(), db_quoteinterval('1 HOUR')
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if(! $r)
|
if(! $r)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach($r as $rr) {
|
foreach($r as $rv) {
|
||||||
queue_deliver($rr);
|
queue_deliver($rv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ class Ratenotif {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
$hash = random_string();
|
$hash = random_string();
|
||||||
$n = zot_build_packet($channel,'notify',null,null,$hash);
|
$n = zot_build_packet($channel,'notify',null,null,'',$hash);
|
||||||
|
|
||||||
queue_insert(array(
|
queue_insert(array(
|
||||||
'hash' => $hash,
|
'hash' => $hash,
|
||||||
@@ -88,6 +88,14 @@ class Ratenotif {
|
|||||||
'msg' => json_encode($encoded_item)
|
'msg' => json_encode($encoded_item)
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
|
$x = q("select count(outq_hash) as total from outq where outq_delivered = 0");
|
||||||
|
if(intval($x[0]['total']) > intval(get_config('system','force_queue_threshold',300))) {
|
||||||
|
logger('immediate delivery deferred.', LOGGER_DEBUG, LOG_INFO);
|
||||||
|
update_queue_item($hash);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$deliver[] = $hash;
|
$deliver[] = $hash;
|
||||||
|
|
||||||
if(count($deliver) >= $deliveries_per_process) {
|
if(count($deliver) >= $deliveries_per_process) {
|
||||||
|
|||||||
78
Zotlabs/Daemon/Thumbnail.php
Normal file
78
Zotlabs/Daemon/Thumbnail.php
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<?php /** @file */
|
||||||
|
|
||||||
|
namespace Zotlabs\Daemon;
|
||||||
|
|
||||||
|
|
||||||
|
class Thumbnail {
|
||||||
|
|
||||||
|
static public function run($argc,$argv) {
|
||||||
|
|
||||||
|
if(! $argc == 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
$c = q("select * from attach where hash = '%s' ",
|
||||||
|
dbesc($argv[1])
|
||||||
|
);
|
||||||
|
|
||||||
|
if(! $c)
|
||||||
|
return;
|
||||||
|
|
||||||
|
$attach = $c[0];
|
||||||
|
|
||||||
|
$preview_style = intval(get_config('system','thumbnail_security',0));
|
||||||
|
$preview_width = intval(get_config('system','thumbnail_width',300));
|
||||||
|
$preview_height = intval(get_config('system','thumbnail_height',300));
|
||||||
|
|
||||||
|
$p = [
|
||||||
|
'attach' => $attach,
|
||||||
|
'preview_style' => $preview_style,
|
||||||
|
'preview_width' => $preview_width,
|
||||||
|
'preview_height' => $preview_height,
|
||||||
|
'thumbnail' => null
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hooks thumbnail
|
||||||
|
* * \e array \b attach
|
||||||
|
* * \e int \b preview_style
|
||||||
|
* * \e int \b preview_width
|
||||||
|
* * \e int \b preview_height
|
||||||
|
* * \e string \b thumbnail
|
||||||
|
*/
|
||||||
|
|
||||||
|
call_hooks('thumbnail',$p);
|
||||||
|
if($p['thumbnail']) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$default_controller = null;
|
||||||
|
|
||||||
|
$files = glob('Zotlabs/Thumbs/*.php');
|
||||||
|
if($files) {
|
||||||
|
foreach($files as $f) {
|
||||||
|
$clsname = '\\Zotlabs\\Thumbs\\' . ucfirst(basename($f,'.php'));
|
||||||
|
if(class_exists($clsname)) {
|
||||||
|
$x = new $clsname();
|
||||||
|
if(method_exists($x,'Match')) {
|
||||||
|
$matched = $x->Match($attach['filetype']);
|
||||||
|
if($matched) {
|
||||||
|
$x->Thumb($attach,$preview_style,$preview_width,$preview_height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(method_exists($x,'MatchDefault')) {
|
||||||
|
$default_matched = $x->MatchDefault(substr($attach['filetype'],0,strpos($attach['filetype'],'/')));
|
||||||
|
if($default_matched) {
|
||||||
|
$default_controller = $x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(($default_controller)
|
||||||
|
&& ((! file_exists(dbunescbin($attach['content']) . '.thumb'))
|
||||||
|
|| (filectime(dbunescbin($attach['content']) . 'thumb') < (time() - 60)))) {
|
||||||
|
$default_controller->Thumb($attach,$preview_style,$preview_width,$preview_height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,12 @@
|
|||||||
|
|
||||||
namespace Zotlabs\Extend;
|
namespace Zotlabs\Extend;
|
||||||
|
|
||||||
|
use App;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Hook class.
|
||||||
|
*
|
||||||
|
*/
|
||||||
class Hook {
|
class Hook {
|
||||||
|
|
||||||
static public function register($hook,$file,$function,$version = 1,$priority = 0) {
|
static public function register($hook,$file,$function,$version = 1,$priority = 0) {
|
||||||
@@ -10,7 +15,7 @@ class Hook {
|
|||||||
$function = serialize($function);
|
$function = serialize($function);
|
||||||
}
|
}
|
||||||
|
|
||||||
$r = q("SELECT * FROM `hook` WHERE `hook` = '%s' AND `file` = '%s' AND `fn` = '%s' and priority = %d and hook_version = %d LIMIT 1",
|
$r = q("SELECT * FROM hook WHERE hook = '%s' AND file = '%s' AND fn = '%s' and priority = %d and hook_version = %d LIMIT 1",
|
||||||
dbesc($hook),
|
dbesc($hook),
|
||||||
dbesc($file),
|
dbesc($file),
|
||||||
dbesc($function),
|
dbesc($function),
|
||||||
@@ -23,13 +28,13 @@ class Hook {
|
|||||||
// To aid in upgrade and transition, remove old settings for any registered hooks that match in all respects except
|
// To aid in upgrade and transition, remove old settings for any registered hooks that match in all respects except
|
||||||
// for priority or hook_version
|
// for priority or hook_version
|
||||||
|
|
||||||
$r = q("DELETE FROM `hook` where `hook` = '%s' and `file` = '%s' and `fn` = '%s'",
|
$r = q("DELETE FROM hook where hook = '%s' and file = '%s' and fn = '%s'",
|
||||||
dbesc($hook),
|
dbesc($hook),
|
||||||
dbesc($file),
|
dbesc($file),
|
||||||
dbesc($function)
|
dbesc($function)
|
||||||
);
|
);
|
||||||
|
|
||||||
$r = q("INSERT INTO `hook` (`hook`, `file`, `fn`, `priority`, `hook_version`) VALUES ( '%s', '%s', '%s', %d, %d )",
|
$r = q("INSERT INTO hook (hook, file, fn, priority, hook_version) VALUES ( '%s', '%s', '%s', %d, %d )",
|
||||||
dbesc($hook),
|
dbesc($hook),
|
||||||
dbesc($file),
|
dbesc($file),
|
||||||
dbesc($function),
|
dbesc($function),
|
||||||
@@ -40,11 +45,20 @@ class Hook {
|
|||||||
return $r;
|
return $r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static public function register_array($file,$arr) {
|
||||||
|
if($arr) {
|
||||||
|
foreach($arr as $k => $v) {
|
||||||
|
self::register($k,$file,$v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static public function unregister($hook,$file,$function,$version = 1,$priority = 0) {
|
static public function unregister($hook,$file,$function,$version = 1,$priority = 0) {
|
||||||
if(is_array($function)) {
|
if(is_array($function)) {
|
||||||
$function = serialize($function);
|
$function = serialize($function);
|
||||||
}
|
}
|
||||||
$r = q("DELETE FROM hook WHERE hook = '%s' AND `file` = '%s' AND `fn` = '%s' and priority = %d and hook_version = %d",
|
$r = q("DELETE FROM hook WHERE hook = '%s' AND file = '%s' AND fn = '%s' and priority = %d and hook_version = %d",
|
||||||
dbesc($hook),
|
dbesc($hook),
|
||||||
dbesc($file),
|
dbesc($file),
|
||||||
dbesc($function),
|
dbesc($function),
|
||||||
@@ -55,19 +69,21 @@ class Hook {
|
|||||||
return $r;
|
return $r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// unregister all hooks with this file component.
|
/**
|
||||||
// Useful for addon upgrades where you want to clean out old interfaces.
|
* @brief Unregister all hooks with this file component.
|
||||||
|
*
|
||||||
|
* Useful for addon upgrades where you want to clean out old interfaces.
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
*/
|
||||||
static public function unregister_by_file($file) {
|
static public function unregister_by_file($file) {
|
||||||
|
$r = q("DELETE FROM hook WHERE file = '%s' ",
|
||||||
$r = q("DELETE FROM hook WHERE `file` = '%s' ",
|
|
||||||
dbesc($file)
|
dbesc($file)
|
||||||
);
|
);
|
||||||
|
|
||||||
return $r;
|
return $r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Inserts a hook into a page request.
|
* @brief Inserts a hook into a page request.
|
||||||
*
|
*
|
||||||
@@ -89,7 +105,6 @@ class Hook {
|
|||||||
* @param int $priority
|
* @param int $priority
|
||||||
* currently not implemented in this function, would require the hook array to be resorted
|
* currently not implemented in this function, would require the hook array to be resorted
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static public function insert($hook, $fn, $version = 0, $priority = 0) {
|
static public function insert($hook, $fn, $version = 0, $priority = 0) {
|
||||||
if(is_array($fn)) {
|
if(is_array($fn)) {
|
||||||
$fn = serialize($fn);
|
$fn = serialize($fn);
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ class AConfig {
|
|||||||
return XConfig::Load('a_' . $account_id);
|
return XConfig::Load('a_' . $account_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function Get($account_id,$family,$key) {
|
static public function Get($account_id,$family,$key,$default = false) {
|
||||||
return XConfig::Get('a_' . $account_id,$family,$key);
|
return XConfig::Get('a_' . $account_id,$family,$key, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function Set($account_id,$family,$key,$value) {
|
static public function Set($account_id,$family,$key,$value) {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class AbConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static public function Get($chan,$xhash,$family,$key) {
|
static public function Get($chan,$xhash,$family,$key, $default = false) {
|
||||||
$r = q("select * from abconfig where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' limit 1",
|
$r = q("select * from abconfig where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' limit 1",
|
||||||
intval($chan),
|
intval($chan),
|
||||||
dbesc($xhash),
|
dbesc($xhash),
|
||||||
@@ -26,7 +26,7 @@ class AbConfig {
|
|||||||
if($r) {
|
if($r) {
|
||||||
return ((preg_match('|^a:[0-9]+:{.*}$|s', $r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']);
|
return ((preg_match('|^a:[0-9]+:{.*}$|s', $r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']);
|
||||||
}
|
}
|
||||||
return false;
|
return $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
273
Zotlabs/Lib/ActivityStreams.php
Normal file
273
Zotlabs/Lib/ActivityStreams.php
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zotlabs\Lib;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ActivityStreams class.
|
||||||
|
*
|
||||||
|
* Parses an ActivityStream JSON string.
|
||||||
|
*/
|
||||||
|
class ActivityStreams {
|
||||||
|
|
||||||
|
public $data;
|
||||||
|
public $valid = false;
|
||||||
|
public $id = '';
|
||||||
|
public $type = '';
|
||||||
|
public $actor = null;
|
||||||
|
public $obj = null;
|
||||||
|
public $tgt = null;
|
||||||
|
public $origin = null;
|
||||||
|
public $owner = null;
|
||||||
|
public $signer = null;
|
||||||
|
public $ldsig = null;
|
||||||
|
public $sigok = false;
|
||||||
|
public $recips = null;
|
||||||
|
public $raw_recips = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor for ActivityStreams.
|
||||||
|
*
|
||||||
|
* Takes a JSON string as parameter, decodes it and sets up this object.
|
||||||
|
*
|
||||||
|
* @param string $string
|
||||||
|
*/
|
||||||
|
function __construct($string) {
|
||||||
|
|
||||||
|
$this->data = json_decode($string, true);
|
||||||
|
if($this->data) {
|
||||||
|
$this->valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($this->is_valid()) {
|
||||||
|
$this->id = $this->get_property_obj('id');
|
||||||
|
$this->type = $this->get_primary_type();
|
||||||
|
$this->actor = $this->get_compound_property('actor');
|
||||||
|
$this->obj = $this->get_compound_property('object');
|
||||||
|
$this->tgt = $this->get_compound_property('target');
|
||||||
|
$this->origin = $this->get_compound_property('origin');
|
||||||
|
$this->recips = $this->collect_recips();
|
||||||
|
|
||||||
|
$this->ldsig = $this->get_compound_property('signature');
|
||||||
|
if($this->ldsig) {
|
||||||
|
$this->signer = $this->get_compound_property('creator',$this->ldsig);
|
||||||
|
if($this->signer && $this->signer['publicKey'] && $this->signer['publicKey']['publicKeyPem']) {
|
||||||
|
$this->sigok = \Zotlabs\Lib\LDSignatures::verify($this->data,$this->signer['publicKey']['publicKeyPem']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(($this->type === 'Note') && (! $this->obj)) {
|
||||||
|
$this->obj = $this->data;
|
||||||
|
$this->type = 'Create';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return if instantiated ActivityStream is valid.
|
||||||
|
*
|
||||||
|
* @return boolean Return true if the JSON string could be decoded.
|
||||||
|
*/
|
||||||
|
function is_valid() {
|
||||||
|
return $this->valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_recips($arr) {
|
||||||
|
$this->saved_recips = $arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Collects all recipients.
|
||||||
|
*
|
||||||
|
* @param string $base
|
||||||
|
* @param string $namespace (optional) default empty
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function collect_recips($base = '', $namespace = '') {
|
||||||
|
$x = [];
|
||||||
|
$fields = [ 'to', 'cc', 'bto', 'bcc', 'audience'];
|
||||||
|
foreach($fields as $f) {
|
||||||
|
$y = $this->get_compound_property($f, $base, $namespace);
|
||||||
|
if($y) {
|
||||||
|
$x = array_merge($x, $y);
|
||||||
|
if(! is_array($this->raw_recips))
|
||||||
|
$this->raw_recips = [];
|
||||||
|
|
||||||
|
$this->raw_recips[$f] = $x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// not yet ready for prime time
|
||||||
|
// $x = $this->expand($x,$base,$namespace);
|
||||||
|
return $x;
|
||||||
|
}
|
||||||
|
|
||||||
|
function expand($arr,$base = '',$namespace = '') {
|
||||||
|
$ret = [];
|
||||||
|
|
||||||
|
// right now use a hardwired recursion depth of 5
|
||||||
|
|
||||||
|
for($z = 0; $z < 5; $z ++) {
|
||||||
|
if(is_array($arr) && $arr) {
|
||||||
|
foreach($arr as $a) {
|
||||||
|
if(is_array($a)) {
|
||||||
|
$ret[] = $a;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$x = $this->get_compound_property($a,$base,$namespace);
|
||||||
|
if($x) {
|
||||||
|
$ret = array_merge($ret,$x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @fixme de-duplicate
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param array $base
|
||||||
|
* @param string $namespace if not set return empty string
|
||||||
|
* @return string|NULL
|
||||||
|
*/
|
||||||
|
function get_namespace($base, $namespace) {
|
||||||
|
|
||||||
|
if(! $namespace)
|
||||||
|
return '';
|
||||||
|
|
||||||
|
$key = null;
|
||||||
|
|
||||||
|
foreach( [ $this->data, $base ] as $b ) {
|
||||||
|
if(! $b)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(array_key_exists('@context', $b)) {
|
||||||
|
if(is_array($b['@context'])) {
|
||||||
|
foreach($b['@context'] as $ns) {
|
||||||
|
if(is_array($ns)) {
|
||||||
|
foreach($ns as $k => $v) {
|
||||||
|
if($namespace === $v)
|
||||||
|
$key = $k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if($namespace === $ns) {
|
||||||
|
$key = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if($namespace === $b['@context']) {
|
||||||
|
$key = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param string $property
|
||||||
|
* @param array $base (optional)
|
||||||
|
* @param string $namespace (optional) default empty
|
||||||
|
* @return NULL|mixed
|
||||||
|
*/
|
||||||
|
function get_property_obj($property, $base = '', $namespace = '') {
|
||||||
|
$prefix = $this->get_namespace($base, $namespace);
|
||||||
|
if($prefix === null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
$base = (($base) ? $base : $this->data);
|
||||||
|
$propname = (($prefix) ? $prefix . ':' : '') . $property;
|
||||||
|
|
||||||
|
return ((array_key_exists($propname, $base)) ? $base[$propname] : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fetches a property from an URL.
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @return NULL|mixed
|
||||||
|
*/
|
||||||
|
function fetch_property($url) {
|
||||||
|
$redirects = 0;
|
||||||
|
if(! check_siteallowed($url)) {
|
||||||
|
logger('blacklisted: ' . $url);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$x = z_fetch_url($url, true, $redirects,
|
||||||
|
['headers' => [ 'Accept: application/ld+json; profile="https://www.w3.org/ns/activitystreams", application/activity+json' ]]);
|
||||||
|
if($x['success'])
|
||||||
|
return json_decode($x['body'], true);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param string $property
|
||||||
|
* @param array $base
|
||||||
|
* @param string $namespace (optional) default empty
|
||||||
|
* @return NULL|mixed
|
||||||
|
*/
|
||||||
|
function get_compound_property($property, $base = '', $namespace = '') {
|
||||||
|
$x = $this->get_property_obj($property, $base, $namespace);
|
||||||
|
if($this->is_url($x)) {
|
||||||
|
$x = $this->fetch_property($x);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if string starts with http.
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
function is_url($url) {
|
||||||
|
if(($url) && (! is_array($url)) && (strpos($url, 'http') === 0)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the type property.
|
||||||
|
*
|
||||||
|
* @param array $base
|
||||||
|
* @param string $namespace (optional) default empty
|
||||||
|
* @return NULL|mixed
|
||||||
|
*/
|
||||||
|
function get_primary_type($base = '', $namespace = '') {
|
||||||
|
if(! $base)
|
||||||
|
$base = $this->data;
|
||||||
|
|
||||||
|
$x = $this->get_property_obj('type', $base, $namespace);
|
||||||
|
if(is_array($x)) {
|
||||||
|
foreach($x as $y) {
|
||||||
|
if(strpos($y, ':') === false) {
|
||||||
|
return $y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $x;
|
||||||
|
}
|
||||||
|
|
||||||
|
function debug() {
|
||||||
|
$x = var_export($this, true);
|
||||||
|
return $x;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -34,10 +34,11 @@ class Apps {
|
|||||||
if($files) {
|
if($files) {
|
||||||
foreach($files as $f) {
|
foreach($files as $f) {
|
||||||
$path = explode('/',$f);
|
$path = explode('/',$f);
|
||||||
$plugin = $path[1];
|
$plugin = trim($path[1]);
|
||||||
if(plugin_is_installed($plugin)) {
|
if(plugin_is_installed($plugin)) {
|
||||||
$x = self::parse_app_description($f,$translate);
|
$x = self::parse_app_description($f,$translate);
|
||||||
if($x) {
|
if($x) {
|
||||||
|
$x['plugin'] = $plugin;
|
||||||
$ret[] = $x;
|
$ret[] = $x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,7 +55,6 @@ class Apps {
|
|||||||
return;
|
return;
|
||||||
$apps = self::get_system_apps(false);
|
$apps = self::get_system_apps(false);
|
||||||
|
|
||||||
|
|
||||||
self::$installed_system_apps = q("select * from app where app_system = 1 and app_channel = %d",
|
self::$installed_system_apps = q("select * from app where app_system = 1 and app_channel = %d",
|
||||||
intval(local_channel())
|
intval(local_channel())
|
||||||
);
|
);
|
||||||
@@ -68,7 +68,7 @@ class Apps {
|
|||||||
if($id !== true) {
|
if($id !== true) {
|
||||||
// if we already installed this app, but it changed, preserve any categories we created
|
// if we already installed this app, but it changed, preserve any categories we created
|
||||||
$s = '';
|
$s = '';
|
||||||
$r = q("select * from term where otype = %d and oid = d",
|
$r = q("select * from term where otype = %d and oid = %d",
|
||||||
intval(TERM_OBJ_APP),
|
intval(TERM_OBJ_APP),
|
||||||
intval($id)
|
intval($id)
|
||||||
);
|
);
|
||||||
@@ -102,11 +102,13 @@ class Apps {
|
|||||||
foreach(self::$installed_system_apps as $iapp) {
|
foreach(self::$installed_system_apps as $iapp) {
|
||||||
if($iapp['app_id'] == hash('whirlpool',$app['name'])) {
|
if($iapp['app_id'] == hash('whirlpool',$app['name'])) {
|
||||||
$notfound = false;
|
$notfound = false;
|
||||||
if($iapp['app_version'] != $app['version']) {
|
if(($iapp['app_version'] != $app['version'])
|
||||||
|
|| ($app['plugin'] && (! $iapp['app_plugin']))) {
|
||||||
return intval($iapp['app_id']);
|
return intval($iapp['app_id']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $notfound;
|
return $notfound;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,8 +146,11 @@ class Apps {
|
|||||||
$ret['type'] = 'system';
|
$ret['type'] = 'system';
|
||||||
|
|
||||||
foreach($ret as $k => $v) {
|
foreach($ret as $k => $v) {
|
||||||
if(strpos($v,'http') === 0)
|
if(strpos($v,'http') === 0) {
|
||||||
$ret[$k] = zid($v);
|
if(! (local_channel() && strpos($v,z_root()) === 0)) {
|
||||||
|
$ret[$k] = zid($v);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(array_key_exists('desc',$ret))
|
if(array_key_exists('desc',$ret))
|
||||||
@@ -157,11 +162,21 @@ class Apps {
|
|||||||
if(array_key_exists('version',$ret))
|
if(array_key_exists('version',$ret))
|
||||||
$ret['version'] = str_replace(array('\'','"'),array(''','&dquot;'),$ret['version']);
|
$ret['version'] = str_replace(array('\'','"'),array(''','&dquot;'),$ret['version']);
|
||||||
|
|
||||||
|
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)) {
|
||||||
$requires = explode(',',$ret['requires']);
|
$requires = explode(',',$ret['requires']);
|
||||||
foreach($requires as $require) {
|
foreach($requires as $require) {
|
||||||
$require = trim(strtolower($require));
|
$require = trim(strtolower($require));
|
||||||
|
$config = false;
|
||||||
|
|
||||||
|
if(substr($require, 0, 7) == 'config:') {
|
||||||
|
$config = true;
|
||||||
|
$require = ltrim($require, 'config:');
|
||||||
|
$require = explode('=', $require);
|
||||||
|
}
|
||||||
|
|
||||||
switch($require) {
|
switch($require) {
|
||||||
case 'nologin':
|
case 'nologin':
|
||||||
if(local_channel())
|
if(local_channel())
|
||||||
@@ -184,10 +199,13 @@ class Apps {
|
|||||||
unset($ret);
|
unset($ret);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if(! (local_channel() && feature_enabled(local_channel(),$require)))
|
if($config)
|
||||||
|
$unset = ((get_config('system', $require[0]) == $require[1]) ? false : true);
|
||||||
|
else
|
||||||
|
$unset = ((local_channel() && feature_enabled(local_channel(),$require)) ? false : true);
|
||||||
|
if($unset)
|
||||||
unset($ret);
|
unset($ret);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -202,8 +220,10 @@ class Apps {
|
|||||||
|
|
||||||
static public function translate_system_apps(&$arr) {
|
static public function translate_system_apps(&$arr) {
|
||||||
$apps = array(
|
$apps = array(
|
||||||
'Site Admin' => t('Site Admin'),
|
'Apps' => t('Apps'),
|
||||||
'Bug Report' => t('Bug Report'),
|
'Cards' => t('Cards'),
|
||||||
|
'Admin' => t('Site Admin'),
|
||||||
|
'Report Bug' => t('Report Bug'),
|
||||||
'View Bookmarks' => t('View Bookmarks'),
|
'View Bookmarks' => t('View Bookmarks'),
|
||||||
'My Chatrooms' => t('My Chatrooms'),
|
'My Chatrooms' => t('My Chatrooms'),
|
||||||
'Connections' => t('Connections'),
|
'Connections' => t('Connections'),
|
||||||
@@ -212,7 +232,7 @@ class Apps {
|
|||||||
'Suggest Channels' => t('Suggest Channels'),
|
'Suggest Channels' => t('Suggest Channels'),
|
||||||
'Login' => t('Login'),
|
'Login' => t('Login'),
|
||||||
'Channel Manager' => t('Channel Manager'),
|
'Channel Manager' => t('Channel Manager'),
|
||||||
'Grid' => t('Grid'),
|
'Grid' => t('Activity'),
|
||||||
'Settings' => t('Settings'),
|
'Settings' => t('Settings'),
|
||||||
'Files' => t('Files'),
|
'Files' => t('Files'),
|
||||||
'Webpages' => t('Webpages'),
|
'Webpages' => t('Webpages'),
|
||||||
@@ -238,8 +258,18 @@ class Apps {
|
|||||||
'Profile Photo' => t('Profile Photo')
|
'Profile Photo' => t('Profile Photo')
|
||||||
);
|
);
|
||||||
|
|
||||||
if(array_key_exists($arr['name'],$apps))
|
if(array_key_exists('name',$arr)) {
|
||||||
$arr['name'] = $apps[$arr['name']];
|
if(array_key_exists($arr['name'],$apps)) {
|
||||||
|
$arr['name'] = $apps[$arr['name']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for($x = 0; $x < count($arr); $x++) {
|
||||||
|
if(array_key_exists($arr[$x]['name'],$apps)) {
|
||||||
|
$arr[$x]['name'] = $apps[$arr[$x]['name']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,6 +285,7 @@ class Apps {
|
|||||||
* list: normal mode for viewing an app on the app page
|
* list: normal mode for viewing an app on the app page
|
||||||
* no buttons are shown
|
* no buttons are shown
|
||||||
* edit: viewing the app page in editing mode provides a delete button
|
* edit: viewing the app page in editing mode provides a delete button
|
||||||
|
* nav: render apps for app-bin
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$installed = false;
|
$installed = false;
|
||||||
@@ -267,21 +298,36 @@ class Apps {
|
|||||||
|
|
||||||
self::translate_system_apps($papp);
|
self::translate_system_apps($papp);
|
||||||
|
|
||||||
|
if(trim($papp['plugin']) && (! plugin_is_installed(trim($papp['plugin']))))
|
||||||
|
return '';
|
||||||
|
|
||||||
$papp['papp'] = self::papp_encode($papp);
|
$papp['papp'] = self::papp_encode($papp);
|
||||||
|
|
||||||
if(! strstr($papp['url'],'://'))
|
if(! strstr($papp['url'],'://'))
|
||||||
$papp['url'] = z_root() . ((strpos($papp['url'],'/') === 0) ? '' : '/') . $papp['url'];
|
$papp['url'] = z_root() . ((strpos($papp['url'],'/') === 0) ? '' : '/') . $papp['url'];
|
||||||
|
|
||||||
foreach($papp as $k => $v) {
|
foreach($papp as $k => $v) {
|
||||||
if(strpos($v,'http') === 0 && $k != 'papp')
|
if(strpos($v,'http') === 0 && $k != 'papp') {
|
||||||
$papp[$k] = zid($v);
|
if(! (local_channel() && strpos($v,z_root()) === 0)) {
|
||||||
|
$papp[$k] = zid($v);
|
||||||
|
}
|
||||||
|
}
|
||||||
if($k === 'desc')
|
if($k === 'desc')
|
||||||
$papp['desc'] = str_replace(array('\'','"'),array(''','&dquot;'),$papp['desc']);
|
$papp['desc'] = str_replace(array('\'','"'),array(''','&dquot;'),$papp['desc']);
|
||||||
|
|
||||||
if($k === 'requires') {
|
if($k === 'requires') {
|
||||||
$requires = explode(',',$v);
|
$requires = explode(',',$v);
|
||||||
|
|
||||||
foreach($requires as $require) {
|
foreach($requires as $require) {
|
||||||
$require = trim(strtolower($require));
|
$require = trim(strtolower($require));
|
||||||
|
$config = false;
|
||||||
|
|
||||||
|
if(substr($require, 0, 7) == 'config:') {
|
||||||
|
$config = true;
|
||||||
|
$require = ltrim($require, 'config:');
|
||||||
|
$require = explode('=', $require);
|
||||||
|
}
|
||||||
|
|
||||||
switch($require) {
|
switch($require) {
|
||||||
case 'nologin':
|
case 'nologin':
|
||||||
if(local_channel())
|
if(local_channel())
|
||||||
@@ -305,10 +351,13 @@ class Apps {
|
|||||||
return '';
|
return '';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if(! (local_channel() && feature_enabled(local_channel(),$require)))
|
if($config)
|
||||||
|
$unset = ((get_config('system', $require[0]) === $require[1]) ? false : true);
|
||||||
|
else
|
||||||
|
$unset = ((local_channel() && feature_enabled(local_channel(),$require)) ? false : true);
|
||||||
|
if($unset)
|
||||||
return '';
|
return '';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -332,14 +381,35 @@ class Apps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$install_action = (($installed) ? t('Update') : t('Install'));
|
$install_action = (($installed) ? t('Update') : t('Install'));
|
||||||
|
$icon = ((strpos($papp['photo'],'icon:') === 0) ? substr($papp['photo'],5) : '');
|
||||||
|
|
||||||
|
if($mode === 'navbar') {
|
||||||
|
return replace_macros(get_markup_template('app_nav.tpl'),array(
|
||||||
|
'$app' => $papp,
|
||||||
|
'$icon' => $icon,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
return replace_macros(get_markup_template('app.tpl'),array(
|
return replace_macros(get_markup_template('app.tpl'),array(
|
||||||
'$app' => $papp,
|
'$app' => $papp,
|
||||||
|
'$icon' => $icon,
|
||||||
'$hosturl' => $hosturl,
|
'$hosturl' => $hosturl,
|
||||||
'$purchase' => (($papp['page'] && (! $installed)) ? t('Purchase') : ''),
|
'$purchase' => (($papp['page'] && (! $installed)) ? t('Purchase') : ''),
|
||||||
'$install' => (($hosturl && $mode == 'view') ? $install_action : ''),
|
'$install' => (($hosturl && $mode == 'view') ? $install_action : ''),
|
||||||
'$edit' => ((local_channel() && $installed && $mode == 'edit') ? t('Edit') : ''),
|
'$edit' => ((local_channel() && $installed && $mode == 'edit') ? t('Edit') : ''),
|
||||||
'$delete' => ((local_channel() && $installed && $mode == 'edit') ? t('Delete') : '')
|
'$delete' => ((local_channel() && $installed && $mode == 'edit') ? t('Delete') : ''),
|
||||||
|
'$undelete' => ((local_channel() && $installed && $mode == 'edit') ? t('Undelete') : ''),
|
||||||
|
'$deleted' => $papp['deleted'],
|
||||||
|
'$feature' => (($papp['embed']) ? false : true),
|
||||||
|
'$pin' => (($papp['embed']) ? false : true),
|
||||||
|
'$featured' => ((strpos($papp['categories'], 'nav_featured_app') === false) ? false : true),
|
||||||
|
'$pinned' => ((strpos($papp['categories'], 'nav_pinned_app') === false) ? false : true),
|
||||||
|
'$navapps' => (($mode == 'nav') ? true : false),
|
||||||
|
'$order' => (($mode == 'nav-order') ? true : false),
|
||||||
|
'$add' => t('Add to app-tray'),
|
||||||
|
'$remove' => t('Remove from app-tray'),
|
||||||
|
'$add_nav' => t('Pin to navbar'),
|
||||||
|
'$remove_nav' => t('Unpin from navbar')
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,7 +429,7 @@ class Apps {
|
|||||||
if($r) {
|
if($r) {
|
||||||
if(! $r[0]['app_system']) {
|
if(! $r[0]['app_system']) {
|
||||||
if($app['categories'] && (! $app['term'])) {
|
if($app['categories'] && (! $app['term'])) {
|
||||||
$r[0]['term'] = q("select * from term where otype = %d and oid = d",
|
$r[0]['term'] = q("select * from term where otype = %d and oid = %d",
|
||||||
intval(TERM_OBJ_APP),
|
intval(TERM_OBJ_APP),
|
||||||
intval($r[0]['id'])
|
intval($r[0]['id'])
|
||||||
);
|
);
|
||||||
@@ -382,36 +452,84 @@ class Apps {
|
|||||||
intval($uid)
|
intval($uid)
|
||||||
);
|
);
|
||||||
if($x) {
|
if($x) {
|
||||||
$x[0]['app_deleted'] = 1;
|
if(! intval($x[0]['app_deleted'])) {
|
||||||
q("delete from term where otype = %d and oid = %d",
|
$x[0]['app_deleted'] = 1;
|
||||||
intval(TERM_OBJ_APP),
|
q("delete from term where otype = %d and oid = %d",
|
||||||
intval($x[0]['id'])
|
intval(TERM_OBJ_APP),
|
||||||
);
|
intval($x[0]['id'])
|
||||||
if($x[0]['app_system']) {
|
|
||||||
$r = q("update app set app_deleted = 1 where app_id = '%s' and app_channel = %d",
|
|
||||||
dbesc($app['guid']),
|
|
||||||
intval($uid)
|
|
||||||
);
|
);
|
||||||
|
if($x[0]['app_system']) {
|
||||||
|
$r = q("update app set app_deleted = 1 where app_id = '%s' and app_channel = %d",
|
||||||
|
dbesc($app['guid']),
|
||||||
|
intval($uid)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$r = q("delete from app where app_id = '%s' and app_channel = %d",
|
||||||
|
dbesc($app['guid']),
|
||||||
|
intval($uid)
|
||||||
|
);
|
||||||
|
|
||||||
|
// we don't sync system apps - they may be completely different on the other system
|
||||||
|
build_sync_packet($uid,array('app' => $x));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$r = q("delete from app where app_id = '%s' and app_channel = %d",
|
self::app_undestroy($uid,$app);
|
||||||
dbesc($app['guid']),
|
|
||||||
intval($uid)
|
|
||||||
);
|
|
||||||
|
|
||||||
// we don't sync system apps - they may be completely different on the other system
|
|
||||||
build_sync_packet($uid,array('app' => $x));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static public function app_undestroy($uid,$app) {
|
||||||
|
|
||||||
|
// undelete a system app
|
||||||
|
|
||||||
|
if($uid && $app['guid']) {
|
||||||
|
|
||||||
|
$x = q("select * from app where app_id = '%s' and app_channel = %d limit 1",
|
||||||
|
dbesc($app['guid']),
|
||||||
|
intval($uid)
|
||||||
|
);
|
||||||
|
if($x) {
|
||||||
|
if($x[0]['app_system']) {
|
||||||
|
$r = q("update app set app_deleted = 0 where app_id = '%s' and app_channel = %d",
|
||||||
|
dbesc($app['guid']),
|
||||||
|
intval($uid)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function app_feature($uid,$app,$term) {
|
||||||
|
$r = q("select id from app where app_id = '%s' and app_channel = %d limit 1",
|
||||||
|
dbesc($app['guid']),
|
||||||
|
intval($uid)
|
||||||
|
);
|
||||||
|
|
||||||
|
$x = q("select * from term where otype = %d and oid = %d and term = '%s' limit 1",
|
||||||
|
intval(TERM_OBJ_APP),
|
||||||
|
intval($r[0]['id']),
|
||||||
|
dbesc($term)
|
||||||
|
);
|
||||||
|
|
||||||
|
if($x) {
|
||||||
|
q("delete from term where otype = %d and oid = %d and term = '%s'",
|
||||||
|
intval(TERM_OBJ_APP),
|
||||||
|
intval($x[0]['oid']),
|
||||||
|
dbesc($term)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
store_item_tag($uid, $r[0]['id'], TERM_OBJ_APP, TERM_CATEGORY, $term, escape_tags(z_root() . '/apps/?f=&cat=' . $term));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static public function app_installed($uid,$app) {
|
static public function app_installed($uid,$app) {
|
||||||
|
|
||||||
$r = q("select id from app where app_id = '%s' and app_version = '%s' and app_channel = %d limit 1",
|
$r = q("select id from app where app_id = '%s' and app_channel = %d limit 1",
|
||||||
dbesc((array_key_exists('guid',$app)) ? $app['guid'] : ''),
|
dbesc((array_key_exists('guid',$app)) ? $app['guid'] : ''),
|
||||||
dbesc((array_key_exists('version',$app)) ? $app['version'] : ''),
|
|
||||||
intval($uid)
|
intval($uid)
|
||||||
);
|
);
|
||||||
return(($r) ? true : false);
|
return(($r) ? true : false);
|
||||||
@@ -419,16 +537,27 @@ class Apps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static public function app_list($uid, $deleted = false, $cat = '') {
|
static public function app_list($uid, $deleted = false, $cats = []) {
|
||||||
if($deleted)
|
if($deleted)
|
||||||
$sql_extra = " and app_deleted = 1 ";
|
$sql_extra = "";
|
||||||
else
|
else
|
||||||
$sql_extra = " and app_deleted = 0 ";
|
$sql_extra = " and app_deleted = 0 ";
|
||||||
|
|
||||||
if($cat) {
|
if($cats) {
|
||||||
$r = q("select oid from term where otype = %d and term = '%s'",
|
|
||||||
intval(TERM_OBJ_APP),
|
$cat_sql_extra = " and ( ";
|
||||||
dbesc($cat)
|
|
||||||
|
foreach($cats as $cat) {
|
||||||
|
if(strpos($cat_sql_extra, 'term'))
|
||||||
|
$cat_sql_extra .= "or ";
|
||||||
|
|
||||||
|
$cat_sql_extra .= "term = '" . dbesc($cat) . "' ";
|
||||||
|
}
|
||||||
|
|
||||||
|
$cat_sql_extra .= ") ";
|
||||||
|
|
||||||
|
$r = q("select oid from term where otype = %d $cat_sql_extra",
|
||||||
|
intval(TERM_OBJ_APP)
|
||||||
);
|
);
|
||||||
if(! $r)
|
if(! $r)
|
||||||
return $r;
|
return $r;
|
||||||
@@ -445,6 +574,7 @@ class Apps {
|
|||||||
$r = q("select * from app where app_channel = %d $sql_extra order by app_name asc",
|
$r = q("select * from app where app_channel = %d $sql_extra order by app_name asc",
|
||||||
intval($uid)
|
intval($uid)
|
||||||
);
|
);
|
||||||
|
|
||||||
if($r) {
|
if($r) {
|
||||||
for($x = 0; $x < count($r); $x ++) {
|
for($x = 0; $x < count($r); $x ++) {
|
||||||
if(! $r[$x]['app_system'])
|
if(! $r[$x]['app_system'])
|
||||||
@@ -455,9 +585,133 @@ class Apps {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return($r);
|
return($r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static public function app_order($uid,$apps) {
|
||||||
|
|
||||||
|
if(! $apps)
|
||||||
|
return $apps;
|
||||||
|
|
||||||
|
$x = (($uid) ? get_pconfig($uid,'system','app_order') : get_config('system','app_order'));
|
||||||
|
if(($x) && (! is_array($x))) {
|
||||||
|
$y = explode(',',$x);
|
||||||
|
$y = array_map('trim',$y);
|
||||||
|
$x = $y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(! (is_array($x) && ($x)))
|
||||||
|
return $apps;
|
||||||
|
|
||||||
|
$ret = [];
|
||||||
|
foreach($x as $xx) {
|
||||||
|
$y = self::find_app_in_array($xx,$apps);
|
||||||
|
if($y) {
|
||||||
|
$ret[] = $y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach($apps as $ap) {
|
||||||
|
if(! self::find_app_in_array($ap['name'],$ret)) {
|
||||||
|
$ret[] = $ap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static function find_app_in_array($name,$arr) {
|
||||||
|
if(! $arr)
|
||||||
|
return false;
|
||||||
|
foreach($arr as $x) {
|
||||||
|
if($x['name'] === $name) {
|
||||||
|
return $x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function moveup($uid,$guid) {
|
||||||
|
$syslist = array();
|
||||||
|
$list = self::app_list($uid, false, ['nav_featured_app', 'nav_pinned_app']);
|
||||||
|
if($list) {
|
||||||
|
foreach($list as $li) {
|
||||||
|
$syslist[] = self::app_encode($li);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self::translate_system_apps($syslist);
|
||||||
|
|
||||||
|
usort($syslist,'self::app_name_compare');
|
||||||
|
|
||||||
|
$syslist = self::app_order($uid,$syslist);
|
||||||
|
|
||||||
|
if(! $syslist)
|
||||||
|
return;
|
||||||
|
|
||||||
|
$newlist = [];
|
||||||
|
|
||||||
|
foreach($syslist as $k => $li) {
|
||||||
|
if($li['guid'] === $guid) {
|
||||||
|
$position = $k;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(! $position)
|
||||||
|
return;
|
||||||
|
$dest_position = $position - 1;
|
||||||
|
$saved = $syslist[$dest_position];
|
||||||
|
$syslist[$dest_position] = $syslist[$position];
|
||||||
|
$syslist[$position] = $saved;
|
||||||
|
|
||||||
|
$narr = [];
|
||||||
|
foreach($syslist as $x) {
|
||||||
|
$narr[] = $x['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
set_pconfig($uid,'system','app_order',implode(',',$narr));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static function movedown($uid,$guid) {
|
||||||
|
$syslist = array();
|
||||||
|
$list = self::app_list($uid, false, ['nav_featured_app', 'nav_pinned_app']);
|
||||||
|
if($list) {
|
||||||
|
foreach($list as $li) {
|
||||||
|
$syslist[] = self::app_encode($li);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self::translate_system_apps($syslist);
|
||||||
|
|
||||||
|
usort($syslist,'self::app_name_compare');
|
||||||
|
|
||||||
|
$syslist = self::app_order($uid,$syslist);
|
||||||
|
|
||||||
|
if(! $syslist)
|
||||||
|
return;
|
||||||
|
|
||||||
|
$newlist = [];
|
||||||
|
|
||||||
|
foreach($syslist as $k => $li) {
|
||||||
|
if($li['guid'] === $guid) {
|
||||||
|
$position = $k;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($position >= count($syslist) - 1)
|
||||||
|
return;
|
||||||
|
$dest_position = $position + 1;
|
||||||
|
$saved = $syslist[$dest_position];
|
||||||
|
$syslist[$dest_position] = $syslist[$position];
|
||||||
|
$syslist[$position] = $saved;
|
||||||
|
|
||||||
|
$narr = [];
|
||||||
|
foreach($syslist as $x) {
|
||||||
|
$narr[] = $x['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
set_pconfig($uid,'system','app_order',implode(',',$narr));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static public function app_decode($s) {
|
static public function app_decode($s) {
|
||||||
$x = base64_decode(str_replace(array('<br />',"\r","\n",' '),array('','','',''),$s));
|
$x = base64_decode(str_replace(array('<br />',"\r","\n",' '),array('','','',''),$s));
|
||||||
@@ -467,7 +721,7 @@ class Apps {
|
|||||||
|
|
||||||
static public function app_store($arr) {
|
static public function app_store($arr) {
|
||||||
|
|
||||||
// logger('app_store: ' . print_r($arr,true));
|
//logger('app_store: ' . print_r($arr,true));
|
||||||
|
|
||||||
$darray = array();
|
$darray = array();
|
||||||
$ret = array('success' => false);
|
$ret = array('success' => false);
|
||||||
@@ -478,7 +732,7 @@ class Apps {
|
|||||||
if((! $darray['app_url']) || (! $darray['app_channel']))
|
if((! $darray['app_url']) || (! $darray['app_channel']))
|
||||||
return $ret;
|
return $ret;
|
||||||
|
|
||||||
if($arr['photo'] && ! strstr($arr['photo'],z_root())) {
|
if($arr['photo'] && (strpos($arr['photo'],'icon:') !== 0) && (! strstr($arr['photo'],z_root()))) {
|
||||||
$x = import_xchan_photo($arr['photo'],get_observer_hash(),true);
|
$x = import_xchan_photo($arr['photo'],get_observer_hash(),true);
|
||||||
$arr['photo'] = $x[1];
|
$arr['photo'] = $x[1];
|
||||||
}
|
}
|
||||||
@@ -494,13 +748,14 @@ class Apps {
|
|||||||
$darray['app_addr'] = ((x($arr,'addr')) ? escape_tags($arr['addr']) : '');
|
$darray['app_addr'] = ((x($arr,'addr')) ? escape_tags($arr['addr']) : '');
|
||||||
$darray['app_price'] = ((x($arr,'price')) ? escape_tags($arr['price']) : '');
|
$darray['app_price'] = ((x($arr,'price')) ? escape_tags($arr['price']) : '');
|
||||||
$darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : '');
|
$darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : '');
|
||||||
|
$darray['app_plugin'] = ((x($arr,'plugin')) ? escape_tags(trim($arr['plugin'])) : '');
|
||||||
$darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : '');
|
$darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : '');
|
||||||
$darray['app_system'] = ((x($arr,'system')) ? intval($arr['system']) : 0);
|
$darray['app_system'] = ((x($arr,'system')) ? intval($arr['system']) : 0);
|
||||||
$darray['app_deleted'] = ((x($arr,'deleted')) ? intval($arr['deleted']) : 0);
|
$darray['app_deleted'] = ((x($arr,'deleted')) ? intval($arr['deleted']) : 0);
|
||||||
|
|
||||||
$created = datetime_convert();
|
$created = datetime_convert();
|
||||||
|
|
||||||
$r = q("insert into app ( app_id, app_sig, app_author, app_name, app_desc, app_url, app_photo, app_version, app_channel, app_addr, app_price, app_page, app_requires, app_created, app_edited, app_system, app_deleted ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, %d )",
|
$r = q("insert into app ( app_id, app_sig, app_author, app_name, app_desc, app_url, app_photo, app_version, app_channel, app_addr, app_price, app_page, app_requires, app_created, app_edited, app_system, app_plugin, app_deleted ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', %d )",
|
||||||
dbesc($darray['app_id']),
|
dbesc($darray['app_id']),
|
||||||
dbesc($darray['app_sig']),
|
dbesc($darray['app_sig']),
|
||||||
dbesc($darray['app_author']),
|
dbesc($darray['app_author']),
|
||||||
@@ -517,6 +772,7 @@ class Apps {
|
|||||||
dbesc($created),
|
dbesc($created),
|
||||||
dbesc($created),
|
dbesc($created),
|
||||||
intval($darray['app_system']),
|
intval($darray['app_system']),
|
||||||
|
dbesc($darray['app_plugin']),
|
||||||
intval($darray['app_deleted'])
|
intval($darray['app_deleted'])
|
||||||
);
|
);
|
||||||
if($r) {
|
if($r) {
|
||||||
@@ -545,6 +801,7 @@ class Apps {
|
|||||||
|
|
||||||
static public function app_update($arr) {
|
static public function app_update($arr) {
|
||||||
|
|
||||||
|
//logger('app_update: ' . print_r($arr,true));
|
||||||
$darray = array();
|
$darray = array();
|
||||||
$ret = array('success' => false);
|
$ret = array('success' => false);
|
||||||
|
|
||||||
@@ -555,7 +812,7 @@ class Apps {
|
|||||||
if((! $darray['app_url']) || (! $darray['app_channel']) || (! $darray['app_id']))
|
if((! $darray['app_url']) || (! $darray['app_channel']) || (! $darray['app_id']))
|
||||||
return $ret;
|
return $ret;
|
||||||
|
|
||||||
if($arr['photo'] && ! strstr($arr['photo'],z_root())) {
|
if($arr['photo'] && (strpos($arr['photo'],'icon:') !== 0) && (! strstr($arr['photo'],z_root()))) {
|
||||||
$x = import_xchan_photo($arr['photo'],get_observer_hash(),true);
|
$x = import_xchan_photo($arr['photo'],get_observer_hash(),true);
|
||||||
$arr['photo'] = $x[1];
|
$arr['photo'] = $x[1];
|
||||||
}
|
}
|
||||||
@@ -569,13 +826,14 @@ class Apps {
|
|||||||
$darray['app_addr'] = ((x($arr,'addr')) ? escape_tags($arr['addr']) : '');
|
$darray['app_addr'] = ((x($arr,'addr')) ? escape_tags($arr['addr']) : '');
|
||||||
$darray['app_price'] = ((x($arr,'price')) ? escape_tags($arr['price']) : '');
|
$darray['app_price'] = ((x($arr,'price')) ? escape_tags($arr['price']) : '');
|
||||||
$darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : '');
|
$darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : '');
|
||||||
|
$darray['app_plugin'] = ((x($arr,'plugin')) ? escape_tags(trim($arr['plugin'])) : '');
|
||||||
$darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : '');
|
$darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : '');
|
||||||
$darray['app_system'] = ((x($arr,'system')) ? intval($arr['system']) : 0);
|
$darray['app_system'] = ((x($arr,'system')) ? intval($arr['system']) : 0);
|
||||||
$darray['app_deleted'] = ((x($arr,'deleted')) ? intval($arr['deleted']) : 0);
|
$darray['app_deleted'] = ((x($arr,'deleted')) ? intval($arr['deleted']) : 0);
|
||||||
|
|
||||||
$edited = datetime_convert();
|
$edited = datetime_convert();
|
||||||
|
|
||||||
$r = q("update app set app_sig = '%s', app_author = '%s', app_name = '%s', app_desc = '%s', app_url = '%s', app_photo = '%s', app_version = '%s', app_addr = '%s', app_price = '%s', app_page = '%s', app_requires = '%s', app_edited = '%s', app_system = %d, app_deleted = %d where app_id = '%s' and app_channel = %d",
|
$r = q("update app set app_sig = '%s', app_author = '%s', app_name = '%s', app_desc = '%s', app_url = '%s', app_photo = '%s', app_version = '%s', app_addr = '%s', app_price = '%s', app_page = '%s', app_requires = '%s', app_edited = '%s', app_system = %d, app_plugin = '%s', app_deleted = %d where app_id = '%s' and app_channel = %d",
|
||||||
dbesc($darray['app_sig']),
|
dbesc($darray['app_sig']),
|
||||||
dbesc($darray['app_author']),
|
dbesc($darray['app_author']),
|
||||||
dbesc($darray['app_name']),
|
dbesc($darray['app_name']),
|
||||||
@@ -589,6 +847,7 @@ class Apps {
|
|||||||
dbesc($darray['app_requires']),
|
dbesc($darray['app_requires']),
|
||||||
dbesc($edited),
|
dbesc($edited),
|
||||||
intval($darray['app_system']),
|
intval($darray['app_system']),
|
||||||
|
dbesc($darray['app_plugin']),
|
||||||
intval($darray['app_deleted']),
|
intval($darray['app_deleted']),
|
||||||
dbesc($darray['app_id']),
|
dbesc($darray['app_id']),
|
||||||
intval($darray['app_channel'])
|
intval($darray['app_channel'])
|
||||||
@@ -655,6 +914,9 @@ class Apps {
|
|||||||
if($app['app_photo'])
|
if($app['app_photo'])
|
||||||
$ret['photo'] = $app['app_photo'];
|
$ret['photo'] = $app['app_photo'];
|
||||||
|
|
||||||
|
if($app['app_icon'])
|
||||||
|
$ret['icon'] = $app['app_icon'];
|
||||||
|
|
||||||
if($app['app_version'])
|
if($app['app_version'])
|
||||||
$ret['version'] = $app['app_version'];
|
$ret['version'] = $app['app_version'];
|
||||||
|
|
||||||
@@ -673,6 +935,9 @@ class Apps {
|
|||||||
if($app['app_system'])
|
if($app['app_system'])
|
||||||
$ret['system'] = $app['app_system'];
|
$ret['system'] = $app['app_system'];
|
||||||
|
|
||||||
|
if($app['app_plugin'])
|
||||||
|
$ret['plugin'] = trim($app['app_plugin']);
|
||||||
|
|
||||||
if($app['app_deleted'])
|
if($app['app_deleted'])
|
||||||
$ret['deleted'] = $app['app_deleted'];
|
$ret['deleted'] = $app['app_deleted'];
|
||||||
|
|
||||||
@@ -690,6 +955,8 @@ class Apps {
|
|||||||
if(! $embed)
|
if(! $embed)
|
||||||
return $ret;
|
return $ret;
|
||||||
|
|
||||||
|
$ret['embed'] = true;
|
||||||
|
|
||||||
if(array_key_exists('categories',$ret))
|
if(array_key_exists('categories',$ret))
|
||||||
unset($ret['categories']);
|
unset($ret['categories']);
|
||||||
|
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ namespace Zotlabs\Lib;
|
|||||||
class Cache {
|
class Cache {
|
||||||
public static function get($key) {
|
public static function get($key) {
|
||||||
|
|
||||||
$key = substr($key,0,254);
|
$hash = hash('whirlpool',$key);
|
||||||
|
|
||||||
$r = q("SELECT v FROM cache WHERE k = '%s' limit 1",
|
$r = q("SELECT v FROM cache WHERE k = '%s' limit 1",
|
||||||
dbesc($key)
|
dbesc($hash)
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($r)
|
if ($r)
|
||||||
@@ -22,20 +22,20 @@ class Cache {
|
|||||||
|
|
||||||
public static function set($key,$value) {
|
public static function set($key,$value) {
|
||||||
|
|
||||||
$key = substr($key,0,254);
|
$hash = hash('whirlpool',$key);
|
||||||
|
|
||||||
$r = q("SELECT * FROM cache WHERE k = '%s' limit 1",
|
$r = q("SELECT * FROM cache WHERE k = '%s' limit 1",
|
||||||
dbesc($key)
|
dbesc($hash)
|
||||||
);
|
);
|
||||||
if($r) {
|
if($r) {
|
||||||
q("UPDATE cache SET v = '%s', updated = '%s' WHERE k = '%s'",
|
q("UPDATE cache SET v = '%s', updated = '%s' WHERE k = '%s'",
|
||||||
dbesc($value),
|
dbesc($value),
|
||||||
dbesc(datetime_convert()),
|
dbesc(datetime_convert()),
|
||||||
dbesc($key));
|
dbesc($hash));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
q("INSERT INTO cache ( k, v, updated) VALUES ('%s','%s','%s')",
|
q("INSERT INTO cache ( k, v, updated) VALUES ('%s','%s','%s')",
|
||||||
dbesc($key),
|
dbesc($hash),
|
||||||
dbesc($value),
|
dbesc($value),
|
||||||
dbesc(datetime_convert()));
|
dbesc(datetime_convert()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,22 +2,18 @@
|
|||||||
namespace Zotlabs\Lib;
|
namespace Zotlabs\Lib;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Chat related functions.
|
* @brief A class with chatroom related static methods.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Chatroom {
|
class Chatroom {
|
||||||
/**
|
/**
|
||||||
* @brief Creates a chatroom.
|
* @brief Creates a chatroom.
|
||||||
*
|
*
|
||||||
* @param array $channel
|
* @param array $channel
|
||||||
* @param array $arr
|
* @param array $arr
|
||||||
* @return An associative array containing:
|
* @return array An associative array containing:
|
||||||
* - success: A boolean
|
* * \e boolean \b success - A boolean success status
|
||||||
* - message: (optional) A string
|
* * \e string \b message - (optional) A string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static public function create($channel, $arr) {
|
static public function create($channel, $arr) {
|
||||||
|
|
||||||
$ret = array('success' => false);
|
$ret = array('success' => false);
|
||||||
@@ -225,10 +221,16 @@ class Chatroom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create a chat message via API.
|
* @brief Create a chat message via API.
|
||||||
|
*
|
||||||
* It is the caller's responsibility to enter the room.
|
* It is the caller's responsibility to enter the room.
|
||||||
*/
|
*
|
||||||
|
* @param int $uid
|
||||||
|
* @param int $room_id
|
||||||
|
* @param string $xchan
|
||||||
|
* @param string $text
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
static public function message($uid, $room_id, $xchan, $text) {
|
static public function message($uid, $room_id, $xchan, $text) {
|
||||||
|
|
||||||
$ret = array('success' => false);
|
$ret = array('success' => false);
|
||||||
@@ -245,12 +247,18 @@ class Chatroom {
|
|||||||
if(! $r)
|
if(! $r)
|
||||||
return $ret;
|
return $ret;
|
||||||
|
|
||||||
$arr = array(
|
$arr = [
|
||||||
'chat_room' => $room_id,
|
'chat_room' => $room_id,
|
||||||
'chat_xchan' => $xchan,
|
'chat_xchan' => $xchan,
|
||||||
'chat_text' => $text
|
'chat_text' => $text
|
||||||
);
|
];
|
||||||
|
/**
|
||||||
|
* @hooks chat_message
|
||||||
|
* Called to create a chat message.
|
||||||
|
* * \e int \b chat_room
|
||||||
|
* * \e string \b chat_xchan
|
||||||
|
* * \e string \b chat_text
|
||||||
|
*/
|
||||||
call_hooks('chat_message', $arr);
|
call_hooks('chat_message', $arr);
|
||||||
|
|
||||||
$x = q("insert into chat ( chat_room, chat_xchan, created, chat_text )
|
$x = q("insert into chat ( chat_room, chat_xchan, created, chat_text )
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?php /** @file */
|
<?php
|
||||||
|
|
||||||
namespace Zotlabs\Lib;
|
namespace Zotlabs\Lib;
|
||||||
|
|
||||||
@@ -14,7 +14,6 @@ class Config {
|
|||||||
* @param string $family
|
* @param string $family
|
||||||
* The category of the configuration value
|
* The category of the configuration value
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static public function Load($family) {
|
static public function Load($family) {
|
||||||
if(! array_key_exists($family, \App::$config))
|
if(! array_key_exists($family, \App::$config))
|
||||||
\App::$config[$family] = array();
|
\App::$config[$family] = array();
|
||||||
@@ -47,13 +46,12 @@ class Config {
|
|||||||
* @return mixed
|
* @return mixed
|
||||||
* Return the set value, or false if the database update failed
|
* Return the set value, or false if the database update failed
|
||||||
*/
|
*/
|
||||||
|
static public function Set($family, $key, $value) {
|
||||||
static public function Set($family,$key,$value) {
|
|
||||||
// manage array value
|
// manage array value
|
||||||
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
|
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
|
||||||
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
|
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
|
||||||
|
|
||||||
if(get_config($family, $key) === false || (! self::get_from_storage($family, $key))) {
|
if(self::Get($family, $key) === false || (! self::get_from_storage($family, $key))) {
|
||||||
$ret = q("INSERT INTO config ( cat, k, v ) VALUES ( '%s', '%s', '%s' ) ",
|
$ret = q("INSERT INTO config ( cat, k, v ) VALUES ( '%s', '%s', '%s' ) ",
|
||||||
dbesc($family),
|
dbesc($family),
|
||||||
dbesc($key),
|
dbesc($key),
|
||||||
@@ -76,8 +74,8 @@ class Config {
|
|||||||
\App::$config[$family][$key] = $value;
|
\App::$config[$family][$key] = $value;
|
||||||
$ret = $value;
|
$ret = $value;
|
||||||
}
|
}
|
||||||
return $ret;
|
|
||||||
|
|
||||||
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -95,16 +93,16 @@ class Config {
|
|||||||
* The category of the configuration value
|
* The category of the configuration value
|
||||||
* @param string $key
|
* @param string $key
|
||||||
* The configuration key to query
|
* The configuration key to query
|
||||||
|
* @param string $default (optional) default false
|
||||||
* @return mixed Return value or false on error or if not set
|
* @return mixed Return value or false on error or if not set
|
||||||
*/
|
*/
|
||||||
|
static public function Get($family, $key, $default = false) {
|
||||||
static public function Get($family,$key) {
|
|
||||||
if((! array_key_exists($family, \App::$config)) || (! array_key_exists('config_loaded', \App::$config[$family])))
|
if((! array_key_exists($family, \App::$config)) || (! array_key_exists('config_loaded', \App::$config[$family])))
|
||||||
self::Load($family);
|
self::Load($family);
|
||||||
|
|
||||||
if(array_key_exists('config_loaded', \App::$config[$family])) {
|
if(array_key_exists('config_loaded', \App::$config[$family])) {
|
||||||
if(! array_key_exists($key, \App::$config[$family])) {
|
if(! array_key_exists($key, \App::$config[$family])) {
|
||||||
return false;
|
return $default;
|
||||||
}
|
}
|
||||||
return ((! is_array(\App::$config[$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$family][$key]))
|
return ((! is_array(\App::$config[$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$family][$key]))
|
||||||
? unserialize(\App::$config[$family][$key])
|
? unserialize(\App::$config[$family][$key])
|
||||||
@@ -112,7 +110,7 @@ class Config {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -127,17 +125,18 @@ class Config {
|
|||||||
* The configuration key to delete
|
* The configuration key to delete
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
|
static public function Delete($family, $key) {
|
||||||
static public function Delete($family,$key) {
|
|
||||||
|
|
||||||
$ret = false;
|
$ret = false;
|
||||||
|
|
||||||
if(array_key_exists($family, \App::$config) && array_key_exists($key, \App::$config[$family]))
|
if(array_key_exists($family, \App::$config) && array_key_exists($key, \App::$config[$family]))
|
||||||
unset(\App::$config[$family][$key]);
|
unset(\App::$config[$family][$key]);
|
||||||
$ret = q("DELETE FROM config WHERE cat = '%s' AND k = '%s'",
|
|
||||||
|
$ret = q("DELETE FROM config WHERE cat = '%s' AND k = '%s'",
|
||||||
dbesc($family),
|
dbesc($family),
|
||||||
dbesc($key)
|
dbesc($key)
|
||||||
);
|
);
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,12 +153,12 @@ class Config {
|
|||||||
* The configuration key to query
|
* The configuration key to query
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static private function get_from_storage($family,$key) {
|
static private function get_from_storage($family,$key) {
|
||||||
$ret = q("SELECT * FROM config WHERE cat = '%s' AND k = '%s' LIMIT 1",
|
$ret = q("SELECT * FROM config WHERE cat = '%s' AND k = '%s' LIMIT 1",
|
||||||
dbesc($family),
|
dbesc($family),
|
||||||
dbesc($key)
|
dbesc($key)
|
||||||
);
|
);
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
121
Zotlabs/Lib/DB_Upgrade.php
Normal file
121
Zotlabs/Lib/DB_Upgrade.php
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zotlabs\Lib;
|
||||||
|
|
||||||
|
|
||||||
|
class DB_Upgrade {
|
||||||
|
|
||||||
|
public $config_name = '';
|
||||||
|
public $func_prefix = '';
|
||||||
|
|
||||||
|
function __construct($db_revision) {
|
||||||
|
|
||||||
|
$platform_name = System::get_platform_name();
|
||||||
|
|
||||||
|
$update_file = 'install/' . $platform_name . '/update.php';
|
||||||
|
if(! file_exists($update_file)) {
|
||||||
|
$update_file = 'install/update.php';
|
||||||
|
$this->config_name = 'db_version';
|
||||||
|
$this->func_prefix = 'update_r';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->config_name = $platform_name . '_db_version';
|
||||||
|
$this->func_prefix = $platform_name . '_update_';
|
||||||
|
}
|
||||||
|
|
||||||
|
$build = get_config('system', $this->config_name, 0);
|
||||||
|
if(! intval($build))
|
||||||
|
$build = set_config('system', $this->config_name, $db_revision);
|
||||||
|
|
||||||
|
if($build == $db_revision) {
|
||||||
|
// Nothing to be done.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$stored = intval($build);
|
||||||
|
if(! $stored) {
|
||||||
|
logger('Critical: check_config unable to determine database schema version');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$current = intval($db_revision);
|
||||||
|
|
||||||
|
if(($stored < $current) && file_exists($update_file)) {
|
||||||
|
|
||||||
|
Config::Load('database');
|
||||||
|
|
||||||
|
// We're reporting a different version than what is currently installed.
|
||||||
|
// Run any existing update scripts to bring the database up to current.
|
||||||
|
|
||||||
|
require_once($update_file);
|
||||||
|
|
||||||
|
// make sure that boot.php and update.php are the same release, we might be
|
||||||
|
// updating from git right this very second and the correct version of the update.php
|
||||||
|
// file may not be here yet. This can happen on a very busy site.
|
||||||
|
|
||||||
|
if($db_revision == UPDATE_VERSION) {
|
||||||
|
for($x = $stored; $x < $current; $x ++) {
|
||||||
|
$func = $this->func_prefix . $x;
|
||||||
|
if(function_exists($func)) {
|
||||||
|
// There could be a lot of processes running or about to run.
|
||||||
|
// We want exactly one process to run the update command.
|
||||||
|
// So store the fact that we're taking responsibility
|
||||||
|
// after first checking to see if somebody else already has.
|
||||||
|
|
||||||
|
// If the update fails or times-out completely you may need to
|
||||||
|
// delete the config entry to try again.
|
||||||
|
|
||||||
|
if(get_config('database', $func))
|
||||||
|
break;
|
||||||
|
set_config('database',$func, '1');
|
||||||
|
// call the specific update
|
||||||
|
|
||||||
|
$retval = $func();
|
||||||
|
if($retval) {
|
||||||
|
|
||||||
|
// Prevent sending hundreds of thousands of emails by creating
|
||||||
|
// a lockfile.
|
||||||
|
|
||||||
|
$lockfile = 'store/[data]/mailsent';
|
||||||
|
|
||||||
|
if ((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 86400)))
|
||||||
|
return;
|
||||||
|
@unlink($lockfile);
|
||||||
|
//send the administrator an e-mail
|
||||||
|
file_put_contents($lockfile, $x);
|
||||||
|
|
||||||
|
$r = q("select account_language from account where account_email = '%s' limit 1",
|
||||||
|
dbesc(\App::$config['system']['admin_email'])
|
||||||
|
);
|
||||||
|
push_lang(($r) ? $r[0]['account_language'] : 'en');
|
||||||
|
|
||||||
|
z_mail(
|
||||||
|
[
|
||||||
|
'toEmail' => \App::$config['system']['admin_email'],
|
||||||
|
'messageSubject' => sprintf( t('Update Error at %s'), z_root()),
|
||||||
|
'textVersion' => replace_macros(get_intltext_template('update_fail_eml.tpl'),
|
||||||
|
[
|
||||||
|
'$sitename' => \App::$config['system']['sitename'],
|
||||||
|
'$siteurl' => z_root(),
|
||||||
|
'$update' => $x,
|
||||||
|
'$error' => sprintf( t('Update %s failed. See error logs.'), $x)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
//try the logger
|
||||||
|
logger('CRITICAL: Update Failed: ' . $x);
|
||||||
|
pop_lang();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
set_config('database',$func, 'success');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_config('system', $this->config_name, $db_revision);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -67,7 +67,7 @@ class Enotify {
|
|||||||
$sender_name = $product;
|
$sender_name = $product;
|
||||||
$hostname = \App::get_hostname();
|
$hostname = \App::get_hostname();
|
||||||
if(strpos($hostname,':'))
|
if(strpos($hostname,':'))
|
||||||
$hostname = substr($hostname,0,strpos($hostname,':'));
|
$hostname = substr($hostname,0,strpos($hostname,':'));
|
||||||
|
|
||||||
// Do not translate 'noreply' as it must be a legal 7-bit email address
|
// Do not translate 'noreply' as it must be a legal 7-bit email address
|
||||||
|
|
||||||
@@ -77,16 +77,13 @@ class Enotify {
|
|||||||
|
|
||||||
$sender_email = get_config('system','from_email');
|
$sender_email = get_config('system','from_email');
|
||||||
if(! $sender_email)
|
if(! $sender_email)
|
||||||
$sender_email = 'Administrator' . '@' . \App::get_hostname();
|
$sender_email = 'Administrator' . '@' . $hostname;
|
||||||
|
|
||||||
|
|
||||||
$sender_name = get_config('system','from_email_name');
|
$sender_name = get_config('system','from_email_name');
|
||||||
if(! $sender_name)
|
if(! $sender_name)
|
||||||
$sender_name = \Zotlabs\Lib\System::get_site_name();
|
$sender_name = \Zotlabs\Lib\System::get_site_name();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$additional_mail_header = "";
|
$additional_mail_header = "";
|
||||||
|
|
||||||
if(array_key_exists('item', $params)) {
|
if(array_key_exists('item', $params)) {
|
||||||
@@ -105,6 +102,10 @@ class Enotify {
|
|||||||
$title = $params['item']['title'];
|
$title = $params['item']['title'];
|
||||||
$body = $params['item']['body'];
|
$body = $params['item']['body'];
|
||||||
}
|
}
|
||||||
|
if($params['item']['created'] < datetime_convert('UTC','UTC','now - 1 month')) {
|
||||||
|
logger('notification invoked for an old item which may have been refetched.',LOGGER_DEBUG,LOG_INFO);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$title = $body = '';
|
$title = $body = '';
|
||||||
@@ -129,7 +130,9 @@ class Enotify {
|
|||||||
if ($params['type'] == NOTIFY_COMMENT) {
|
if ($params['type'] == NOTIFY_COMMENT) {
|
||||||
// logger("notification: params = " . print_r($params, true), LOGGER_DEBUG);
|
// logger("notification: params = " . print_r($params, true), LOGGER_DEBUG);
|
||||||
|
|
||||||
$itemlink = $params['link'];
|
$moderated = (($params['item']['item_blocked'] == ITEM_MODERATED) ? true : false);
|
||||||
|
|
||||||
|
$itemlink = $params['link'];
|
||||||
|
|
||||||
// ignore like/unlike activity on posts - they probably require a separate notification preference
|
// ignore like/unlike activity on posts - they probably require a separate notification preference
|
||||||
|
|
||||||
@@ -169,7 +172,6 @@ class Enotify {
|
|||||||
|
|
||||||
xchan_query($p);
|
xchan_query($p);
|
||||||
|
|
||||||
|
|
||||||
$item_post_type = item_post_type($p[0]);
|
$item_post_type = item_post_type($p[0]);
|
||||||
// $private = $p[0]['item_private'];
|
// $private = $p[0]['item_private'];
|
||||||
$parent_id = $p[0]['id'];
|
$parent_id = $p[0]['id'];
|
||||||
@@ -207,15 +209,102 @@ class Enotify {
|
|||||||
// Before this we have the name of the replier on the subject rendering
|
// Before this we have the name of the replier on the subject rendering
|
||||||
// differents subjects for messages on the same thread.
|
// differents subjects for messages on the same thread.
|
||||||
|
|
||||||
$subject = sprintf( t('[$Projectname:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
|
if($moderated)
|
||||||
|
$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, %2$s commented on an item/conversation you have been following.'), $recip['channel_name'], $sender['xchan_name']);
|
$preamble = sprintf( t('%1$s, %2$s commented on an item/conversation you have been following.'), $recip['channel_name'], $sender['xchan_name']);
|
||||||
$epreamble = $dest_str;
|
$epreamble = $dest_str;
|
||||||
|
|
||||||
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
|
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
|
||||||
$tsitelink = sprintf( $sitelink, $siteurl );
|
$tsitelink = sprintf( $sitelink, $siteurl );
|
||||||
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
|
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
|
||||||
|
if($moderated) {
|
||||||
|
$tsitelink .= "\n\n" . sprintf( t('Please visit %s to approve or reject this comment.'), z_root() . '/moderate' );
|
||||||
|
$hsitelink .= "<br><br>" . sprintf( t('Please visit %s to approve or reject this comment.'), '<a href="' . z_root() . '/moderate">' . z_root() . '/moderate</a>' );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($params['type'] == NOTIFY_LIKE) {
|
||||||
|
// logger("notification: params = " . print_r($params, true), LOGGER_DEBUG);
|
||||||
|
|
||||||
|
$itemlink = $params['link'];
|
||||||
|
|
||||||
|
// ignore like/unlike activity on posts - they probably require a separate notification preference
|
||||||
|
|
||||||
|
if (array_key_exists('item',$params) && (! activity_match($params['item']['verb'],ACTIVITY_LIKE))) {
|
||||||
|
logger('notification: not a like activity. Ignoring.');
|
||||||
|
pop_lang();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parent_mid = $params['parent_mid'];
|
||||||
|
|
||||||
|
// Check to see if there was already a notify for this post.
|
||||||
|
// If so don't create a second notification
|
||||||
|
|
||||||
|
$p = null;
|
||||||
|
$p = q("select id from notify where link = '%s' and uid = %d limit 1",
|
||||||
|
dbesc($params['link']),
|
||||||
|
intval($recip['channel_id'])
|
||||||
|
);
|
||||||
|
if ($p) {
|
||||||
|
logger('notification: like already notified');
|
||||||
|
pop_lang();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// if it's a post figure out who's post it is.
|
||||||
|
|
||||||
|
$p = null;
|
||||||
|
|
||||||
|
if($params['otype'] === 'item' && $parent_mid) {
|
||||||
|
$p = q("select * from item where mid = '%s' and uid = %d limit 1",
|
||||||
|
dbesc($parent_mid),
|
||||||
|
intval($recip['channel_id'])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
xchan_query($p);
|
||||||
|
|
||||||
|
|
||||||
|
$item_post_type = item_post_type($p[0]);
|
||||||
|
// $private = $p[0]['item_private'];
|
||||||
|
$parent_id = $p[0]['id'];
|
||||||
|
|
||||||
|
$parent_item = $p[0];
|
||||||
|
|
||||||
|
|
||||||
|
// "your post"
|
||||||
|
if($p[0]['owner']['xchan_name'] == $p[0]['author']['xchan_name'] && intval($p[0]['item_wall']))
|
||||||
|
$dest_str = sprintf(t('%1$s, %2$s liked [zrl=%3$s]your %4$s[/zrl]'),
|
||||||
|
$recip['channel_name'],
|
||||||
|
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
|
||||||
|
$itemlink,
|
||||||
|
$item_post_type);
|
||||||
|
else {
|
||||||
|
pop_lang();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some mail softwares relies on subject field for threading.
|
||||||
|
// So, we cannot have different subjects for notifications of the same thread.
|
||||||
|
// Before this we have the name of the replier on the subject rendering
|
||||||
|
// differents subjects for messages on the same thread.
|
||||||
|
|
||||||
|
$subject = sprintf( t('[$Projectname:Notify] Like received to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
|
||||||
|
$preamble = sprintf( t('%1$s, %2$s liked an item/conversation you created.'), $recip['channel_name'], $sender['xchan_name']);
|
||||||
|
$epreamble = $dest_str;
|
||||||
|
|
||||||
|
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
|
||||||
|
$tsitelink = sprintf( $sitelink, $siteurl );
|
||||||
|
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if($params['type'] == NOTIFY_WALL) {
|
if($params['type'] == NOTIFY_WALL) {
|
||||||
$subject = sprintf( t('[$Projectname:Notify] %s posted to your profile wall') , $sender['xchan_name']);
|
$subject = sprintf( t('[$Projectname:Notify] %s posted to your profile wall') , $sender['xchan_name']);
|
||||||
|
|
||||||
@@ -364,7 +453,7 @@ class Enotify {
|
|||||||
do {
|
do {
|
||||||
$dups = false;
|
$dups = false;
|
||||||
$hash = random_string();
|
$hash = random_string();
|
||||||
$r = q("SELECT `id` FROM `notify` WHERE `hash` = '%s' LIMIT 1",
|
$r = q("SELECT id FROM notify WHERE hash = '%s' LIMIT 1",
|
||||||
dbesc($hash));
|
dbesc($hash));
|
||||||
if ($r)
|
if ($r)
|
||||||
$dups = true;
|
$dups = true;
|
||||||
@@ -415,13 +504,14 @@ class Enotify {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$r = q("insert into notify (hash,xname,url,photo,created,aid,uid,link,parent,seen,ntype,verb,otype)
|
$r = q("insert into notify (hash,xname,url,photo,created,msg,aid,uid,link,parent,seen,ntype,verb,otype)
|
||||||
values('%s','%s','%s','%s','%s',%d,%d,'%s','%s',%d,%d,'%s','%s')",
|
values('%s','%s','%s','%s','%s','%s',%d,%d,'%s','%s',%d,%d,'%s','%s')",
|
||||||
dbesc($datarray['hash']),
|
dbesc($datarray['hash']),
|
||||||
dbesc($datarray['xname']),
|
dbesc($datarray['xname']),
|
||||||
dbesc($datarray['url']),
|
dbesc($datarray['url']),
|
||||||
dbesc($datarray['photo']),
|
dbesc($datarray['photo']),
|
||||||
dbesc($datarray['created']),
|
dbesc($datarray['created']),
|
||||||
|
dbesc(''), // will fill this in below after the record is created
|
||||||
intval($datarray['aid']),
|
intval($datarray['aid']),
|
||||||
intval($datarray['uid']),
|
intval($datarray['uid']),
|
||||||
dbesc($datarray['link']),
|
dbesc($datarray['link']),
|
||||||
@@ -633,7 +723,7 @@ class Enotify {
|
|||||||
call_hooks('email_send', $params);
|
call_hooks('email_send', $params);
|
||||||
|
|
||||||
if($params['sent']) {
|
if($params['sent']) {
|
||||||
logger("notification: enotify::send (addon) returns " . $params['result'], LOGGER_DEBUG);
|
logger("notification: enotify::send (addon) returns " . (($params['result']) ? 'success' : 'failure'), LOGGER_DEBUG);
|
||||||
return $params['result'];
|
return $params['result'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -676,7 +766,7 @@ class Enotify {
|
|||||||
$multipartMessageBody, // message body
|
$multipartMessageBody, // message body
|
||||||
$messageHeader // message headers
|
$messageHeader // message headers
|
||||||
);
|
);
|
||||||
logger("notification: enotify::send returns " . $res, LOGGER_DEBUG);
|
logger("notification: enotify::send returns " . (($res) ? 'success' : 'failure'), LOGGER_DEBUG);
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -688,10 +778,14 @@ class Enotify {
|
|||||||
|
|
||||||
// Call localize_item to get a one line status for activities.
|
// Call localize_item to get a one line status for activities.
|
||||||
// This should set $item['localized'] to indicate we have a brief summary.
|
// This should set $item['localized'] to indicate we have a brief summary.
|
||||||
|
// and perhaps $item['shortlocalized'] for an even briefer summary
|
||||||
|
|
||||||
localize_item($item);
|
localize_item($item);
|
||||||
|
|
||||||
if($item['localize']) {
|
if($item['shortlocalize']) {
|
||||||
|
$itemem_text = $item['shortlocalize'];
|
||||||
|
}
|
||||||
|
elseif($item['localize']) {
|
||||||
$itemem_text = $item['localize'];
|
$itemem_text = $item['localize'];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -709,6 +803,9 @@ class Enotify {
|
|||||||
'photo' => $item['author']['xchan_photo_s'],
|
'photo' => $item['author']['xchan_photo_s'],
|
||||||
'when' => relative_date($item['created']),
|
'when' => relative_date($item['created']),
|
||||||
'class' => (intval($item['item_unseen']) ? 'notify-unseen' : 'notify-seen'),
|
'class' => (intval($item['item_unseen']) ? 'notify-unseen' : 'notify-seen'),
|
||||||
|
'b64mid' => ((in_array($item['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) ? 'b64.' . base64url_encode($item['thr_parent']) : 'b64.' . base64url_encode($item['mid'])),
|
||||||
|
'notify_id' => 'undefined',
|
||||||
|
'thread_top' => (($item['item_thread_top']) ? true : false),
|
||||||
'message' => strip_tags(bbcode($itemem_text))
|
'message' => strip_tags(bbcode($itemem_text))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class IConfig {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function Get(&$item, $family, $key) {
|
static public function Get(&$item, $family, $key, $default = false) {
|
||||||
|
|
||||||
$is_item = false;
|
$is_item = false;
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ class IConfig {
|
|||||||
$iid = $item;
|
$iid = $item;
|
||||||
|
|
||||||
if(! $iid)
|
if(! $iid)
|
||||||
return false;
|
return $default;
|
||||||
|
|
||||||
if(is_array($item) && array_key_exists('iconfig',$item) && is_array($item['iconfig'])) {
|
if(is_array($item) && array_key_exists('iconfig',$item) && is_array($item['iconfig'])) {
|
||||||
foreach($item['iconfig'] as $c) {
|
foreach($item['iconfig'] as $c) {
|
||||||
@@ -48,7 +48,7 @@ class IConfig {
|
|||||||
$item['iconfig'][] = $r[0];
|
$item['iconfig'][] = $r[0];
|
||||||
return $r[0]['v'];
|
return $r[0]['v'];
|
||||||
}
|
}
|
||||||
return false;
|
return $default;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
38
Zotlabs/Lib/JSalmon.php
Normal file
38
Zotlabs/Lib/JSalmon.php
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zotlabs\Lib;
|
||||||
|
|
||||||
|
|
||||||
|
class JSalmon {
|
||||||
|
|
||||||
|
static function sign($data,$key_id,$key) {
|
||||||
|
|
||||||
|
$arr = $data;
|
||||||
|
$data = json_encode($data,JSON_UNESCAPED_SLASHES);
|
||||||
|
$data = base64url_encode($data, false); // do not strip padding
|
||||||
|
$data_type = 'application/x-zot+json';
|
||||||
|
$encoding = 'base64url';
|
||||||
|
$algorithm = 'RSA-SHA256';
|
||||||
|
|
||||||
|
$data = preg_replace('/\s+/','',$data);
|
||||||
|
|
||||||
|
// precomputed base64url encoding of data_type, encoding, algorithm concatenated with periods
|
||||||
|
|
||||||
|
$precomputed = '.' . base64url_encode($data_type,false) . '.YmFzZTY0dXJs.UlNBLVNIQTI1Ng==';
|
||||||
|
|
||||||
|
$signature = base64url_encode(rsa_sign($data . $precomputed, $key), false);
|
||||||
|
|
||||||
|
return ([
|
||||||
|
'signed' => true,
|
||||||
|
'data' => $data,
|
||||||
|
'data_type' => $data_type,
|
||||||
|
'encoding' => $encoding,
|
||||||
|
'alg' => $algorithm,
|
||||||
|
'sigs' => [
|
||||||
|
'value' => $signature,
|
||||||
|
'key_id' => base64url_encode($key_id)
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
135
Zotlabs/Lib/LDSignatures.php
Normal file
135
Zotlabs/Lib/LDSignatures.php
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zotlabs\Lib;
|
||||||
|
|
||||||
|
require_once('library/jsonld/jsonld.php');
|
||||||
|
|
||||||
|
class LDSignatures {
|
||||||
|
|
||||||
|
|
||||||
|
static function verify($data,$pubkey) {
|
||||||
|
|
||||||
|
$ohash = self::hash(self::signable_options($data['signature']));
|
||||||
|
$dhash = self::hash(self::signable_data($data));
|
||||||
|
|
||||||
|
$x = rsa_verify($ohash . $dhash,base64_decode($data['signature']['signatureValue']), $pubkey);
|
||||||
|
logger('LD-verify: ' . intval($x));
|
||||||
|
|
||||||
|
return $x;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function dopplesign(&$data,$channel) {
|
||||||
|
// remove for the time being - performance issues
|
||||||
|
// $data['magicEnv'] = self::salmon_sign($data,$channel);
|
||||||
|
return self::sign($data,$channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function sign($data,$channel) {
|
||||||
|
|
||||||
|
$options = [
|
||||||
|
'type' => 'RsaSignature2017',
|
||||||
|
'nonce' => random_string(64),
|
||||||
|
'creator' => z_root() . '/channel/' . $channel['channel_address'] . '/public_key_pem',
|
||||||
|
'created' => datetime_convert('UTC','UTC', 'now', 'Y-m-d\Th:i:s\Z')
|
||||||
|
];
|
||||||
|
|
||||||
|
$ohash = self::hash(self::signable_options($options));
|
||||||
|
$dhash = self::hash(self::signable_data($data));
|
||||||
|
$options['signatureValue'] = base64_encode(rsa_sign($ohash . $dhash,$channel['channel_prvkey']));
|
||||||
|
|
||||||
|
$signed = array_merge([
|
||||||
|
'@context' => [
|
||||||
|
ACTIVITYSTREAMS_JSONLD_REV,
|
||||||
|
'https://w3id.org/security/v1' ],
|
||||||
|
],$options);
|
||||||
|
|
||||||
|
return $signed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static function signable_data($data) {
|
||||||
|
|
||||||
|
$newdata = [];
|
||||||
|
if($data) {
|
||||||
|
foreach($data as $k => $v) {
|
||||||
|
if(! in_array($k,[ 'signature' ])) {
|
||||||
|
$newdata[$k] = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return json_encode($newdata,JSON_UNESCAPED_SLASHES);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static function signable_options($options) {
|
||||||
|
|
||||||
|
$newopts = [ '@context' => 'https://w3id.org/identity/v1' ];
|
||||||
|
if($options) {
|
||||||
|
foreach($options as $k => $v) {
|
||||||
|
if(! in_array($k,[ 'type','id','signatureValue' ])) {
|
||||||
|
$newopts[$k] = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return json_encode($newopts,JSON_UNESCAPED_SLASHES);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function hash($obj) {
|
||||||
|
|
||||||
|
return hash('sha256',self::normalise($obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
static function normalise($data) {
|
||||||
|
if(is_string($data)) {
|
||||||
|
$data = json_decode($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(! is_object($data))
|
||||||
|
return '';
|
||||||
|
|
||||||
|
jsonld_set_document_loader('jsonld_document_loader');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$d = jsonld_normalize($data,[ 'algorithm' => 'URDNA2015', 'format' => 'application/nquads' ]);
|
||||||
|
}
|
||||||
|
catch (\Exception $e) {
|
||||||
|
logger('normalise error:' . print_r($e,true));
|
||||||
|
logger('normalise error: ' . print_r($data,true));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $d;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function salmon_sign($data,$channel) {
|
||||||
|
|
||||||
|
$arr = $data;
|
||||||
|
$data = json_encode($data,JSON_UNESCAPED_SLASHES);
|
||||||
|
$data = base64url_encode($data, false); // do not strip padding
|
||||||
|
$data_type = 'application/activity+json';
|
||||||
|
$encoding = 'base64url';
|
||||||
|
$algorithm = 'RSA-SHA256';
|
||||||
|
$keyhash = base64url_encode(z_root() . '/channel/' . $channel['channel_address']);
|
||||||
|
|
||||||
|
$data = str_replace(array(" ","\t","\r","\n"),array("","","",""),$data);
|
||||||
|
|
||||||
|
// precomputed base64url encoding of data_type, encoding, algorithm concatenated with periods
|
||||||
|
|
||||||
|
$precomputed = '.' . base64url_encode($data_type,false) . '.YmFzZTY0dXJs.UlNBLVNIQTI1Ng==';
|
||||||
|
|
||||||
|
$signature = base64url_encode(rsa_sign($data . $precomputed,$channel['channel_prvkey']));
|
||||||
|
|
||||||
|
return ([
|
||||||
|
'id' => $arr['id'],
|
||||||
|
'meData' => $data,
|
||||||
|
'meDataType' => $data_type,
|
||||||
|
'meEncoding' => $encoding,
|
||||||
|
'meAlgorithm' => $algorithm,
|
||||||
|
'meCreator' => z_root() . '/channel/' . $channel['channel_address'] . '/public_key_pem',
|
||||||
|
'meSignatureValue' => $signature
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
103
Zotlabs/Lib/MarkdownSoap.php
Normal file
103
Zotlabs/Lib/MarkdownSoap.php
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zotlabs\Lib;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MarkdownSoap
|
||||||
|
* Purify Markdown for storage
|
||||||
|
* $x = new MarkdownSoap($string_to_be_cleansed);
|
||||||
|
* $text = $x->clean();
|
||||||
|
*
|
||||||
|
* What this does:
|
||||||
|
* 1. extracts code blocks and privately escapes them from processing
|
||||||
|
* 2. Run html purifier on the content
|
||||||
|
* 3. put back the code blocks
|
||||||
|
* 4. run htmlspecialchars on the entire content for safe storage
|
||||||
|
*
|
||||||
|
* At render time:
|
||||||
|
* $markdown = \Zotlabs\Lib\MarkdownSoap::unescape($text);
|
||||||
|
* $html = \Michelf\MarkdownExtra::DefaultTransform($markdown);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class MarkdownSoap {
|
||||||
|
|
||||||
|
private $token;
|
||||||
|
|
||||||
|
private $str;
|
||||||
|
|
||||||
|
function __construct($s) {
|
||||||
|
$this->str = $s;
|
||||||
|
$this->token = random_string(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function clean() {
|
||||||
|
|
||||||
|
$x = $this->extract_code($this->str);
|
||||||
|
|
||||||
|
$x = $this->purify($x);
|
||||||
|
|
||||||
|
$x = $this->putback_code($x);
|
||||||
|
|
||||||
|
$x = $this->escape($x);
|
||||||
|
|
||||||
|
return $x;
|
||||||
|
}
|
||||||
|
|
||||||
|
function extract_code($s) {
|
||||||
|
|
||||||
|
$text = preg_replace_callback('{
|
||||||
|
(?:\n\n|\A\n?)
|
||||||
|
( # $1 = the code block -- one or more lines, starting with a space/tab
|
||||||
|
(?>
|
||||||
|
[ ]{'.'4'.'} # Lines must start with a tab or a tab-width of spaces
|
||||||
|
.*\n+
|
||||||
|
)+
|
||||||
|
)
|
||||||
|
((?=^[ ]{0,'.'4'.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
|
||||||
|
}xm',
|
||||||
|
[ $this , 'encode_code' ], $s);
|
||||||
|
|
||||||
|
return $text;
|
||||||
|
}
|
||||||
|
|
||||||
|
function encode_code($matches) {
|
||||||
|
return $this->token . ';' . base64_encode($matches[0]) . ';' ;
|
||||||
|
}
|
||||||
|
|
||||||
|
function decode_code($matches) {
|
||||||
|
return base64_decode($matches[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function putback_code($s) {
|
||||||
|
$text = preg_replace_callback('{' . $this->token . '\;(.*?)\;}xm',[ $this, 'decode_code' ], $s);
|
||||||
|
return $text;
|
||||||
|
}
|
||||||
|
|
||||||
|
function purify($s) {
|
||||||
|
$s = $this->protect_autolinks($s);
|
||||||
|
$s = purify_html($s);
|
||||||
|
$s = $this->unprotect_autolinks($s);
|
||||||
|
return $s;
|
||||||
|
}
|
||||||
|
|
||||||
|
function protect_autolinks($s) {
|
||||||
|
$s = preg_replace('/\<(https?\:\/\/)(.*?)\>/','[$1$2]($1$2)',$s);
|
||||||
|
return $s;
|
||||||
|
}
|
||||||
|
|
||||||
|
function unprotect_autolinks($s) {
|
||||||
|
return $s;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function escape($s) {
|
||||||
|
return htmlspecialchars($s,ENT_QUOTES,'UTF-8',false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function unescape($s) {
|
||||||
|
return htmlspecialchars_decode($s,ENT_QUOTES);
|
||||||
|
}
|
||||||
|
}
|
||||||
282
Zotlabs/Lib/NativeWiki.php
Normal file
282
Zotlabs/Lib/NativeWiki.php
Normal file
@@ -0,0 +1,282 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zotlabs\Lib;
|
||||||
|
|
||||||
|
define ( 'NWIKI_ITEM_RESOURCE_TYPE', 'nwiki' );
|
||||||
|
|
||||||
|
class NativeWiki {
|
||||||
|
|
||||||
|
|
||||||
|
static public 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['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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function create_wiki($channel, $observer_hash, $wiki, $acl) {
|
||||||
|
|
||||||
|
// Generate unique resource_id using the same method as item_message_id()
|
||||||
|
do {
|
||||||
|
$dups = false;
|
||||||
|
$resource_id = random_string();
|
||||||
|
$r = q("SELECT mid FROM item WHERE resource_id = '%s' AND resource_type = '%s' AND uid = %d LIMIT 1",
|
||||||
|
dbesc($resource_id),
|
||||||
|
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
|
||||||
|
intval($channel['channel_id'])
|
||||||
|
);
|
||||||
|
if($r)
|
||||||
|
$dups = true;
|
||||||
|
} while($dups == true);
|
||||||
|
|
||||||
|
$ac = $acl->get();
|
||||||
|
$mid = item_message_id();
|
||||||
|
|
||||||
|
$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['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'] = ACTIVITY_OBJ_WIKI;
|
||||||
|
$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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static public 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_type'])
|
||||||
|
);
|
||||||
|
if($q) {
|
||||||
|
$r = array_merge($r,$q);
|
||||||
|
}
|
||||||
|
xchan_query($r);
|
||||||
|
$sync_item = fetch_post_tags($r);
|
||||||
|
build_sync_packet($uid,array('wiki' => array(encode_item($sync_item[0],true))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete_wiki($channel_id,$observer_hash,$resource_id) {
|
||||||
|
|
||||||
|
$w = self::get_wiki($channel_id,$observer_hash,$resource_id);
|
||||||
|
$item = $w['wiki'];
|
||||||
|
if(! $item) {
|
||||||
|
return array('item' => null, 'success' => false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$drop = drop_item($item['id'], false, DROPITEM_NORMAL, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
info( t('Wiki files deleted successfully'));
|
||||||
|
|
||||||
|
return array('item' => $item, 'item_id' => $item['id'], 'success' => (($drop === 1) ? true : false));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static public 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 limit 1",
|
||||||
|
intval($channel_id),
|
||||||
|
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
|
||||||
|
dbesc($resource_id)
|
||||||
|
);
|
||||||
|
if(! $item) {
|
||||||
|
return array('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)),
|
||||||
|
'mimeType' => $mimeType,
|
||||||
|
'typelock' => $typelock
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static public 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)),
|
||||||
|
intval($uid)
|
||||||
|
);
|
||||||
|
|
||||||
|
if($item) {
|
||||||
|
return array('id' => $item[0]['id'], 'resource_id' => $item[0]['resource_id']);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return array('id' => null, 'resource_id' => null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static public 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
695
Zotlabs/Lib/NativeWikiPage.php
Normal file
695
Zotlabs/Lib/NativeWikiPage.php
Normal file
@@ -0,0 +1,695 @@
|
|||||||
|
<?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)))),
|
||||||
|
'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),
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
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))
|
||||||
|
];
|
||||||
|
|
||||||
|
return [ 'success' => true, 'page' => $page ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [ 'success' => false, 'item_id' => $c['item_id'], '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' => $filename, '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);
|
||||||
|
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('content' => $content, 'message' => 'No commit was provided', 'success' => false);
|
||||||
|
}
|
||||||
|
|
||||||
|
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||||
|
if (!$w['wiki']) {
|
||||||
|
return array('content' => $content, '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 [ 'content' => $content, '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)));
|
||||||
|
$pages[] = $m;
|
||||||
|
}
|
||||||
|
$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')
|
||||||
|
));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,8 +1,21 @@
|
|||||||
<?php /** @file */
|
<?php
|
||||||
|
|
||||||
namespace Zotlabs\Lib;
|
namespace Zotlabs\Lib;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Class for handling channel specific configurations.
|
||||||
|
*
|
||||||
|
* <b>PConfig</b> is used for channel specific configurations and takes a
|
||||||
|
* <i>channel_id</i> as identifier. It stores for example which features are
|
||||||
|
* enabled per channel. The storage is of size MEDIUMTEXT.
|
||||||
|
*
|
||||||
|
* @code{.php}$var = Zotlabs\Lib\PConfig::Get('uid', 'category', 'key');
|
||||||
|
* // with default value for non existent key
|
||||||
|
* $var = Zotlabs\Lib\PConfig::Get('uid', 'category', 'unsetkey', 'defaultvalue');@endcode
|
||||||
|
*
|
||||||
|
* The old (deprecated?) way to access a PConfig value is:
|
||||||
|
* @code{.php}$var = get_pconfig(local_channel(), 'category', 'key');@endcode
|
||||||
|
*/
|
||||||
class PConfig {
|
class PConfig {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -13,18 +26,18 @@ class PConfig {
|
|||||||
*
|
*
|
||||||
* @param string $uid
|
* @param string $uid
|
||||||
* The channel_id
|
* The channel_id
|
||||||
* @return void|false Nothing or false if $uid is false
|
* @return void|false Nothing or false if $uid is null or false
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static public function Load($uid) {
|
static public function Load($uid) {
|
||||||
if(is_null($uid) || $uid === false)
|
if(is_null($uid) || $uid === false)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(! array_key_exists($uid, \App::$config))
|
|
||||||
\App::$config[$uid] = array();
|
|
||||||
|
|
||||||
if(! is_array(\App::$config)) {
|
if(! is_array(\App::$config)) {
|
||||||
btlogger('App::$config not an array: ' . $uid);
|
btlogger('App::$config not an array');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(! array_key_exists($uid, \App::$config)) {
|
||||||
|
\App::$config[$uid] = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(! is_array(\App::$config[$uid])) {
|
if(! is_array(\App::$config[$uid])) {
|
||||||
@@ -63,26 +76,25 @@ class PConfig {
|
|||||||
* The category of the configuration value
|
* The category of the configuration value
|
||||||
* @param string $key
|
* @param string $key
|
||||||
* The configuration key to query
|
* The configuration key to query
|
||||||
* @param boolean $instore (deprecated, without function)
|
* @param mixed $default (optional, default false)
|
||||||
|
* Default value to return if key does not exist
|
||||||
* @return mixed Stored value or false if it does not exist
|
* @return mixed Stored value or false if it does not exist
|
||||||
*/
|
*/
|
||||||
|
static public function Get($uid, $family, $key, $default = false) {
|
||||||
static public function Get($uid,$family,$key,$instore = false) {
|
|
||||||
|
|
||||||
if(is_null($uid) || $uid === false)
|
if(is_null($uid) || $uid === false)
|
||||||
return false;
|
return $default;
|
||||||
|
|
||||||
if(! array_key_exists($uid, \App::$config))
|
if(! array_key_exists($uid, \App::$config))
|
||||||
self::Load($uid);
|
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 false;
|
return $default;
|
||||||
|
|
||||||
return ((! is_array(\App::$config[$uid][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \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])
|
? unserialize(\App::$config[$uid][$family][$key])
|
||||||
: \App::$config[$uid][$family][$key]
|
: \App::$config[$uid][$family][$key]
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -101,7 +113,6 @@ class PConfig {
|
|||||||
* The value to store
|
* The value to store
|
||||||
* @return mixed Stored $value or false
|
* @return mixed Stored $value or false
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static public function Set($uid, $family, $key, $value) {
|
static public function Set($uid, $family, $key, $value) {
|
||||||
|
|
||||||
// this catches subtle errors where this function has been called
|
// this catches subtle errors where this function has been called
|
||||||
@@ -119,7 +130,7 @@ class PConfig {
|
|||||||
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
|
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
|
||||||
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
|
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
|
||||||
|
|
||||||
if(get_pconfig($uid, $family, $key) === false) {
|
if(self::Get($uid, $family, $key) === false) {
|
||||||
if(! array_key_exists($uid, \App::$config))
|
if(! array_key_exists($uid, \App::$config))
|
||||||
\App::$config[$uid] = array();
|
\App::$config[$uid] = array();
|
||||||
if(! array_key_exists($family, \App::$config[$uid]))
|
if(! array_key_exists($family, \App::$config[$uid]))
|
||||||
@@ -131,7 +142,6 @@ class PConfig {
|
|||||||
dbesc($key),
|
dbesc($key),
|
||||||
dbesc($dbvalue)
|
dbesc($dbvalue)
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
@@ -141,7 +151,6 @@ class PConfig {
|
|||||||
dbesc($family),
|
dbesc($family),
|
||||||
dbesc($key)
|
dbesc($key)
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// keep a separate copy for all variables which were
|
// keep a separate copy for all variables which were
|
||||||
@@ -177,7 +186,6 @@ class PConfig {
|
|||||||
* The configuration key to delete
|
* The configuration key to delete
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static public function Delete($uid, $family, $key) {
|
static public function Delete($uid, $family, $key) {
|
||||||
|
|
||||||
if(is_null($uid) || $uid === false)
|
if(is_null($uid) || $uid === false)
|
||||||
@@ -185,16 +193,19 @@ class PConfig {
|
|||||||
|
|
||||||
$ret = false;
|
$ret = false;
|
||||||
|
|
||||||
if(array_key_exists($key, \App::$config[$uid][$family]))
|
if(array_key_exists($uid,\App::$config)
|
||||||
|
&& is_array(\App::$config['uid'])
|
||||||
|
&& array_key_exists($family,\App::$config['uid'])
|
||||||
|
&& array_key_exists($key, \App::$config[$uid][$family]))
|
||||||
unset(\App::$config[$uid][$family][$key]);
|
unset(\App::$config[$uid][$family][$key]);
|
||||||
$ret = q("DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s'",
|
|
||||||
intval($uid),
|
$ret = q("DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s'",
|
||||||
dbesc($family),
|
intval($uid),
|
||||||
dbesc($key)
|
dbesc($family),
|
||||||
);
|
dbesc($key)
|
||||||
|
);
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
146
Zotlabs/Lib/Permcat.php
Normal file
146
Zotlabs/Lib/Permcat.php
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zotlabs\Lib;
|
||||||
|
|
||||||
|
use \Zotlabs\Access as Zaccess;
|
||||||
|
|
||||||
|
class Permcat {
|
||||||
|
|
||||||
|
private $permcats = [];
|
||||||
|
|
||||||
|
public function __construct($channel_id) {
|
||||||
|
|
||||||
|
$perms = [];
|
||||||
|
|
||||||
|
// first check role perms for a perms_connect setting
|
||||||
|
|
||||||
|
$role = get_pconfig($channel_id,'system','permissions_role');
|
||||||
|
if($role) {
|
||||||
|
$x = Zaccess\PermissionRoles::role_perms($role);
|
||||||
|
if($x['perms_connect']) {
|
||||||
|
$perms = Zaccess\Permissions::FilledPerms($x['perms_connect']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no role perms it may be a custom role, see if there any autoperms
|
||||||
|
|
||||||
|
if(! $perms) {
|
||||||
|
$perms = Zaccess\Permissions::FilledAutoPerms($channel_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no autoperms it may be a custom role with manual perms
|
||||||
|
|
||||||
|
if(! $perms) {
|
||||||
|
$r = q("select channel_hash from channel where channel_id = %d",
|
||||||
|
intval($channel_id)
|
||||||
|
);
|
||||||
|
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) {
|
||||||
|
$perms[$xv['k']] = intval($xv['v']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// nothing was found - create a filled permission array where all permissions are 0
|
||||||
|
|
||||||
|
if(! $perms) {
|
||||||
|
$perms = Zaccess\Permissions::FilledPerms([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->permcats[] = [
|
||||||
|
'name' => 'default',
|
||||||
|
'localname' => t('default','permcat'),
|
||||||
|
'perms' => Zaccess\Permissions::Operms($perms),
|
||||||
|
'system' => 1
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
$p = $this->load_permcats($channel_id);
|
||||||
|
if($p) {
|
||||||
|
for($x = 0; $x < count($p); $x++) {
|
||||||
|
$this->permcats[] = [
|
||||||
|
'name' => $p[$x][0],
|
||||||
|
'localname' => $p[$x][1],
|
||||||
|
'perms' => Zaccess\Permissions::Operms(Zaccess\Permissions::FilledPerms($p[$x][2])),
|
||||||
|
'system' => intval($p[$x][3])
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function listing() {
|
||||||
|
return $this->permcats;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fetch($name) {
|
||||||
|
if($name && $this->permcats) {
|
||||||
|
foreach($this->permcats as $permcat) {
|
||||||
|
if(strcasecmp($permcat['name'],$name) === 0) {
|
||||||
|
return $permcat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ['error' => true];
|
||||||
|
}
|
||||||
|
|
||||||
|
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'),
|
||||||
|
[ '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
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
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 ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
call_hooks('permcats',$permcats);
|
||||||
|
|
||||||
|
return $permcats;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function find_permcat($arr,$name) {
|
||||||
|
if((! $arr) || (! $name))
|
||||||
|
return false;
|
||||||
|
foreach($arr as $p)
|
||||||
|
if($p['name'] == $name)
|
||||||
|
return $p['value'];
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function update($channel_id, $name,$permarr) {
|
||||||
|
PConfig::Set($channel_id,'permcat',$name,$permarr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function delete($channel_id,$name) {
|
||||||
|
PConfig::Delete($channel_id,'permcat',$name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ require_once("include/text.php");
|
|||||||
* permission settings for an item with an empty ACL.
|
* permission settings for an item with an empty ACL.
|
||||||
* i.e the caption, icon, and tooltip for the no-ACL option in the ACL dialog.
|
* i.e the caption, icon, and tooltip for the no-ACL option in the ACL dialog.
|
||||||
*/
|
*/
|
||||||
class PermissionDescription {
|
class PermissionDescription {
|
||||||
|
|
||||||
private $global_perm;
|
private $global_perm;
|
||||||
private $channel_perm;
|
private $channel_perm;
|
||||||
@@ -20,14 +20,17 @@ class PermissionDescription {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor is private.
|
* Constructor is private.
|
||||||
* Use static methods fromGlobalPermission(), fromStandalonePermission(), or fromDescription()
|
* Use static methods fromGlobalPermission(), fromStandalonePermission(),
|
||||||
* to create instances.
|
* or fromDescription() to create instances.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
* @param int $global_perm
|
||||||
|
* @param int $channel_perm
|
||||||
|
* @param string $description (optional) default empty
|
||||||
*/
|
*/
|
||||||
private function __construct($global_perm, $channel_perm, $description = '') {
|
private function __construct($global_perm, $channel_perm, $description = '') {
|
||||||
|
|
||||||
$this->global_perm = $global_perm;
|
$this->global_perm = $global_perm;
|
||||||
$this->channel_perm = $channel_perm;
|
$this->channel_perm = $channel_perm;
|
||||||
|
|
||||||
$this->fallback_description = ($description == '') ? t('Visible to your default audience') : $description;
|
$this->fallback_description = ($description == '') ? t('Visible to your default audience') : $description;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +46,6 @@ class PermissionDescription {
|
|||||||
return new PermissionDescription('', 0x80000, $description);
|
return new PermissionDescription('', 0x80000, $description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use this method only if the interpretation of an empty ACL doesn't fall back to a global
|
* Use this method only if the interpretation of an empty ACL doesn't fall back to a global
|
||||||
* default permission. You should pass one of the constants from boot.php - PERMS_PUBLIC,
|
* default permission. You should pass one of the constants from boot.php - PERMS_PUBLIC,
|
||||||
@@ -56,10 +58,10 @@ class PermissionDescription {
|
|||||||
|
|
||||||
$result = new PermissionDescription('', $perm);
|
$result = new PermissionDescription('', $perm);
|
||||||
|
|
||||||
$checkPerm = $this->get_permission_description();
|
$checkPerm = $result->get_permission_description();
|
||||||
if ($checkPerm == $this->fallback_description) {
|
if($checkPerm == $result->fallback_description) {
|
||||||
$result = null;
|
$result = null;
|
||||||
logger('null PermissionDescription from unknown standalone permission: ' . $perm ,LOGGER_DEBUG, LOG_ERROR);
|
logger('null PermissionDescription from unknown standalone permission: ' . $perm, LOGGER_DEBUG, LOG_ERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
@@ -80,19 +82,19 @@ class PermissionDescription {
|
|||||||
|
|
||||||
$global_perms = \Zotlabs\Access\Permissions::Perms();
|
$global_perms = \Zotlabs\Access\Permissions::Perms();
|
||||||
|
|
||||||
if (array_key_exists($permname, $global_perms)) {
|
if(array_key_exists($permname, $global_perms)) {
|
||||||
|
|
||||||
$channelPerm = \Zotlabs\Access\PermissionLimits::Get(\App::$channel['channel_id'],$permname);
|
$channelPerm = \Zotlabs\Access\PermissionLimits::Get(\App::$channel['channel_id'], $permname);
|
||||||
|
|
||||||
$result = new PermissionDescription('', $channelPerm);
|
$result = new PermissionDescription('', $channelPerm);
|
||||||
} else {
|
} else {
|
||||||
// The acl dialog can handle null arguments, but it shouldn't happen
|
// The acl dialog can handle null arguments, but it shouldn't happen
|
||||||
logger('null PermissionDescription from unknown global permission: ' . $permname ,LOGGER_DEBUG, LOG_ERROR);
|
logger('null PermissionDescription from unknown global permission: ' . $permname, LOGGER_DEBUG, LOG_ERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a localized description of the permission, or a generic message if the permission
|
* Gets a localized description of the permission, or a generic message if the permission
|
||||||
* is unknown.
|
* is unknown.
|
||||||
@@ -102,7 +104,6 @@ class PermissionDescription {
|
|||||||
public function get_permission_description() {
|
public function get_permission_description() {
|
||||||
|
|
||||||
switch($this->channel_perm) {
|
switch($this->channel_perm) {
|
||||||
|
|
||||||
case 0: return t('Only me');
|
case 0: return t('Only me');
|
||||||
case PERMS_PUBLIC: return t('Public');
|
case PERMS_PUBLIC: return t('Public');
|
||||||
case PERMS_NETWORK: return t('Anybody in the $Projectname network');
|
case PERMS_NETWORK: return t('Anybody in the $Projectname network');
|
||||||
@@ -124,7 +125,6 @@ class PermissionDescription {
|
|||||||
public function get_permission_icon() {
|
public function get_permission_icon() {
|
||||||
|
|
||||||
switch($this->channel_perm) {
|
switch($this->channel_perm) {
|
||||||
|
|
||||||
case 0:/* only me */ return 'fa-eye-slash';
|
case 0:/* only me */ return 'fa-eye-slash';
|
||||||
case PERMS_PUBLIC: return 'fa-globe';
|
case PERMS_PUBLIC: return 'fa-globe';
|
||||||
case PERMS_NETWORK: return 'fa-share-alt-square'; // fa-share-alt-square is very similiar to the hubzilla logo, but we should create our own logo class to use
|
case PERMS_NETWORK: return 'fa-share-alt-square'; // fa-share-alt-square is very similiar to the hubzilla logo, but we should create our own logo class to use
|
||||||
@@ -137,7 +137,6 @@ class PermissionDescription {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a localized description of where the permission came from, if this is known.
|
* Returns a localized description of where the permission came from, if this is known.
|
||||||
* If it's not know, or if the permission is standalone and didn't come from a default
|
* If it's not know, or if the permission is standalone and didn't come from a default
|
||||||
@@ -148,7 +147,6 @@ class PermissionDescription {
|
|||||||
public function get_permission_origin_description() {
|
public function get_permission_origin_description() {
|
||||||
|
|
||||||
switch($this->global_perm) {
|
switch($this->global_perm) {
|
||||||
|
|
||||||
case PERMS_R_STREAM: return t('This is your default setting for the audience of your normal stream, and posts.');
|
case PERMS_R_STREAM: return t('This is your default setting for the audience of your normal stream, and posts.');
|
||||||
case PERMS_R_PROFILE: return t('This is your default setting for who can view your default channel profile');
|
case PERMS_R_PROFILE: return t('This is your default setting for who can view your default channel profile');
|
||||||
case PERMS_R_ABOOK: return t('This is your default setting for who can view your connections');
|
case PERMS_R_ABOOK: return t('This is your default setting for who can view your connections');
|
||||||
|
|||||||
28
Zotlabs/Lib/SConfig.php
Normal file
28
Zotlabs/Lib/SConfig.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zotlabs\Lib;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Account configuration storage is built on top of the under-utilised xconfig.
|
||||||
|
*
|
||||||
|
* @see XConfig
|
||||||
|
*/
|
||||||
|
class SConfig {
|
||||||
|
|
||||||
|
static public function Load($server_id) {
|
||||||
|
return XConfig::Load('s_' . $server_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function Get($server_id,$family,$key,$default = false) {
|
||||||
|
return XConfig::Get('s_' . $server_id,$family,$key, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function Set($server_id,$family,$key,$value) {
|
||||||
|
return XConfig::Set('s_' . $server_id,$family,$key,$value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function Delete($server_id,$family,$key) {
|
||||||
|
return XConfig::Delete('s_' . $server_id,$family,$key);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -19,6 +19,9 @@ class System {
|
|||||||
static public function get_project_version() {
|
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']) && \App::$config['system']['hide_version'])
|
||||||
return '';
|
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'];
|
||||||
|
|
||||||
return self::get_std_version();
|
return self::get_std_version();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,20 +35,37 @@ class System {
|
|||||||
static public function get_notify_icon() {
|
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']) && \App::$config['system']['email_notify_icon_url'])
|
||||||
return \App::$config['system']['email_notify_icon_url'];
|
return \App::$config['system']['email_notify_icon_url'];
|
||||||
return z_root() . '/images/hz-white-32.png';
|
return z_root() . DEFAULT_NOTIFY_ICON;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function get_site_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']) && \App::$config['system']['site_icon_url'])
|
||||||
return \App::$config['system']['site_icon_url'];
|
return \App::$config['system']['site_icon_url'];
|
||||||
return z_root() . '/images/hz-32.png';
|
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'])
|
||||||
|
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'])
|
||||||
|
return \App::$config['system']['project_srclink'];
|
||||||
|
return 'https://github.com/redmatrix/hubzilla';
|
||||||
|
}
|
||||||
|
|
||||||
static public function get_server_role() {
|
static public function get_server_role() {
|
||||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['server_role'])
|
return 'pro';
|
||||||
return \App::$config['system']['server_role'];
|
}
|
||||||
return 'standard';
|
|
||||||
|
|
||||||
|
static public function get_zot_revision() {
|
||||||
|
$x = [ 'revision' => ZOT_REVISION ];
|
||||||
|
call_hooks('zot_revision',$x);
|
||||||
|
return $x['revision'];
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function get_std_version() {
|
static public function get_std_version() {
|
||||||
@@ -54,5 +74,12 @@ class System {
|
|||||||
return '0.0.0';
|
return '0.0.0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static public function compatible_project($p) {
|
||||||
|
|
||||||
|
if(get_directory_realm() != DIRECTORY_REALM)
|
||||||
|
return true;
|
||||||
|
if(in_array(strtolower($p),['hubzilla','zap','red']))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
Zotlabs/Lib/Techlevels.php
Normal file
21
Zotlabs/Lib/Techlevels.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zotlabs\Lib;
|
||||||
|
|
||||||
|
|
||||||
|
class Techlevels {
|
||||||
|
|
||||||
|
static public function levels() {
|
||||||
|
$techlevels = [
|
||||||
|
'0' => t('0. Beginner/Basic'),
|
||||||
|
'1' => t('1. Novice - not skilled but willing to learn'),
|
||||||
|
'2' => t('2. Intermediate - somewhat comfortable'),
|
||||||
|
'3' => t('3. Advanced - very comfortable'),
|
||||||
|
'4' => t('4. Expert - I can write computer code'),
|
||||||
|
'5' => t('5. Wizard - I probably know more than you do')
|
||||||
|
];
|
||||||
|
return $techlevels;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -29,6 +29,7 @@ class ThreadItem {
|
|||||||
private $visiting = false;
|
private $visiting = false;
|
||||||
private $channel = null;
|
private $channel = null;
|
||||||
private $display_mode = 'normal';
|
private $display_mode = 'normal';
|
||||||
|
private $reload = '';
|
||||||
|
|
||||||
|
|
||||||
public function __construct($data) {
|
public function __construct($data) {
|
||||||
@@ -37,14 +38,14 @@ class ThreadItem {
|
|||||||
$this->toplevel = ($this->get_id() == $this->get_data_value('parent'));
|
$this->toplevel = ($this->get_id() == $this->get_data_value('parent'));
|
||||||
|
|
||||||
// Prepare the children
|
// Prepare the children
|
||||||
if(count($data['children'])) {
|
if($data['children']) {
|
||||||
foreach($data['children'] as $item) {
|
foreach($data['children'] as $item) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Only add those that will be displayed
|
* Only add those that will be displayed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if((! visible_activity($item)) || array_key_exists('author_blocked',$item)) {
|
if((! visible_activity($item)) || array_key_exists('blocked',$item)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +83,8 @@ class ThreadItem {
|
|||||||
$dropping = false;
|
$dropping = false;
|
||||||
$star = false;
|
$star = false;
|
||||||
$isstarred = "unstarred fa-star-o";
|
$isstarred = "unstarred fa-star-o";
|
||||||
$indent = '';
|
$is_comment = false;
|
||||||
|
$is_item = false;
|
||||||
$osparkle = '';
|
$osparkle = '';
|
||||||
$total_children = $this->count_descendants();
|
$total_children = $this->count_descendants();
|
||||||
$unseen_comments = (($item['real_uid']) ? 0 : $this->count_unseen_descendants());
|
$unseen_comments = (($item['real_uid']) ? 0 : $this->count_unseen_descendants());
|
||||||
@@ -100,10 +102,23 @@ class ThreadItem {
|
|||||||
if($item['author']['xchan_network'] === 'rss')
|
if($item['author']['xchan_network'] === 'rss')
|
||||||
$shareable = true;
|
$shareable = true;
|
||||||
|
|
||||||
|
|
||||||
$mode = $conv->get_mode();
|
$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'])
|
if(local_channel() && $observer['xchan_hash'] === $item['author_xchan'])
|
||||||
$edpost = array(z_root()."/editpost/".$item['id'], t("Edit"));
|
$edpost = array(z_root() . '/' . $edlink . '/' . $item['id'], t('Edit'));
|
||||||
else
|
else
|
||||||
$edpost = false;
|
$edpost = false;
|
||||||
|
|
||||||
@@ -136,7 +151,7 @@ class ThreadItem {
|
|||||||
$filer = ((($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) ? t("Save to Folder") : false);
|
$filer = ((($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) ? t("Save to Folder") : false);
|
||||||
|
|
||||||
$profile_avatar = $item['author']['xchan_photo_m'];
|
$profile_avatar = $item['author']['xchan_photo_m'];
|
||||||
$profile_link = chanlink_url($item['author']['xchan_url']);
|
$profile_link = chanlink_hash($item['author_xchan']);
|
||||||
$profile_name = $item['author']['xchan_name'];
|
$profile_name = $item['author']['xchan_name'];
|
||||||
|
|
||||||
$location = format_location($item);
|
$location = format_location($item);
|
||||||
@@ -152,7 +167,7 @@ class ThreadItem {
|
|||||||
$response_verbs[] = 'attendyes';
|
$response_verbs[] = 'attendyes';
|
||||||
$response_verbs[] = 'attendno';
|
$response_verbs[] = 'attendno';
|
||||||
$response_verbs[] = 'attendmaybe';
|
$response_verbs[] = 'attendmaybe';
|
||||||
if($this->is_commentable()) {
|
if($this->is_commentable() && $observer) {
|
||||||
$isevent = true;
|
$isevent = true;
|
||||||
$attend = array( t('I will attend'), t('I will not attend'), t('I might attend'));
|
$attend = array( t('I will attend'), t('I will not attend'), t('I might attend'));
|
||||||
}
|
}
|
||||||
@@ -163,7 +178,7 @@ class ThreadItem {
|
|||||||
$response_verbs[] = 'agree';
|
$response_verbs[] = 'agree';
|
||||||
$response_verbs[] = 'disagree';
|
$response_verbs[] = 'disagree';
|
||||||
$response_verbs[] = 'abstain';
|
$response_verbs[] = 'abstain';
|
||||||
if($this->is_commentable()) {
|
if($this->is_commentable() && $observer) {
|
||||||
$conlabels = array( t('I agree'), t('I disagree'), t('I abstain'));
|
$conlabels = array( t('I agree'), t('I disagree'), t('I abstain'));
|
||||||
$canvote = true;
|
$canvote = true;
|
||||||
}
|
}
|
||||||
@@ -181,9 +196,9 @@ class ThreadItem {
|
|||||||
|
|
||||||
$like_count = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid']] : '');
|
$like_count = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid']] : '');
|
||||||
$like_list = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid'] . '-l'] : '');
|
$like_list = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid'] . '-l'] : '');
|
||||||
if (count($like_list) > MAX_LIKERS) {
|
if (($like_list) && (count($like_list) > MAX_LIKERS)) {
|
||||||
$like_list_part = array_slice($like_list, 0, MAX_LIKERS);
|
$like_list_part = array_slice($like_list, 0, MAX_LIKERS);
|
||||||
array_push($like_list_part, '<a href="#" data-toggle="modal" data-target="#likeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>');
|
array_push($like_list_part, '<a class="dropdown-item" href="#" data-toggle="modal" data-target="#likeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>');
|
||||||
} else {
|
} else {
|
||||||
$like_list_part = '';
|
$like_list_part = '';
|
||||||
}
|
}
|
||||||
@@ -193,9 +208,9 @@ class ThreadItem {
|
|||||||
$dislike_count = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid']] : '');
|
$dislike_count = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid']] : '');
|
||||||
$dislike_list = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid'] . '-l'] : '');
|
$dislike_list = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid'] . '-l'] : '');
|
||||||
$dislike_button_label = tt('Dislike','Dislikes',$dislike_count,'noun');
|
$dislike_button_label = tt('Dislike','Dislikes',$dislike_count,'noun');
|
||||||
if (count($dislike_list) > MAX_LIKERS) {
|
if (($dislike_list) && (count($dislike_list) > MAX_LIKERS)) {
|
||||||
$dislike_list_part = array_slice($dislike_list, 0, MAX_LIKERS);
|
$dislike_list_part = array_slice($dislike_list, 0, MAX_LIKERS);
|
||||||
array_push($dislike_list_part, '<a href="#" data-toggle="modal" data-target="#dislikeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>');
|
array_push($dislike_list_part, '<a class="dropdown-item" href="#" data-toggle="modal" data-target="#dislikeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>');
|
||||||
} else {
|
} else {
|
||||||
$dislike_list_part = '';
|
$dislike_list_part = '';
|
||||||
}
|
}
|
||||||
@@ -232,7 +247,7 @@ class ThreadItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$indent = 'comment';
|
$is_comment = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -250,8 +265,6 @@ class ThreadItem {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$server_role = get_config('system','server_role');
|
|
||||||
|
|
||||||
$has_bookmarks = false;
|
$has_bookmarks = false;
|
||||||
if(is_array($item['term'])) {
|
if(is_array($item['term'])) {
|
||||||
foreach($item['term'] as $t) {
|
foreach($item['term'] as $t) {
|
||||||
@@ -264,7 +277,7 @@ class ThreadItem {
|
|||||||
if(($item['obj_type'] === ACTIVITY_OBJ_EVENT) && $conv->get_profile_owner() == local_channel())
|
if(($item['obj_type'] === ACTIVITY_OBJ_EVENT) && $conv->get_profile_owner() == local_channel())
|
||||||
$has_event = true;
|
$has_event = true;
|
||||||
|
|
||||||
if($this->is_commentable()) {
|
if($this->is_commentable() && $observer) {
|
||||||
$like = array( t("I like this \x28toggle\x29"), t("like"));
|
$like = array( t("I like this \x28toggle\x29"), t("like"));
|
||||||
$dislike = array( t("I don't like this \x28toggle\x29"), t("dislike"));
|
$dislike = array( t("I don't like this \x28toggle\x29"), t("dislike"));
|
||||||
}
|
}
|
||||||
@@ -276,13 +289,13 @@ class ThreadItem {
|
|||||||
|
|
||||||
$keep_reports = intval(get_config('system','expire_delivery_reports'));
|
$keep_reports = intval(get_config('system','expire_delivery_reports'));
|
||||||
if($keep_reports === 0)
|
if($keep_reports === 0)
|
||||||
$keep_reports = 30;
|
$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)
|
if((! get_config('system','disable_dreport')) && strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC',"now - $keep_reports days")) > 0)
|
||||||
$dreport = t('Delivery Report');
|
$dreport = t('Delivery Report');
|
||||||
|
|
||||||
if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0)
|
if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0)
|
||||||
$indent .= ' shiny';
|
$is_new = true;
|
||||||
|
|
||||||
|
|
||||||
localize_item($item);
|
localize_item($item);
|
||||||
@@ -295,7 +308,7 @@ class ThreadItem {
|
|||||||
$owner_address = substr($item['owner']['xchan_addr'],0,strpos($item['owner']['xchan_addr'],'@'));
|
$owner_address = substr($item['owner']['xchan_addr'],0,strpos($item['owner']['xchan_addr'],'@'));
|
||||||
$viewthread = $item['llink'];
|
$viewthread = $item['llink'];
|
||||||
if($conv->get_mode() === 'channel')
|
if($conv->get_mode() === 'channel')
|
||||||
$viewthread = z_root() . '/channel/' . $owner_address . '?f=&mid=' . $item['mid'];
|
$viewthread = z_root() . '/channel/' . $owner_address . '?f=&mid=' . urlencode($item['mid']);
|
||||||
|
|
||||||
$comment_count_txt = sprintf( tt('%d comment','%d comments',$total_children),$total_children );
|
$comment_count_txt = sprintf( tt('%d comment','%d comments',$total_children),$total_children );
|
||||||
$list_unseen_txt = (($unseen_comments) ? sprintf('%d unseen',$unseen_comments) : '');
|
$list_unseen_txt = (($unseen_comments) ? sprintf('%d unseen',$unseen_comments) : '');
|
||||||
@@ -311,6 +324,7 @@ class ThreadItem {
|
|||||||
$tmp_item = array(
|
$tmp_item = array(
|
||||||
'template' => $this->get_template(),
|
'template' => $this->get_template(),
|
||||||
'mode' => $mode,
|
'mode' => $mode,
|
||||||
|
'item_type' => intval($item['item_type']),
|
||||||
'type' => implode("",array_slice(explode("/",$item['verb']),-1)),
|
'type' => implode("",array_slice(explode("/",$item['verb']),-1)),
|
||||||
'body' => $body['html'],
|
'body' => $body['html'],
|
||||||
'tags' => $body['tags'],
|
'tags' => $body['tags'],
|
||||||
@@ -335,7 +349,8 @@ class ThreadItem {
|
|||||||
'wall' => t('Wall-to-Wall'),
|
'wall' => t('Wall-to-Wall'),
|
||||||
'vwall' => t('via Wall-To-Wall:'),
|
'vwall' => t('via Wall-To-Wall:'),
|
||||||
'profile_url' => $profile_link,
|
'profile_url' => $profile_link,
|
||||||
'item_photo_menu' => item_photo_menu($item),
|
'thread_action_menu' => thread_action_menu($item,$conv->get_mode()),
|
||||||
|
'thread_author_menu' => thread_author_menu($item,$conv->get_mode()),
|
||||||
'dreport' => $dreport,
|
'dreport' => $dreport,
|
||||||
'name' => $profile_name,
|
'name' => $profile_name,
|
||||||
'thumb' => $profile_avatar,
|
'thumb' => $profile_avatar,
|
||||||
@@ -355,7 +370,13 @@ class ThreadItem {
|
|||||||
'unverified' => $unverified,
|
'unverified' => $unverified,
|
||||||
'forged' => $forged,
|
'forged' => $forged,
|
||||||
'location' => $location,
|
'location' => $location,
|
||||||
'indent' => $indent,
|
'divider' => get_pconfig($conv->get_profile_owner(),'system','item_divider'),
|
||||||
|
'attend_label' => t('Attend'),
|
||||||
|
'attend_title' => t('Attendance Options'),
|
||||||
|
'vote_label' => t('Vote'),
|
||||||
|
'vote_title' => t('Voting Options'),
|
||||||
|
'is_comment' => $is_comment,
|
||||||
|
'is_new' => $is_new,
|
||||||
'owner_url' => $this->get_owner_url(),
|
'owner_url' => $this->get_owner_url(),
|
||||||
'owner_photo' => $this->get_owner_photo(),
|
'owner_photo' => $this->get_owner_photo(),
|
||||||
'owner_name' => $this->get_owner_name(),
|
'owner_name' => $this->get_owner_name(),
|
||||||
@@ -364,7 +385,7 @@ class ThreadItem {
|
|||||||
'has_tags' => $has_tags,
|
'has_tags' => $has_tags,
|
||||||
'reactions' => $this->reactions,
|
'reactions' => $this->reactions,
|
||||||
// Item toolbar buttons
|
// Item toolbar buttons
|
||||||
'emojis' => (($this->is_toplevel() && $this->is_commentable() && feature_enabled($conv->get_profile_owner(),'emojis')) ? '1' : ''),
|
'emojis' => (($this->is_toplevel() && $this->is_commentable() && $observer && feature_enabled($conv->get_profile_owner(),'emojis')) ? '1' : ''),
|
||||||
'like' => $like,
|
'like' => $like,
|
||||||
'dislike' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike : ''),
|
'dislike' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike : ''),
|
||||||
'share' => $share,
|
'share' => $share,
|
||||||
@@ -401,9 +422,10 @@ class ThreadItem {
|
|||||||
'showlike' => $showlike,
|
'showlike' => $showlike,
|
||||||
'showdislike' => $showdislike,
|
'showdislike' => $showdislike,
|
||||||
'comment' => $this->get_comment_box($indent),
|
'comment' => $this->get_comment_box($indent),
|
||||||
'previewing' => ($conv->is_preview() ? ' preview ' : ''),
|
'previewing' => ($conv->is_preview() ? true : false ),
|
||||||
|
'preview_lbl' => t('This is an unsaved preview'),
|
||||||
'wait' => t('Please wait'),
|
'wait' => t('Please wait'),
|
||||||
'submid' => substr($item['mid'],0,32),
|
'submid' => str_replace(['+','='], ['',''], base64_encode($item['mid'])),
|
||||||
'thread_level' => $thread_level
|
'thread_level' => $thread_level
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -474,6 +496,14 @@ class ThreadItem {
|
|||||||
return $this->threaded;
|
return $this->threaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function set_reload($val) {
|
||||||
|
$this->reload = $val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_reload() {
|
||||||
|
return $this->reload;
|
||||||
|
}
|
||||||
|
|
||||||
public function set_commentable($val) {
|
public function set_commentable($val) {
|
||||||
$this->commentable = $val;
|
$this->commentable = $val;
|
||||||
foreach($this->get_children() as $child)
|
foreach($this->get_children() as $child)
|
||||||
@@ -707,11 +737,10 @@ class ThreadItem {
|
|||||||
call_hooks('comment_buttons',$arr);
|
call_hooks('comment_buttons',$arr);
|
||||||
$comment_buttons = $arr['comment_buttons'];
|
$comment_buttons = $arr['comment_buttons'];
|
||||||
|
|
||||||
|
|
||||||
$comment_box = replace_macros($template,array(
|
$comment_box = replace_macros($template,array(
|
||||||
'$return_path' => '',
|
'$return_path' => '',
|
||||||
'$threaded' => $this->is_threaded(),
|
'$threaded' => $this->is_threaded(),
|
||||||
'$jsreload' => '', //(($conv->get_mode() === 'display') ? $_SESSION['return_url'] : ''),
|
'$jsreload' => $conv->reload,
|
||||||
'$type' => (($conv->get_mode() === 'channel') ? 'wall-comment' : 'net-comment'),
|
'$type' => (($conv->get_mode() === 'channel') ? 'wall-comment' : 'net-comment'),
|
||||||
'$id' => $this->get_id(),
|
'$id' => $this->get_id(),
|
||||||
'$parent' => $this->get_id(),
|
'$parent' => $this->get_id(),
|
||||||
@@ -729,15 +758,21 @@ class ThreadItem {
|
|||||||
'$edquote' => t('Quote'),
|
'$edquote' => t('Quote'),
|
||||||
'$edcode' => t('Code'),
|
'$edcode' => t('Code'),
|
||||||
'$edimg' => t('Image'),
|
'$edimg' => t('Image'),
|
||||||
|
'$edatt' => t('Attach File'),
|
||||||
'$edurl' => t('Insert Link'),
|
'$edurl' => t('Insert Link'),
|
||||||
'$edvideo' => t('Video'),
|
'$edvideo' => t('Video'),
|
||||||
'$preview' => t('Preview'), // ((feature_enabled($conv->get_profile_owner(),'preview')) ? t('Preview') : ''),
|
'$preview' => t('Preview'), // ((feature_enabled($conv->get_profile_owner(),'preview')) ? t('Preview') : ''),
|
||||||
'$indent' => $indent,
|
'$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),
|
'$feature_encrypt' => ((feature_enabled($conv->get_profile_owner(),'content_encrypt')) ? true : false),
|
||||||
'$encrypt' => t('Encrypt text'),
|
'$encrypt' => t('Encrypt text'),
|
||||||
'$cipher' => $conv->get_cipher(),
|
'$cipher' => $conv->get_cipher(),
|
||||||
'$sourceapp' => \App::$sourcename
|
'$sourceapp' => \App::$sourcename,
|
||||||
|
'$observer' => get_observer_hash(),
|
||||||
|
'$anoncomments' => ((($conv->get_mode() === 'channel' || $conv->get_mode() === 'display') && perm_is_allowed($conv->get_profile_owner(),'','post_comments')) ? true : false),
|
||||||
|
'$anonname' => [ 'anonname', t('Your full name (required)') ],
|
||||||
|
'$anonmail' => [ 'anonmail', t('Your email address (required)') ],
|
||||||
|
'$anonurl' => [ 'anonurl', t('Your website URL (optional)') ]
|
||||||
));
|
));
|
||||||
|
|
||||||
return $comment_box;
|
return $comment_box;
|
||||||
@@ -761,7 +796,7 @@ class ThreadItem {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if($this->is_toplevel() && ($this->get_data_value('author_xchan') != $this->get_data_value('owner_xchan'))) {
|
if($this->is_toplevel() && ($this->get_data_value('author_xchan') != $this->get_data_value('owner_xchan'))) {
|
||||||
$this->owner_url = chanlink_url($this->data['owner']['xchan_url']);
|
$this->owner_url = chanlink_hash($this->data['owner']['xchan_hash']);
|
||||||
$this->owner_photo = $this->data['owner']['xchan_photo_m'];
|
$this->owner_photo = $this->data['owner']['xchan_photo_m'];
|
||||||
$this->owner_name = $this->data['owner']['xchan_name'];
|
$this->owner_name = $this->data['owner']['xchan_name'];
|
||||||
$this->wall_to_wall = true;
|
$this->wall_to_wall = true;
|
||||||
|
|||||||
@@ -18,18 +18,21 @@ class ThreadStream {
|
|||||||
private $observer = null;
|
private $observer = null;
|
||||||
private $writable = false;
|
private $writable = false;
|
||||||
private $commentable = false;
|
private $commentable = false;
|
||||||
|
private $uploadable = false;
|
||||||
private $profile_owner = 0;
|
private $profile_owner = 0;
|
||||||
private $preview = false;
|
private $preview = false;
|
||||||
private $prepared_item = '';
|
private $prepared_item = '';
|
||||||
|
public $reload = '';
|
||||||
private $cipher = 'aes256';
|
private $cipher = 'aes256';
|
||||||
|
|
||||||
// $prepared_item is for use by alternate conversation structures such as photos
|
// $prepared_item is for use by alternate conversation structures such as photos
|
||||||
// wherein we've already prepared a top level item which doesn't look anything like
|
// wherein we've already prepared a top level item which doesn't look anything like
|
||||||
// a normal "post" item
|
// a normal "post" item
|
||||||
|
|
||||||
public function __construct($mode, $preview, $prepared_item = '') {
|
public function __construct($mode, $preview, $uploadable, $prepared_item = '') {
|
||||||
$this->set_mode($mode);
|
$this->set_mode($mode);
|
||||||
$this->preview = $preview;
|
$this->preview = $preview;
|
||||||
|
$this->uploadable = $uploadable;
|
||||||
$this->prepared_item = $prepared_item;
|
$this->prepared_item = $prepared_item;
|
||||||
$c = ((local_channel()) ? get_pconfig(local_channel(),'system','default_cipher') : '');
|
$c = ((local_channel()) ? get_pconfig(local_channel(),'system','default_cipher') : '');
|
||||||
if($c)
|
if($c)
|
||||||
@@ -51,15 +54,34 @@ class ThreadStream {
|
|||||||
$this->profile_owner = local_channel();
|
$this->profile_owner = local_channel();
|
||||||
$this->writable = true;
|
$this->writable = true;
|
||||||
break;
|
break;
|
||||||
|
case 'pubstream':
|
||||||
|
$this->profile_owner = local_channel();
|
||||||
|
$this->writable = ((local_channel()) ? true : false);
|
||||||
|
break;
|
||||||
|
case 'hq':
|
||||||
|
$this->profile_owner = local_channel();
|
||||||
|
$this->writable = true;
|
||||||
|
break;
|
||||||
case 'channel':
|
case 'channel':
|
||||||
$this->profile_owner = \App::$profile['profile_uid'];
|
$this->profile_owner = \App::$profile['profile_uid'];
|
||||||
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||||
break;
|
break;
|
||||||
|
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'];
|
||||||
|
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'];
|
||||||
|
break;
|
||||||
case 'display':
|
case 'display':
|
||||||
// in this mode we set profile_owner after initialisation (from conversation()) and then
|
// in this mode we set profile_owner after initialisation (from conversation()) and then
|
||||||
// pull some trickery which allows us to re-invoke this function afterward
|
// pull some trickery which allows us to re-invoke this function afterward
|
||||||
// it's an ugly hack so FIXME
|
// it's an ugly hack so @FIXME
|
||||||
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||||
|
$this->uploadable = perm_is_allowed($this->profile_owner,$ob_hash,'write_storage');
|
||||||
break;
|
break;
|
||||||
case 'page':
|
case 'page':
|
||||||
$this->profile_owner = \App::$profile['uid'];
|
$this->profile_owner = \App::$profile['uid'];
|
||||||
@@ -91,6 +113,11 @@ class ThreadStream {
|
|||||||
return $this->commentable;
|
return $this->commentable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function is_uploadable() {
|
||||||
|
return $this->uploadable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if page is a preview
|
* Check if page is a preview
|
||||||
*/
|
*/
|
||||||
@@ -158,13 +185,17 @@ class ThreadStream {
|
|||||||
if(intval($item->get_data_value('item_nocomment'))) {
|
if(intval($item->get_data_value('item_nocomment'))) {
|
||||||
$item->set_commentable(false);
|
$item->set_commentable(false);
|
||||||
}
|
}
|
||||||
elseif(($this->observer) && (! $item->is_commentable())) {
|
elseif(! $item->is_commentable()) {
|
||||||
if((array_key_exists('owner',$item->data)) && intval($item->data['owner']['abook_self']))
|
if((array_key_exists('owner',$item->data)) && intval($item->data['owner']['abook_self']))
|
||||||
$item->set_commentable(perm_is_allowed($this->profile_owner,$this->observer['xchan_hash'],'post_comments'));
|
$item->set_commentable(perm_is_allowed($this->profile_owner,$ob_hash,'post_comments'));
|
||||||
else
|
else
|
||||||
$item->set_commentable(can_comment_on_post($this->observer['xchan_hash'],$item->data));
|
$item->set_commentable(can_comment_on_post($ob_hash,$item->data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if($this->mode === 'pubstream' && (! local_channel())) {
|
||||||
|
$item->set_commentable(false);
|
||||||
|
}
|
||||||
|
|
||||||
require_once('include/channel.php');
|
require_once('include/channel.php');
|
||||||
|
|
||||||
$item->set_conversation($this);
|
$item->set_conversation($this);
|
||||||
|
|||||||
@@ -2,7 +2,26 @@
|
|||||||
|
|
||||||
namespace Zotlabs\Lib;
|
namespace Zotlabs\Lib;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Class for handling observer's config.
|
||||||
|
*
|
||||||
|
* <b>XConfig</b> is comparable to <i>PConfig</i>, except that it uses <i>xchan</i>
|
||||||
|
* (an observer hash) as an identifier.
|
||||||
|
*
|
||||||
|
* <b>XConfig</b> is used for observer specific configurations and takes a
|
||||||
|
* <i>xchan</i> as identifier.
|
||||||
|
* The storage is of size MEDIUMTEXT.
|
||||||
|
*
|
||||||
|
* @code{.php}$var = Zotlabs\Lib\XConfig::Get('xchan', 'category', 'key');
|
||||||
|
* // with default value for non existent key
|
||||||
|
* $var = Zotlabs\Lib\XConfig::Get('xchan', 'category', 'unsetkey', 'defaultvalue');@endcode
|
||||||
|
*
|
||||||
|
* The old (deprecated?) way to access a XConfig value is:
|
||||||
|
* @code{.php}$observer = App::get_observer_hash();
|
||||||
|
* if ($observer) {
|
||||||
|
* $var = get_xconfig($observer, 'category', 'key');
|
||||||
|
* }@endcode
|
||||||
|
*/
|
||||||
class XConfig {
|
class XConfig {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -15,7 +34,6 @@ class XConfig {
|
|||||||
* The observer's hash
|
* The observer's hash
|
||||||
* @return void|false Returns false if xchan is not set
|
* @return void|false Returns false if xchan is not set
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static public function Load($xchan) {
|
static public function Load($xchan) {
|
||||||
|
|
||||||
if(! $xchan)
|
if(! $xchan)
|
||||||
@@ -56,19 +74,19 @@ class XConfig {
|
|||||||
* The category of the configuration value
|
* The category of the configuration value
|
||||||
* @param string $key
|
* @param string $key
|
||||||
* The configuration key to query
|
* The configuration key to query
|
||||||
|
* @param boolean $default (optional) default false
|
||||||
* @return mixed Stored $value or false if it does not exist
|
* @return mixed Stored $value or false if it does not exist
|
||||||
*/
|
*/
|
||||||
|
static public function Get($xchan, $family, $key, $default = false) {
|
||||||
static public function Get($xchan, $family, $key) {
|
|
||||||
|
|
||||||
if(! $xchan)
|
if(! $xchan)
|
||||||
return false;
|
return $default;
|
||||||
|
|
||||||
if(! array_key_exists($xchan, \App::$config))
|
if(! array_key_exists($xchan, \App::$config))
|
||||||
load_xconfig($xchan);
|
load_xconfig($xchan);
|
||||||
|
|
||||||
if((! array_key_exists($family, \App::$config[$xchan])) || (! array_key_exists($key, \App::$config[$xchan][$family])))
|
if((! array_key_exists($family, \App::$config[$xchan])) || (! array_key_exists($key, \App::$config[$xchan][$family])))
|
||||||
return false;
|
return $default;
|
||||||
|
|
||||||
return ((! is_array(\App::$config[$xchan][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$xchan][$family][$key]))
|
return ((! is_array(\App::$config[$xchan][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$xchan][$family][$key]))
|
||||||
? unserialize(\App::$config[$xchan][$family][$key])
|
? unserialize(\App::$config[$xchan][$family][$key])
|
||||||
@@ -82,7 +100,6 @@ class XConfig {
|
|||||||
* Stores a config value ($value) in the category ($family) under the key ($key)
|
* Stores a config value ($value) in the category ($family) under the key ($key)
|
||||||
* for the observer's $xchan hash.
|
* for the observer's $xchan hash.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @param string $xchan
|
* @param string $xchan
|
||||||
* The observer's hash
|
* The observer's hash
|
||||||
* @param string $family
|
* @param string $family
|
||||||
@@ -93,7 +110,6 @@ class XConfig {
|
|||||||
* The value to store
|
* The value to store
|
||||||
* @return mixed Stored $value or false
|
* @return mixed Stored $value or false
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static public function Set($xchan, $family, $key, $value) {
|
static public function Set($xchan, $family, $key, $value) {
|
||||||
|
|
||||||
// manage array value
|
// manage array value
|
||||||
@@ -106,7 +122,7 @@ class XConfig {
|
|||||||
if(! array_key_exists($family, \App::$config[$xchan]))
|
if(! array_key_exists($family, \App::$config[$xchan]))
|
||||||
\App::$config[$xchan][$family] = array();
|
\App::$config[$xchan][$family] = array();
|
||||||
|
|
||||||
$ret = q("INSERT INTO xconfig ( xchan, cat, k, v ) VALUES ( '%s', '%s', '%s', '%s' ) ",
|
$ret = q("INSERT INTO xconfig ( xchan, cat, k, v ) VALUES ( '%s', '%s', '%s', '%s' )",
|
||||||
dbesc($xchan),
|
dbesc($xchan),
|
||||||
dbesc($family),
|
dbesc($family),
|
||||||
dbesc($key),
|
dbesc($key),
|
||||||
@@ -126,6 +142,7 @@ class XConfig {
|
|||||||
|
|
||||||
if($ret)
|
if($ret)
|
||||||
return $value;
|
return $value;
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,11 +160,11 @@ class XConfig {
|
|||||||
* The configuration key to delete
|
* The configuration key to delete
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static public function Delete($xchan, $family, $key) {
|
static public function Delete($xchan, $family, $key) {
|
||||||
|
|
||||||
if(x(\App::$config[$xchan][$family], $key))
|
if(x(\App::$config[$xchan][$family], $key))
|
||||||
unset(\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'",
|
$ret = q("DELETE FROM xconfig WHERE xchan = '%s' AND cat = '%s' AND k = '%s'",
|
||||||
dbesc($xchan),
|
dbesc($xchan),
|
||||||
dbesc($family),
|
dbesc($family),
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ require_once("include/group.php");
|
|||||||
|
|
||||||
class Acl extends \Zotlabs\Web\Controller {
|
class Acl extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
function init(){
|
function init() {
|
||||||
|
|
||||||
// logger('mod_acl: ' . print_r($_REQUEST,true));
|
logger('mod_acl: ' . print_r($_REQUEST,true));
|
||||||
|
|
||||||
$start = (x($_REQUEST,'start') ? $_REQUEST['start'] : 0);
|
$start = (x($_REQUEST,'start') ? $_REQUEST['start'] : 0);
|
||||||
$count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 500);
|
$count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 500);
|
||||||
@@ -33,6 +33,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
|||||||
// $type =
|
// $type =
|
||||||
// '' => standard ACL request
|
// '' => standard ACL request
|
||||||
// 'g' => Groups only ACL request
|
// 'g' => Groups only ACL request
|
||||||
|
// 'f' => forums only ACL request
|
||||||
// 'c' => Connections only ACL request or editor (textarea) mention request
|
// 'c' => Connections only ACL request or editor (textarea) mention request
|
||||||
// $_REQUEST['search'] contains ACL search text.
|
// $_REQUEST['search'] contains ACL search text.
|
||||||
|
|
||||||
@@ -49,19 +50,19 @@ class Acl extends \Zotlabs\Web\Controller {
|
|||||||
$extra_channels = (x($_REQUEST,'extra_channels') ? $_REQUEST['extra_channels'] : array());
|
$extra_channels = (x($_REQUEST,'extra_channels') ? $_REQUEST['extra_channels'] : array());
|
||||||
|
|
||||||
// The different autocomplete libraries use different names for the search text
|
// The different autocomplete libraries use different names for the search text
|
||||||
// parameter. Internaly we'll use $search to represent the search text no matter
|
// parameter. Internally we'll use $search to represent the search text no matter
|
||||||
// what request variable it was attached to.
|
// what request variable it was attached to.
|
||||||
|
|
||||||
if(array_key_exists('query',$_REQUEST)) {
|
if(array_key_exists('query',$_REQUEST)) {
|
||||||
$search = $_REQUEST['query'];
|
$search = $_REQUEST['query'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (! local_channel()) && (! ($type == 'x' || $type == 'c')))
|
if( (! local_channel()) && (! in_array($type, [ 'x', 'c', 'f' ])))
|
||||||
killme();
|
killme();
|
||||||
|
|
||||||
$permitted = [];
|
$permitted = [];
|
||||||
|
|
||||||
if(in_array($type, [ 'm', 'a', 'c' ])) {
|
if(in_array($type, [ 'm', 'a', 'c', 'f' ])) {
|
||||||
|
|
||||||
// These queries require permission checking. We'll create a simple array of xchan_hash for those with
|
// These queries require permission checking. We'll create a simple array of xchan_hash for those with
|
||||||
// the requisite permissions which we can check against.
|
// the requisite permissions which we can check against.
|
||||||
@@ -77,7 +78,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
|
|
||||||
if($search) {
|
if($search) {
|
||||||
$sql_extra = " AND `name` LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " ";
|
$sql_extra = " AND groups.gname LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " ";
|
||||||
$sql_extra2 = "AND ( xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " OR xchan_addr LIKE " . protect_sprintf( "'%" . dbesc($search) . ((strpos($search,'@') === false) ? "%@%'" : "%'")) . ") ";
|
$sql_extra2 = "AND ( xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " OR xchan_addr LIKE " . protect_sprintf( "'%" . dbesc($search) . ((strpos($search,'@') === false) ? "%@%'" : "%'")) . ") ";
|
||||||
|
|
||||||
// This horrible mess is needed because position also returns 0 if nothing is found.
|
// This horrible mess is needed because position also returns 0 if nothing is found.
|
||||||
@@ -87,8 +88,8 @@ class Acl extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$order_extra2 = "CASE WHEN xchan_name LIKE "
|
$order_extra2 = "CASE WHEN xchan_name LIKE "
|
||||||
. protect_sprintf( "'%" . dbesc($search) . "%'" )
|
. protect_sprintf( "'%" . dbesc($search) . "%'" )
|
||||||
. " then POSITION('" . dbesc($search)
|
. " then POSITION('" . protect_sprintf(dbesc($search))
|
||||||
. "' IN xchan_name) else position('" . dbesc($search) . "' IN xchan_addr) end, ";
|
. "' IN xchan_name) else position('" . protect_sprintf(dbesc($search)) . "' IN xchan_addr) end, ";
|
||||||
|
|
||||||
$col = ((strpos($search,'@') !== false) ? 'xchan_addr' : 'xchan_name' );
|
$col = ((strpos($search,'@') !== false) ? 'xchan_addr' : 'xchan_name' );
|
||||||
$sql_extra3 = "AND $col like " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " ";
|
$sql_extra3 = "AND $col like " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " ";
|
||||||
@@ -104,10 +105,31 @@ class Acl extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
if($type == '' || $type == 'g') {
|
if($type == '' || $type == 'g') {
|
||||||
|
|
||||||
|
// virtual groups based on private profile viewing ability
|
||||||
|
|
||||||
|
$r = q("select id, profile_guid, profile_name from profile where is_default = 0 and uid = %d",
|
||||||
|
intval(local_channel())
|
||||||
|
);
|
||||||
|
if($r) {
|
||||||
|
foreach($r as $rv) {
|
||||||
|
$groups[] = array(
|
||||||
|
"type" => "g",
|
||||||
|
"photo" => "images/twopeople.png",
|
||||||
|
"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']),
|
||||||
|
"link" => ''
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normal privacy groups
|
||||||
|
|
||||||
$r = q("SELECT groups.id, groups.hash, groups.gname
|
$r = q("SELECT groups.id, groups.hash, groups.gname
|
||||||
FROM groups,group_member
|
FROM groups, group_member
|
||||||
WHERE groups.deleted = 0 AND groups.uid = %d
|
WHERE groups.deleted = 0 AND groups.uid = %d
|
||||||
AND group_member.gid=groups.id
|
AND group_member.gid = groups.id
|
||||||
$sql_extra
|
$sql_extra
|
||||||
GROUP BY groups.id
|
GROUP BY groups.id
|
||||||
ORDER BY groups.gname
|
ORDER BY groups.gname
|
||||||
@@ -133,26 +155,42 @@ class Acl extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($type == '' || $type == 'c') {
|
if($type == '' || $type == 'c' || $type === 'f') {
|
||||||
$extra_channels_sql = '';
|
|
||||||
// Only include channels who allow the observer to view their permissions
|
|
||||||
foreach($extra_channels as $channel) {
|
|
||||||
if(perm_is_allowed(intval($channel), get_observer_hash(),'view_contacts'))
|
|
||||||
$extra_channels_sql .= "," . intval($channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
$extra_channels_sql = substr($extra_channels_sql,1); // Remove initial comma
|
$extra_channels_sql = '';
|
||||||
|
|
||||||
|
// Only include channels who allow the observer to view their connections
|
||||||
|
if($extra_channels) {
|
||||||
|
foreach($extra_channels as $channel) {
|
||||||
|
if(perm_is_allowed(intval($channel), get_observer_hash(),'view_contacts')) {
|
||||||
|
if($extra_channel_sql)
|
||||||
|
$extra_channels_sql .= ',';
|
||||||
|
$extra_channels_sql .= intval($channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Getting info from the abook is better for local users because it contains info about permissions
|
// Getting info from the abook is better for local users because it contains info about permissions
|
||||||
if(local_channel()) {
|
if(local_channel()) {
|
||||||
if($extra_channels_sql != '')
|
if($extra_channels_sql != '')
|
||||||
$extra_channels_sql = " OR (abook_channel IN ($extra_channels_sql)) and abook_hidden = 0 ";
|
$extra_channels_sql = " OR (abook_channel IN ($extra_channels_sql)) and abook_hidden = 0 ";
|
||||||
|
|
||||||
|
|
||||||
|
// Add atokens belonging to the local channel
|
||||||
|
|
||||||
|
if($search) {
|
||||||
|
$sql_extra_atoken = "AND ( atoken_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . ") ";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$sql_extra_atoken = '';
|
||||||
|
}
|
||||||
|
|
||||||
$r2 = null;
|
$r2 = null;
|
||||||
|
|
||||||
$r1 = q("select * from atoken where atoken_uid = %d",
|
$r1 = q("select * from atoken where atoken_uid = %d $sql_extra_atoken",
|
||||||
intval(local_channel())
|
intval(local_channel())
|
||||||
);
|
);
|
||||||
|
|
||||||
if($r1) {
|
if($r1) {
|
||||||
require_once('include/security.php');
|
require_once('include/security.php');
|
||||||
$r2 = array();
|
$r2 = array();
|
||||||
@@ -172,6 +210,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add connections
|
||||||
|
|
||||||
$r = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, xchan_pubforum, abook_flags, abook_self
|
$r = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, xchan_pubforum, abook_flags, abook_self
|
||||||
FROM abook left join xchan on abook_xchan = xchan_hash
|
FROM abook left join xchan on abook_xchan = xchan_hash
|
||||||
@@ -276,7 +315,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
|||||||
$contacts[] = array(
|
$contacts[] = array(
|
||||||
"photo" => $g['photo'],
|
"photo" => $g['photo'],
|
||||||
"name" => $g['name'],
|
"name" => $g['name'],
|
||||||
"nick" => $g['address'],
|
"nick" => $g['address']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -293,18 +332,24 @@ class Acl extends \Zotlabs\Web\Controller {
|
|||||||
$r = array();
|
$r = array();
|
||||||
|
|
||||||
if($r) {
|
if($r) {
|
||||||
foreach($r as $g){
|
foreach($r as $g) {
|
||||||
|
|
||||||
// remove RSS feeds from ACLs - they are inaccessible
|
if(($g['network'] === 'rss') && ($type != 'a'))
|
||||||
if(strpos($g['hash'],'/') && $type != 'a')
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(in_array($g['hash'],$permitted) && $type == 'c' && (! $noforums)) {
|
$g['hash'] = urlencode($g['hash']);
|
||||||
|
|
||||||
|
if(! $g['nick']) {
|
||||||
|
$t = explode(' ',strtolower($g['name']));
|
||||||
|
$g['nick'] = $t[0] . '@';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(in_array($g['hash'],$permitted) && in_array($type, [ 'c', 'f' ]) && (! $noforums)) {
|
||||||
$contacts[] = array(
|
$contacts[] = array(
|
||||||
"type" => "c",
|
"type" => "c",
|
||||||
"photo" => "images/twopeople.png",
|
"photo" => "images/twopeople.png",
|
||||||
"name" => $g['name'] . '+',
|
"name" => $g['name'] . (($type === 'f') ? '' : '+'),
|
||||||
"id" => $g['id'] . '+',
|
"id" => urlencode($g['id']) . (($type === 'f') ? '' : '+'),
|
||||||
"xid" => $g['hash'],
|
"xid" => $g['hash'],
|
||||||
"link" => $g['nick'],
|
"link" => $g['nick'],
|
||||||
"nick" => substr($g['nick'],0,strpos($g['nick'],'@')),
|
"nick" => substr($g['nick'],0,strpos($g['nick'],'@')),
|
||||||
@@ -313,18 +358,20 @@ class Acl extends \Zotlabs\Web\Controller {
|
|||||||
"label" => t('network')
|
"label" => t('network')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$contacts[] = array(
|
if($type !== 'f') {
|
||||||
"type" => "c",
|
$contacts[] = array(
|
||||||
"photo" => $g['micro'],
|
"type" => "c",
|
||||||
"name" => $g['name'],
|
"photo" => $g['micro'],
|
||||||
"id" => $g['id'],
|
"name" => $g['name'],
|
||||||
"xid" => $g['hash'],
|
"id" => urlencode($g['id']),
|
||||||
"link" => $g['nick'],
|
"xid" => $g['hash'],
|
||||||
"nick" => (($g['nick']) ? substr($g['nick'],0,strpos($g['nick'],'@')) : t('RSS')),
|
"link" => $g['nick'],
|
||||||
"self" => (intval($g['abook_self']) ? 'abook-self' : ''),
|
"nick" => (($g['nick']) ? substr($g['nick'],0,strpos($g['nick'],'@')) : $g['nick']),
|
||||||
"taggable" => '',
|
"self" => (intval($g['abook_self']) ? 'abook-self' : ''),
|
||||||
"label" => '',
|
"taggable" => '',
|
||||||
);
|
"label" => '',
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,9 +429,11 @@ class Acl extends \Zotlabs\Web\Controller {
|
|||||||
$url = $directory['url'] . '/dirsearch';
|
$url = $directory['url'] . '/dirsearch';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$token = get_config('system','realm_token');
|
||||||
|
|
||||||
$count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 100);
|
$count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 100);
|
||||||
if($url) {
|
if($url) {
|
||||||
$query = $url . '?f=' ;
|
$query = $url . '?f=' . (($token) ? '&t=' . urlencode($token) : '');
|
||||||
$query .= '&name=' . urlencode($search) . "&limit=$count" . (($address) ? '&address=' . urlencode($search) : '');
|
$query .= '&name=' . urlencode($search) . "&limit=$count" . (($address) ? '&address=' . urlencode($search) : '');
|
||||||
|
|
||||||
$x = z_fetch_url($query);
|
$x = z_fetch_url($query);
|
||||||
|
|||||||
@@ -1,21 +1,20 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Zotlabs\Module;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file mod/admin.php
|
* @file Zotlabs/Module/Admin.php
|
||||||
* @brief Hubzilla's admin controller.
|
* @brief Hubzilla's admin controller.
|
||||||
*
|
*
|
||||||
* Controller for the /admin/ area.
|
* Controller for the /admin/ area.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace Zotlabs\Module;
|
||||||
|
|
||||||
require_once('include/queue_fn.php');
|
require_once('include/queue_fn.php');
|
||||||
require_once('include/account.php');
|
require_once('include/account.php');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param App &$a
|
* @brief Admin area.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Admin extends \Zotlabs\Web\Controller {
|
class Admin extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
private $sm = null;
|
private $sm = null;
|
||||||
@@ -49,11 +48,12 @@ class Admin extends \Zotlabs\Web\Controller {
|
|||||||
return login(false);
|
return login(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Page content
|
* Page content
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
nav_set_selected('Admin');
|
||||||
|
|
||||||
$o = '';
|
$o = '';
|
||||||
|
|
||||||
if(argc() > 1) {
|
if(argc() > 1) {
|
||||||
@@ -80,7 +80,6 @@ class Admin extends \Zotlabs\Web\Controller {
|
|||||||
/**
|
/**
|
||||||
* @brief Returns content for Admin Summary Page.
|
* @brief Returns content for Admin Summary Page.
|
||||||
*
|
*
|
||||||
* @param App &$a
|
|
||||||
* @return string HTML from parsed admin_summary.tpl
|
* @return string HTML from parsed admin_summary.tpl
|
||||||
*/
|
*/
|
||||||
function admin_page_summary() {
|
function admin_page_summary() {
|
||||||
@@ -94,23 +93,23 @@ class Admin extends \Zotlabs\Web\Controller {
|
|||||||
intval(ACCOUNT_BLOCKED)
|
intval(ACCOUNT_BLOCKED)
|
||||||
);
|
);
|
||||||
if ($r) {
|
if ($r) {
|
||||||
$accounts['total'] = array('label' => t('# Accounts'), 'val' => $r[0]['total']);
|
$accounts['total'] = array('label' => t('Accounts'), 'val' => $r[0]['total']);
|
||||||
$accounts['blocked'] = array('label' => t('# blocked accounts'), 'val' => $r[0]['blocked']);
|
$accounts['blocked'] = array('label' => t('Blocked accounts'), 'val' => $r[0]['blocked']);
|
||||||
$accounts['expired'] = array('label' => t('# expired accounts'), 'val' => $r[0]['expired']);
|
$accounts['expired'] = array('label' => t('Expired accounts'), 'val' => $r[0]['expired']);
|
||||||
$accounts['expiring'] = array('label' => t('# expiring accounts'), 'val' => $r[0]['expiring']);
|
$accounts['expiring'] = array('label' => t('Expiring accounts'), 'val' => $r[0]['expiring']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// pending registrations
|
// pending registrations
|
||||||
$r = q("SELECT COUNT(id) AS `count` FROM `register` WHERE `uid` != '0'");
|
$r = q("SELECT COUNT(id) AS rtotal FROM register WHERE uid != '0'");
|
||||||
$pending = $r[0]['count'];
|
$pending = $r[0]['rtotal'];
|
||||||
|
|
||||||
// available channels, primary and clones
|
// available channels, primary and clones
|
||||||
$channels = array();
|
$channels = array();
|
||||||
$r = q("SELECT COUNT(*) AS total, COUNT(CASE WHEN channel_primary = 1 THEN 1 ELSE NULL END) AS main, COUNT(CASE WHEN channel_primary = 0 THEN 1 ELSE NULL END) AS clones FROM channel WHERE channel_removed = 0");
|
$r = q("SELECT COUNT(*) AS total, COUNT(CASE WHEN channel_primary = 1 THEN 1 ELSE NULL END) AS main, COUNT(CASE WHEN channel_primary = 0 THEN 1 ELSE NULL END) AS clones FROM channel WHERE channel_removed = 0");
|
||||||
if ($r) {
|
if ($r) {
|
||||||
$channels['total'] = array('label' => t('# Channels'), 'val' => $r[0]['total']);
|
$channels['total'] = array('label' => t('Channels'), 'val' => $r[0]['total']);
|
||||||
$channels['main'] = array('label' => t('# primary'), 'val' => $r[0]['main']);
|
$channels['main'] = array('label' => t('Primary'), 'val' => $r[0]['main']);
|
||||||
$channels['clones'] = array('label' => t('# clones'), 'val' => $r[0]['clones']);
|
$channels['clones'] = array('label' => t('Clones'), 'val' => $r[0]['clones']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can do better, but this is a quick queue status
|
// We can do better, but this is a quick queue status
|
||||||
@@ -121,21 +120,17 @@ class Admin extends \Zotlabs\Web\Controller {
|
|||||||
// If no plugins active return 0, otherwise list of plugin names
|
// If no plugins active return 0, otherwise list of plugin names
|
||||||
$plugins = (count(\App::$plugins) == 0) ? count(\App::$plugins) : \App::$plugins;
|
$plugins = (count(\App::$plugins) == 0) ? count(\App::$plugins) : \App::$plugins;
|
||||||
|
|
||||||
|
if(is_array($plugins))
|
||||||
|
sort($plugins);
|
||||||
|
|
||||||
// Could be extended to provide also other alerts to the admin
|
// Could be extended to provide also other alerts to the admin
|
||||||
$alertmsg = '';
|
$alertmsg = '';
|
||||||
// annoy admin about upcoming unsupported PHP version
|
|
||||||
if (version_compare(PHP_VERSION, '5.4', '<')) {
|
|
||||||
$alertmsg = 'Your PHP version ' . PHP_VERSION . ' will not be supported with the next major release of $Projectname. You are strongly urged to upgrade to a current version.'
|
|
||||||
. '<br>PHP 5.3 has reached its <a href="http://php.net/eol.php" class="alert-link">End of Life (EOL)</a> in August 2014.'
|
|
||||||
. ' A list about current PHP versions can be found <a href="http://php.net/supported-versions.php" class="alert-link">here</a>.';
|
|
||||||
}
|
|
||||||
|
|
||||||
$vmaster = get_repository_version('master');
|
$vmaster = get_repository_version('master');
|
||||||
$vdev = get_repository_version('dev');
|
$vdev = get_repository_version('dev');
|
||||||
|
|
||||||
$upgrade = ((version_compare(STD_VERSION,$vmaster) < 0) ? t('Your software should be updated') : '');
|
$upgrade = ((version_compare(STD_VERSION,$vmaster) < 0) ? t('Your software should be updated') : '');
|
||||||
|
|
||||||
|
|
||||||
$t = get_markup_template('admin_summary.tpl');
|
$t = get_markup_template('admin_summary.tpl');
|
||||||
return replace_macros($t, array(
|
return replace_macros($t, array(
|
||||||
'$title' => t('Administration'),
|
'$title' => t('Administration'),
|
||||||
@@ -150,10 +145,8 @@ class Admin extends \Zotlabs\Web\Controller {
|
|||||||
'$vmaster' => array( t('Repository version (master)'), $vmaster),
|
'$vmaster' => array( t('Repository version (master)'), $vmaster),
|
||||||
'$vdev' => array( t('Repository version (dev)'), $vdev),
|
'$vdev' => array( t('Repository version (dev)'), $vdev),
|
||||||
'$upgrade' => $upgrade,
|
'$upgrade' => $upgrade,
|
||||||
'$build' => get_config('system', 'db_version')
|
'$build' => get_config('system', 'db_version')
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,22 @@ class Account_edit {
|
|||||||
info( sprintf( t('Password changed for account %d.'), $account_id). EOL);
|
info( sprintf( t('Password changed for account %d.'), $account_id). EOL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$service_class = trim($_REQUEST['service_class']);
|
||||||
|
$account_level = intval(trim($_REQUEST['account_level']));
|
||||||
|
$account_language = trim($_REQUEST['account_language']);
|
||||||
|
|
||||||
|
$r = q("update account set account_service_class = '%s', account_level = %d, account_language = '%s'
|
||||||
|
where account_id = %d",
|
||||||
|
dbesc($service_class),
|
||||||
|
intval($account_level),
|
||||||
|
dbesc($account_language),
|
||||||
|
intval($account_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
if($r)
|
||||||
|
info( t('Account settings updated.') . EOL);
|
||||||
|
|
||||||
goaway(z_root() . '/admin/accounts');
|
goaway(z_root() . '/admin/accounts');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,11 +62,15 @@ class Account_edit {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$a = replace_macros(get_markup_template('admin_account_edit.tpl'), [
|
$a = replace_macros(get_markup_template('admin_account_edit.tpl'), [
|
||||||
'$account' => $x[0],
|
'$account' => $x[0],
|
||||||
'$title' => t('Account Edit'),
|
'$title' => t('Account Edit'),
|
||||||
'$pass1' => [ 'pass1', t('New Password'), ' ','' ],
|
'$pass1' => [ 'pass1', t('New Password'), ' ','' ],
|
||||||
'$pass2' => [ 'pass2', t('New Password again'), ' ','' ],
|
'$pass2' => [ 'pass2', t('New Password again'), ' ','' ],
|
||||||
|
'$account_level' => [ 'account_level', t('Technical skill level'), $x[0]['account_level'], '', \Zotlabs\Lib\Techlevels::levels() ],
|
||||||
|
'$account_language' => [ 'account_language' , t('Account language (for emails)'), $x[0]['account_language'], '', language_list() ],
|
||||||
|
'$service_class' => [ 'service_class', t('Service class'), $x[0]['account_service_class'], '' ],
|
||||||
'$submit' => t('Submit'),
|
'$submit' => t('Submit'),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -133,10 +133,9 @@ class Accounts {
|
|||||||
$base = z_root() . '/admin/accounts?f=';
|
$base = z_root() . '/admin/accounts?f=';
|
||||||
$odir = (($dir === 'asc') ? '0' : '1');
|
$odir = (($dir === 'asc') ? '0' : '1');
|
||||||
|
|
||||||
$users = q("SELECT `account_id` , `account_email`, `account_lastlog`, `account_created`, `account_expires`, " . "`account_service_class`, ( account_flags & %d ) > 0 as `blocked`, " .
|
$users = q("SELECT account_id , account_email, account_lastlog, account_created, account_expires, account_service_class, ( account_flags & %d ) > 0 as blocked,
|
||||||
"(SELECT %s FROM channel as ch " .
|
(SELECT %s FROM channel as ch WHERE ch.channel_account_id = ac.account_id and ch.channel_removed = 0 ) as channels FROM account as ac
|
||||||
"WHERE ch.channel_account_id = ac.account_id and ch.channel_removed = 0 ) as `channels` " .
|
where true $serviceclass order by $key $dir limit %d offset %d ",
|
||||||
"FROM account as ac where true $serviceclass order by $key $dir limit %d offset %d ",
|
|
||||||
intval(ACCOUNT_BLOCKED),
|
intval(ACCOUNT_BLOCKED),
|
||||||
db_concat('ch.channel_address', ' '),
|
db_concat('ch.channel_address', ' '),
|
||||||
intval(\App::$pager['itemspage']),
|
intval(\App::$pager['itemspage']),
|
||||||
|
|||||||
@@ -2,14 +2,15 @@
|
|||||||
|
|
||||||
namespace Zotlabs\Module\Admin;
|
namespace Zotlabs\Module\Admin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Admin Module for Channels.
|
||||||
|
*
|
||||||
|
*/
|
||||||
class Channels {
|
class Channels {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Channels admin page.
|
* @brief Handle POST actions on channels admin page.
|
||||||
*
|
*
|
||||||
* @param App &$a
|
|
||||||
*/
|
*/
|
||||||
function post() {
|
function post() {
|
||||||
|
|
||||||
@@ -19,18 +20,18 @@ class Channels {
|
|||||||
|
|
||||||
$xor = db_getfunc('^');
|
$xor = db_getfunc('^');
|
||||||
|
|
||||||
if (x($_POST,'page_channels_block')){
|
if(x($_POST, 'page_channels_block')) {
|
||||||
foreach($channels as $uid){
|
foreach($channels as $uid) {
|
||||||
q("UPDATE channel SET channel_pageflags = ( channel_pageflags $xor %d ) where channel_id = %d",
|
q("UPDATE channel SET channel_pageflags = ( channel_pageflags $xor %d ) where channel_id = %d",
|
||||||
intval(PAGE_CENSORED),
|
intval(PAGE_CENSORED),
|
||||||
intval( $uid )
|
intval( $uid )
|
||||||
);
|
);
|
||||||
\Zotlabs\Daemon\Master::Summon(array('Directory',$uid,'nopush'));
|
\Zotlabs\Daemon\Master::Summon(array('Directory', $uid, 'nopush'));
|
||||||
}
|
}
|
||||||
notice( sprintf( tt("%s channel censored/uncensored", "%s channels censored/uncensored", count($channels)), count($channels)) );
|
notice( sprintf( tt("%s channel censored/uncensored", "%s channels censored/uncensored", count($channels)), count($channels)) );
|
||||||
}
|
}
|
||||||
if (x($_POST,'page_channels_code')){
|
if(x($_POST, 'page_channels_code')) {
|
||||||
foreach($channels as $uid){
|
foreach($channels as $uid) {
|
||||||
q("UPDATE channel SET channel_pageflags = ( channel_pageflags $xor %d ) where channel_id = %d",
|
q("UPDATE channel SET channel_pageflags = ( channel_pageflags $xor %d ) where channel_id = %d",
|
||||||
intval(PAGE_ALLOWCODE),
|
intval(PAGE_ALLOWCODE),
|
||||||
intval( $uid )
|
intval( $uid )
|
||||||
@@ -38,9 +39,9 @@ class Channels {
|
|||||||
}
|
}
|
||||||
notice( sprintf( tt("%s channel code allowed/disallowed", "%s channels code allowed/disallowed", count($channels)), count($channels)) );
|
notice( sprintf( tt("%s channel code allowed/disallowed", "%s channels code allowed/disallowed", count($channels)), count($channels)) );
|
||||||
}
|
}
|
||||||
if (x($_POST,'page_channels_delete')){
|
if(x($_POST, 'page_channels_delete')) {
|
||||||
foreach($channels as $uid){
|
foreach($channels as $uid) {
|
||||||
channel_remove($uid,true);
|
channel_remove($uid, true);
|
||||||
}
|
}
|
||||||
notice( sprintf( tt("%s channel deleted", "%s channels deleted", count($channels)), count($channels)) );
|
notice( sprintf( tt("%s channel deleted", "%s channels deleted", count($channels)), count($channels)) );
|
||||||
}
|
}
|
||||||
@@ -48,13 +49,11 @@ class Channels {
|
|||||||
goaway(z_root() . '/admin/channels' );
|
goaway(z_root() . '/admin/channels' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief Generate channels admin page and handle single item operations.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string with parsed HTML
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
if(argc() > 2) {
|
if(argc() > 2) {
|
||||||
$uid = argv(3);
|
$uid = argv(3);
|
||||||
@@ -105,7 +104,6 @@ class Channels {
|
|||||||
goaway(z_root() . '/admin/channels' );
|
goaway(z_root() . '/admin/channels' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'channel_id');
|
$key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'channel_id');
|
||||||
$dir = 'asc';
|
$dir = 'asc';
|
||||||
if(array_key_exists('dir',$_REQUEST))
|
if(array_key_exists('dir',$_REQUEST))
|
||||||
@@ -114,8 +112,6 @@ class Channels {
|
|||||||
$base = z_root() . '/admin/channels?f=';
|
$base = z_root() . '/admin/channels?f=';
|
||||||
$odir = (($dir === 'asc') ? '0' : '1');
|
$odir = (($dir === 'asc') ? '0' : '1');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* get channels */
|
/* get channels */
|
||||||
|
|
||||||
$total = q("SELECT count(*) as total FROM channel where channel_removed = 0 and channel_system = 0");
|
$total = q("SELECT count(*) as total FROM channel where channel_removed = 0 and channel_system = 0");
|
||||||
@@ -143,7 +139,7 @@ class Channels {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$t = get_markup_template("admin_channels.tpl");
|
$t = get_markup_template('admin_channels.tpl');
|
||||||
$o = replace_macros($t, array(
|
$o = replace_macros($t, array(
|
||||||
// strings //
|
// strings //
|
||||||
'$title' => t('Administration'),
|
'$title' => t('Administration'),
|
||||||
@@ -166,7 +162,7 @@ class Channels {
|
|||||||
'$confirm_delete_multi' => t('Selected channels will be deleted!\n\nEverything that was posted in these channels on this site will be permanently deleted!\n\nAre you sure?'),
|
'$confirm_delete_multi' => t('Selected channels will be deleted!\n\nEverything that was posted in these channels on this site will be permanently deleted!\n\nAre you sure?'),
|
||||||
'$confirm_delete' => t('The channel {0} will be deleted!\n\nEverything that was posted in this channel on this site will be permanently deleted!\n\nAre you sure?'),
|
'$confirm_delete' => t('The channel {0} will be deleted!\n\nEverything that was posted in this channel on this site will be permanently deleted!\n\nAre you sure?'),
|
||||||
|
|
||||||
'$form_security_token' => get_form_security_token("admin_channels"),
|
'$form_security_token' => get_form_security_token('admin_channels'),
|
||||||
|
|
||||||
// values //
|
// values //
|
||||||
'$baseurl' => z_root(),
|
'$baseurl' => z_root(),
|
||||||
@@ -177,10 +173,4 @@ class Channels {
|
|||||||
return $o;
|
return $o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@ class Dbsync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$failed = array();
|
$failed = array();
|
||||||
$r = q("select * from config where `cat` = 'database' ");
|
$r = q("select * from config where cat = 'database' ");
|
||||||
if(count($r)) {
|
if(count($r)) {
|
||||||
foreach($r as $rr) {
|
foreach($r as $rr) {
|
||||||
$upd = intval(substr($rr['k'],8));
|
$upd = intval(substr($rr['k'],8));
|
||||||
|
|||||||
@@ -3,10 +3,14 @@
|
|||||||
namespace Zotlabs\Module\Admin;
|
namespace Zotlabs\Module\Admin;
|
||||||
|
|
||||||
use \Zotlabs\Storage\GitRepo as GitRepo;
|
use \Zotlabs\Storage\GitRepo as GitRepo;
|
||||||
|
use \Michelf\MarkdownExtra;
|
||||||
|
|
||||||
class Plugins {
|
class Plugins {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
*/
|
||||||
function post() {
|
function post() {
|
||||||
|
|
||||||
if(argc() > 2 && is_file("addon/" . argv(2) . "/" . argv(2) . ".php")) {
|
if(argc() > 2 && is_file("addon/" . argv(2) . "/" . argv(2) . ".php")) {
|
||||||
@@ -17,7 +21,6 @@ class Plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
goaway(z_root() . '/admin/plugins/' . argv(2) );
|
goaway(z_root() . '/admin/plugins/' . argv(2) );
|
||||||
|
|
||||||
}
|
}
|
||||||
elseif(argc() > 2) {
|
elseif(argc() > 2) {
|
||||||
switch(argv(2)) {
|
switch(argv(2)) {
|
||||||
@@ -36,7 +39,7 @@ class Plugins {
|
|||||||
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
|
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!symlink('extend/addon', $addonDir)) {
|
if (!symlink(realpath('extend/addon'), $addonDir)) {
|
||||||
logger('Error creating symlink to addon folder: ' . $addonDir);
|
logger('Error creating symlink to addon folder: ' . $addonDir);
|
||||||
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
|
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
|
||||||
}
|
}
|
||||||
@@ -57,7 +60,7 @@ class Plugins {
|
|||||||
$files = array_diff(scandir($repoDir), array('.', '..'));
|
$files = array_diff(scandir($repoDir), array('.', '..'));
|
||||||
foreach ($files as $file) {
|
foreach ($files as $file) {
|
||||||
if (is_dir($repoDir . '/' . $file) && $file !== '.git') {
|
if (is_dir($repoDir . '/' . $file) && $file !== '.git') {
|
||||||
$source = 'extend/addon/' . $repoName . '/' . $file;
|
$source = '../extend/addon/' . $repoName . '/' . $file;
|
||||||
$target = realpath('addon/') . '/' . $file;
|
$target = realpath('addon/') . '/' . $file;
|
||||||
unlink($target);
|
unlink($target);
|
||||||
if (!symlink($source, $target)) {
|
if (!symlink($source, $target)) {
|
||||||
@@ -86,7 +89,7 @@ class Plugins {
|
|||||||
logger('Error creating extend folder: ' . $extendDir);
|
logger('Error creating extend folder: ' . $extendDir);
|
||||||
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
|
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
|
||||||
} else {
|
} else {
|
||||||
if (!symlink('extend/addon', $addonDir)) {
|
if (!symlink(realpath('extend/addon'), $addonDir)) {
|
||||||
logger('Error creating symlink to addon folder: ' . $addonDir);
|
logger('Error creating symlink to addon folder: ' . $addonDir);
|
||||||
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
|
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
|
||||||
}
|
}
|
||||||
@@ -101,14 +104,13 @@ class Plugins {
|
|||||||
logger('Repo directory not writable to web server: ' . $repoDir);
|
logger('Repo directory not writable to web server: ' . $repoDir);
|
||||||
json_return_and_die(array('message' => 'Repo directory not writable to web server.', 'success' => false));
|
json_return_and_die(array('message' => 'Repo directory not writable to web server.', 'success' => false));
|
||||||
}
|
}
|
||||||
// TODO: remove directory and unlink /addon/files
|
/// @TODO remove directory and unlink /addon/files
|
||||||
if (rrmdir($repoDir)) {
|
if (rrmdir($repoDir)) {
|
||||||
json_return_and_die(array('message' => 'Repo deleted.', 'success' => true));
|
json_return_and_die(array('message' => 'Repo deleted.', 'success' => true));
|
||||||
} else {
|
} else {
|
||||||
json_return_and_die(array('message' => 'Error deleting addon repo.', 'success' => false));
|
json_return_and_die(array('message' => 'Error deleting addon repo.', 'success' => false));
|
||||||
}
|
}
|
||||||
case 'installrepo':
|
case 'installrepo':
|
||||||
require_once('library/markdown.php');
|
|
||||||
if (array_key_exists('repoURL', $_REQUEST)) {
|
if (array_key_exists('repoURL', $_REQUEST)) {
|
||||||
require_once('library/PHPGit.autoload.php'); // Load PHPGit dependencies
|
require_once('library/PHPGit.autoload.php'); // Load PHPGit dependencies
|
||||||
$repoURL = $_REQUEST['repoURL'];
|
$repoURL = $_REQUEST['repoURL'];
|
||||||
@@ -119,7 +121,7 @@ class Plugins {
|
|||||||
logger('Error creating extend folder: ' . $extendDir);
|
logger('Error creating extend folder: ' . $extendDir);
|
||||||
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
|
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
|
||||||
} else {
|
} else {
|
||||||
if (!symlink('extend/addon', $addonDir)) {
|
if (!symlink(realpath('extend/addon'), $addonDir)) {
|
||||||
logger('Error creating symlink to addon folder: ' . $addonDir);
|
logger('Error creating symlink to addon folder: ' . $addonDir);
|
||||||
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
|
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
|
||||||
}
|
}
|
||||||
@@ -156,7 +158,7 @@ class Plugins {
|
|||||||
$files = array_diff(scandir($repoDir), array('.', '..'));
|
$files = array_diff(scandir($repoDir), array('.', '..'));
|
||||||
foreach ($files as $file) {
|
foreach ($files as $file) {
|
||||||
if (is_dir($repoDir . '/' . $file) && $file !== '.git') {
|
if (is_dir($repoDir . '/' . $file) && $file !== '.git') {
|
||||||
$source = 'extend/addon/' . $repoName . '/' . $file;
|
$source = '../extend/addon/' . $repoName . '/' . $file;
|
||||||
$target = realpath('addon/') . '/' . $file;
|
$target = realpath('addon/') . '/' . $file;
|
||||||
unlink($target);
|
unlink($target);
|
||||||
if (!symlink($source, $target)) {
|
if (!symlink($source, $target)) {
|
||||||
@@ -170,19 +172,18 @@ class Plugins {
|
|||||||
json_return_and_die(array('repo' => $repo, 'message' => '', 'success' => true));
|
json_return_and_die(array('repo' => $repo, 'message' => '', 'success' => true));
|
||||||
}
|
}
|
||||||
case 'addrepo':
|
case 'addrepo':
|
||||||
require_once('library/markdown.php');
|
|
||||||
if (array_key_exists('repoURL', $_REQUEST)) {
|
if (array_key_exists('repoURL', $_REQUEST)) {
|
||||||
require_once('library/PHPGit.autoload.php'); // Load PHPGit dependencies
|
require_once('library/PHPGit.autoload.php'); // Load PHPGit dependencies
|
||||||
$repoURL = $_REQUEST['repoURL'];
|
$repoURL = $_REQUEST['repoURL'];
|
||||||
$extendDir = 'store/[data]/git/sys/extend';
|
$extendDir = 'store/[data]/git/sys/extend';
|
||||||
$addonDir = $extendDir . '/addon';
|
$addonDir = $extendDir . '/addon';
|
||||||
$tempAddonDir = 'store/[data]/git/sys/temp';
|
$tempAddonDir = realpath('store/[data]') . '/git/sys/temp';
|
||||||
if (!file_exists($extendDir)) {
|
if (!file_exists($extendDir)) {
|
||||||
if (!mkdir($extendDir, 0770, true)) {
|
if (!mkdir($extendDir, 0770, true)) {
|
||||||
logger('Error creating extend folder: ' . $extendDir);
|
logger('Error creating extend folder: ' . $extendDir);
|
||||||
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
|
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
|
||||||
} else {
|
} else {
|
||||||
if (!symlink('extend/addon', $addonDir)) {
|
if (!symlink(realpath('extend/addon'), $addonDir)) {
|
||||||
logger('Error creating symlink to addon folder: ' . $addonDir);
|
logger('Error creating symlink to addon folder: ' . $addonDir);
|
||||||
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
|
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
|
||||||
}
|
}
|
||||||
@@ -225,7 +226,7 @@ class Plugins {
|
|||||||
$repo['readme'] = $repo['manifest'] = null;
|
$repo['readme'] = $repo['manifest'] = null;
|
||||||
foreach ($git->git->tree('master') as $object) {
|
foreach ($git->git->tree('master') as $object) {
|
||||||
if ($object['type'] == 'blob' && (strtolower($object['file']) === 'readme.md' || strtolower($object['file']) === 'readme')) {
|
if ($object['type'] == 'blob' && (strtolower($object['file']) === 'readme.md' || strtolower($object['file']) === 'readme')) {
|
||||||
$repo['readme'] = Markdown($git->git->cat->blob($object['hash']));
|
$repo['readme'] = MarkdownExtra::defaultTransform($git->git->cat->blob($object['hash']));
|
||||||
} else if ($object['type'] == 'blob' && strtolower($object['file']) === 'manifest.json') {
|
} else if ($object['type'] == 'blob' && strtolower($object['file']) === 'manifest.json') {
|
||||||
$repo['manifest'] = $git->git->cat->blob($object['hash']);
|
$repo['manifest'] = $git->git->cat->blob($object['hash']);
|
||||||
}
|
}
|
||||||
@@ -241,7 +242,11 @@ class Plugins {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Plugins admin page.
|
||||||
|
*
|
||||||
|
* @return string with parsed HTML
|
||||||
|
*/
|
||||||
function get() {
|
function get() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -297,8 +302,8 @@ class Plugins {
|
|||||||
}
|
}
|
||||||
goaway(z_root() . '/admin/plugins' );
|
goaway(z_root() . '/admin/plugins' );
|
||||||
}
|
}
|
||||||
|
|
||||||
// display plugin details
|
// display plugin details
|
||||||
require_once('library/markdown.php');
|
|
||||||
|
|
||||||
if (in_array($plugin, \App::$plugins)){
|
if (in_array($plugin, \App::$plugins)){
|
||||||
$status = 'on';
|
$status = 'on';
|
||||||
@@ -311,7 +316,7 @@ class Plugins {
|
|||||||
$readme = null;
|
$readme = null;
|
||||||
if (is_file("addon/$plugin/README.md")){
|
if (is_file("addon/$plugin/README.md")){
|
||||||
$readme = file_get_contents("addon/$plugin/README.md");
|
$readme = file_get_contents("addon/$plugin/README.md");
|
||||||
$readme = Markdown($readme);
|
$readme = MarkdownExtra::defaultTransform($readme);
|
||||||
} else if (is_file("addon/$plugin/README")){
|
} else if (is_file("addon/$plugin/README")){
|
||||||
$readme = "<pre>". file_get_contents("addon/$plugin/README") ."</pre>";
|
$readme = "<pre>". file_get_contents("addon/$plugin/README") ."</pre>";
|
||||||
}
|
}
|
||||||
@@ -395,6 +400,10 @@ class Plugins {
|
|||||||
|
|
||||||
usort($plugins,'self::plugin_sort');
|
usort($plugins,'self::plugin_sort');
|
||||||
|
|
||||||
|
$allowManageRepos = false;
|
||||||
|
if(is_writable('extend/addon') && is_writable('store/[data]')) {
|
||||||
|
$allowManageRepos = true;
|
||||||
|
}
|
||||||
|
|
||||||
$admin_plugins_add_repo_form= replace_macros(
|
$admin_plugins_add_repo_form= replace_macros(
|
||||||
get_markup_template('admin_plugins_addrepo.tpl'), array(
|
get_markup_template('admin_plugins_addrepo.tpl'), array(
|
||||||
@@ -419,7 +428,7 @@ class Plugins {
|
|||||||
$addonrepos = [];
|
$addonrepos = [];
|
||||||
foreach($reponames as $repo) {
|
foreach($reponames as $repo) {
|
||||||
$addonrepos[] = array('name' => $repo, 'description' => '');
|
$addonrepos[] = array('name' => $repo, 'description' => '');
|
||||||
// TODO: Parse repo info to provide more information about repos
|
/// @TODO Parse repo info to provide more information about repos
|
||||||
}
|
}
|
||||||
|
|
||||||
$t = get_markup_template('admin_plugins.tpl');
|
$t = get_markup_template('admin_plugins.tpl');
|
||||||
@@ -432,6 +441,7 @@ class Plugins {
|
|||||||
'$plugins' => $plugins,
|
'$plugins' => $plugins,
|
||||||
'$disabled' => t('Disabled - version incompatibility'),
|
'$disabled' => t('Disabled - version incompatibility'),
|
||||||
'$form_security_token' => get_form_security_token('admin_plugins'),
|
'$form_security_token' => get_form_security_token('admin_plugins'),
|
||||||
|
'$allowManageRepos' => $allowManageRepos,
|
||||||
'$managerepos' => t('Manage Repos'),
|
'$managerepos' => t('Manage Repos'),
|
||||||
'$installedtitle' => t('Installed Plugin Repositories'),
|
'$installedtitle' => t('Installed Plugin Repositories'),
|
||||||
'$addnewrepotitle' => t('Install a New Plugin Repository'),
|
'$addnewrepotitle' => t('Install a New Plugin Repository'),
|
||||||
@@ -466,5 +476,4 @@ class Plugins {
|
|||||||
return(strcmp(strtolower($a[2]['name']),strtolower($b[2]['name'])));
|
return(strcmp(strtolower($a[2]['name']),strtolower($b[2]['name'])));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,6 @@ class Queue {
|
|||||||
$expert = ((array_key_exists('expert',$_REQUEST)) ? intval($_REQUEST['expert']) : 0);
|
$expert = ((array_key_exists('expert',$_REQUEST)) ? intval($_REQUEST['expert']) : 0);
|
||||||
|
|
||||||
if($_REQUEST['drophub']) {
|
if($_REQUEST['drophub']) {
|
||||||
require_once('hubloc.php');
|
|
||||||
hubloc_mark_as_down($_REQUEST['drophub']);
|
hubloc_mark_as_down($_REQUEST['drophub']);
|
||||||
remove_queue_by_posturl($_REQUEST['drophub']);
|
remove_queue_by_posturl($_REQUEST['drophub']);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,9 @@ namespace Zotlabs\Module\Admin;
|
|||||||
|
|
||||||
class Site {
|
class Site {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief POST handler for Admin Site Page.
|
* @brief POST handler for Admin Site Page.
|
||||||
*
|
*
|
||||||
* @param App &$a
|
|
||||||
*/
|
*/
|
||||||
function post(){
|
function post(){
|
||||||
if (!x($_POST, 'page_site')) {
|
if (!x($_POST, 'page_site')) {
|
||||||
@@ -19,36 +17,40 @@ class Site {
|
|||||||
check_form_security_token_redirectOnErr('/admin/site', 'admin_site');
|
check_form_security_token_redirectOnErr('/admin/site', 'admin_site');
|
||||||
|
|
||||||
$sitename = ((x($_POST,'sitename')) ? notags(trim($_POST['sitename'])) : '');
|
$sitename = ((x($_POST,'sitename')) ? notags(trim($_POST['sitename'])) : '');
|
||||||
$server_role = ((x($_POST,'server_role')) ? notags(trim($_POST['server_role'])) : 'standard');
|
|
||||||
|
|
||||||
$banner = ((x($_POST,'banner')) ? trim($_POST['banner']) : false);
|
$banner = ((x($_POST,'banner')) ? trim($_POST['banner']) : false);
|
||||||
|
|
||||||
$admininfo = ((x($_POST,'admininfo')) ? trim($_POST['admininfo']) : false);
|
$admininfo = ((x($_POST,'admininfo')) ? trim($_POST['admininfo']) : false);
|
||||||
|
$siteinfo = ((x($_POST,'siteinfo')) ? trim($_POST['siteinfo']) : '');
|
||||||
$language = ((x($_POST,'language')) ? notags(trim($_POST['language'])) : '');
|
$language = ((x($_POST,'language')) ? notags(trim($_POST['language'])) : '');
|
||||||
$theme = ((x($_POST,'theme')) ? notags(trim($_POST['theme'])) : '');
|
$theme = ((x($_POST,'theme')) ? notags(trim($_POST['theme'])) : '');
|
||||||
$theme_mobile = ((x($_POST,'theme_mobile')) ? notags(trim($_POST['theme_mobile'])) : '');
|
$theme_mobile = ((x($_POST,'theme_mobile')) ? notags(trim($_POST['theme_mobile'])) : '');
|
||||||
// $site_channel = ((x($_POST,'site_channel')) ? notags(trim($_POST['site_channel'])) : '');
|
// $site_channel = ((x($_POST,'site_channel')) ? notags(trim($_POST['site_channel'])) : '');
|
||||||
$maximagesize = ((x($_POST,'maximagesize')) ? intval(trim($_POST['maximagesize'])) : 0);
|
$maximagesize = ((x($_POST,'maximagesize')) ? intval(trim($_POST['maximagesize'])) : 0);
|
||||||
|
|
||||||
$register_policy = ((x($_POST,'register_policy')) ? intval(trim($_POST['register_policy'])) : 0);
|
$register_policy = ((x($_POST,'register_policy')) ? intval(trim($_POST['register_policy'])) : 0);
|
||||||
|
|
||||||
$access_policy = ((x($_POST,'access_policy')) ? intval(trim($_POST['access_policy'])) : 0);
|
$access_policy = ((x($_POST,'access_policy')) ? intval(trim($_POST['access_policy'])) : 0);
|
||||||
$invite_only = ((x($_POST,'invite_only')) ? True : False);
|
$invite_only = ((x($_POST,'invite_only')) ? True : False);
|
||||||
$abandon_days = ((x($_POST,'abandon_days')) ? intval(trim($_POST['abandon_days'])) : 0);
|
$abandon_days = ((x($_POST,'abandon_days')) ? intval(trim($_POST['abandon_days'])) : 0);
|
||||||
|
|
||||||
$register_text = ((x($_POST,'register_text')) ? notags(trim($_POST['register_text'])) : '');
|
$register_text = ((x($_POST,'register_text')) ? notags(trim($_POST['register_text'])) : '');
|
||||||
$frontpage = ((x($_POST,'frontpage')) ? notags(trim($_POST['frontpage'])) : '');
|
$frontpage = ((x($_POST,'frontpage')) ? notags(trim($_POST['frontpage'])) : '');
|
||||||
$mirror_frontpage = ((x($_POST,'mirror_frontpage')) ? intval(trim($_POST['mirror_frontpage'])) : 0);
|
$mirror_frontpage = ((x($_POST,'mirror_frontpage')) ? intval(trim($_POST['mirror_frontpage'])) : 0);
|
||||||
$directory_server = ((x($_POST,'directory_server')) ? trim($_POST['directory_server']) : '');
|
$directory_server = ((x($_POST,'directory_server')) ? trim($_POST['directory_server']) : '');
|
||||||
$allowed_sites = ((x($_POST,'allowed_sites')) ? notags(trim($_POST['allowed_sites'])) : '');
|
$allowed_sites = ((x($_POST,'allowed_sites')) ? notags(trim($_POST['allowed_sites'])) : '');
|
||||||
$force_publish = ((x($_POST,'publish_all')) ? True : False);
|
$force_publish = ((x($_POST,'publish_all')) ? True : False);
|
||||||
$disable_discover_tab = ((x($_POST,'disable_discover_tab')) ? False : True);
|
$disable_discover_tab = ((x($_POST,'disable_discover_tab')) ? False : True);
|
||||||
$login_on_homepage = ((x($_POST,'login_on_homepage')) ? True : False);
|
$login_on_homepage = ((x($_POST,'login_on_homepage')) ? True : False);
|
||||||
$enable_context_help = ((x($_POST,'enable_context_help')) ? True : False);
|
$enable_context_help = ((x($_POST,'enable_context_help')) ? True : False);
|
||||||
$global_directory = ((x($_POST,'directory_submit_url')) ? notags(trim($_POST['directory_submit_url'])) : '');
|
$global_directory = ((x($_POST,'directory_submit_url')) ? notags(trim($_POST['directory_submit_url'])) : '');
|
||||||
$no_community_page = !((x($_POST,'no_community_page')) ? True : False);
|
$no_community_page = !((x($_POST,'no_community_page')) ? True : False);
|
||||||
$default_expire_days = ((array_key_exists('default_expire_days',$_POST)) ? intval($_POST['default_expire_days']) : 0);
|
$default_expire_days = ((array_key_exists('default_expire_days',$_POST)) ? intval($_POST['default_expire_days']) : 0);
|
||||||
|
|
||||||
|
$reply_address = ((array_key_exists('reply_address',$_POST) && trim($_POST['reply_address'])) ? trim($_POST['reply_address']) : 'noreply@' . \App::get_hostname());
|
||||||
|
$from_email = ((array_key_exists('from_email',$_POST) && trim($_POST['from_email'])) ? trim($_POST['from_email']) : 'Administrator@' . \App::get_hostname());
|
||||||
|
$from_email_name = ((array_key_exists('from_email_name',$_POST) && trim($_POST['from_email_name'])) ? trim($_POST['from_email_name']) : \Zotlabs\Lib\System::get_site_name());
|
||||||
|
|
||||||
$verifyssl = ((x($_POST,'verifyssl')) ? True : False);
|
$verifyssl = ((x($_POST,'verifyssl')) ? True : False);
|
||||||
$proxyuser = ((x($_POST,'proxyuser')) ? notags(trim($_POST['proxyuser'])) : '');
|
$proxyuser = ((x($_POST,'proxyuser')) ? notags(trim($_POST['proxyuser'])) : '');
|
||||||
$proxy = ((x($_POST,'proxy')) ? notags(trim($_POST['proxy'])) : '');
|
$proxy = ((x($_POST,'proxy')) ? notags(trim($_POST['proxy'])) : '');
|
||||||
@@ -59,15 +61,15 @@ class Site {
|
|||||||
$maxloadavg = ((x($_POST,'maxloadavg')) ? intval(trim($_POST['maxloadavg'])) : 50);
|
$maxloadavg = ((x($_POST,'maxloadavg')) ? intval(trim($_POST['maxloadavg'])) : 50);
|
||||||
$feed_contacts = ((x($_POST,'feed_contacts')) ? intval($_POST['feed_contacts']) : 0);
|
$feed_contacts = ((x($_POST,'feed_contacts')) ? intval($_POST['feed_contacts']) : 0);
|
||||||
$verify_email = ((x($_POST,'verify_email')) ? 1 : 0);
|
$verify_email = ((x($_POST,'verify_email')) ? 1 : 0);
|
||||||
$techlevel_lock = ((x($_POST,'techlock')) ? intval($_POST['techlock']) : 0);
|
$techlevel_lock = ((x($_POST,'techlock')) ? intval($_POST['techlock']) : 0);
|
||||||
|
$imagick_path = ((x($_POST,'imagick_path')) ? trim($_POST['imagick_path']) : '');
|
||||||
|
$thumbnail_security = ((x($_POST,'thumbnail_security')) ? intval($_POST['thumbnail_security']) : 0);
|
||||||
|
$force_queue = ((intval($_POST['force_queue']) > 0) ? intval($_POST['force_queue']) : 300);
|
||||||
|
|
||||||
$techlevel = null;
|
$techlevel = null;
|
||||||
if(array_key_exists('techlevel',$_POST))
|
if(array_key_exists('techlevel', $_POST))
|
||||||
$techlevel = intval($_POST['techlevel']);
|
$techlevel = intval($_POST['techlevel']);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
set_config('system', 'server_role', $server_role);
|
|
||||||
set_config('system', 'feed_contacts', $feed_contacts);
|
set_config('system', 'feed_contacts', $feed_contacts);
|
||||||
set_config('system', 'delivery_interval', $delivery_interval);
|
set_config('system', 'delivery_interval', $delivery_interval);
|
||||||
set_config('system', 'delivery_batch_count', $delivery_batch_count);
|
set_config('system', 'delivery_batch_count', $delivery_batch_count);
|
||||||
@@ -80,8 +82,16 @@ class Site {
|
|||||||
set_config('system', 'enable_context_help', $enable_context_help);
|
set_config('system', 'enable_context_help', $enable_context_help);
|
||||||
set_config('system', 'verify_email', $verify_email);
|
set_config('system', 'verify_email', $verify_email);
|
||||||
set_config('system', 'default_expire_days', $default_expire_days);
|
set_config('system', 'default_expire_days', $default_expire_days);
|
||||||
|
set_config('system', 'reply_address', $reply_address);
|
||||||
|
set_config('system', 'from_email', $from_email);
|
||||||
|
set_config('system', 'from_email_name' , $from_email_name);
|
||||||
|
set_config('system', 'imagick_convert_path' , $imagick_path);
|
||||||
|
set_config('system', 'thumbnail_security' , $thumbnail_security);
|
||||||
|
|
||||||
set_config('system', 'techlevel_lock', $techlevel_lock);
|
set_config('system', 'techlevel_lock', $techlevel_lock);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(! is_null($techlevel))
|
if(! is_null($techlevel))
|
||||||
set_config('system', 'techlevel', $techlevel);
|
set_config('system', 'techlevel', $techlevel);
|
||||||
|
|
||||||
@@ -101,6 +111,7 @@ class Site {
|
|||||||
linkify_tags($a, $admininfo, local_channel());
|
linkify_tags($a, $admininfo, local_channel());
|
||||||
set_config('system', 'admininfo', $admininfo);
|
set_config('system', 'admininfo', $admininfo);
|
||||||
}
|
}
|
||||||
|
set_config('system','siteinfo',$siteinfo);
|
||||||
set_config('system', 'language', $language);
|
set_config('system', 'language', $language);
|
||||||
set_config('system', 'theme', $theme);
|
set_config('system', 'theme', $theme);
|
||||||
if ( $theme_mobile === '---' ) {
|
if ( $theme_mobile === '---' ) {
|
||||||
@@ -119,6 +130,7 @@ class Site {
|
|||||||
set_config('system','allowed_sites', $allowed_sites);
|
set_config('system','allowed_sites', $allowed_sites);
|
||||||
set_config('system','publish_all', $force_publish);
|
set_config('system','publish_all', $force_publish);
|
||||||
set_config('system','disable_discover_tab', $disable_discover_tab);
|
set_config('system','disable_discover_tab', $disable_discover_tab);
|
||||||
|
set_config('system','force_queue_threshold', $force_queue);
|
||||||
if ($global_directory == '') {
|
if ($global_directory == '') {
|
||||||
del_config('system', 'directory_submit_url');
|
del_config('system', 'directory_submit_url');
|
||||||
} else {
|
} else {
|
||||||
@@ -139,9 +151,8 @@ class Site {
|
|||||||
/**
|
/**
|
||||||
* @brief Admin page site.
|
* @brief Admin page site.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string with HTML
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
|
||||||
/* Installed langs */
|
/* Installed langs */
|
||||||
@@ -166,6 +177,14 @@ class Site {
|
|||||||
foreach($files as $file) {
|
foreach($files as $file) {
|
||||||
$vars = '';
|
$vars = '';
|
||||||
$f = basename($file);
|
$f = basename($file);
|
||||||
|
|
||||||
|
$info = get_theme_info($f);
|
||||||
|
$compatible = check_plugin_versions($info);
|
||||||
|
if(!$compatible) {
|
||||||
|
$theme_choices[$f] = $theme_choices_mobile[$f] = sprintf(t('%s - (Incompatible)'), $f);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (file_exists($file . '/library'))
|
if (file_exists($file . '/library'))
|
||||||
continue;
|
continue;
|
||||||
if (file_exists($file . '/mobile'))
|
if (file_exists($file . '/mobile'))
|
||||||
@@ -192,7 +211,7 @@ class Site {
|
|||||||
// directory server should not be set or settable unless we are a directory client
|
// directory server should not be set or settable unless we are a directory client
|
||||||
|
|
||||||
if($dirmode == DIRECTORY_MODE_NORMAL) {
|
if($dirmode == DIRECTORY_MODE_NORMAL) {
|
||||||
$x = q("select site_url from site where site_flags in (%d,%d) and site_realm = '%s'",
|
$x = q("select site_url from site where site_flags in (%d,%d) and site_realm = '%s' and site_dead = 0",
|
||||||
intval(DIRECTORY_MODE_SECONDARY),
|
intval(DIRECTORY_MODE_SECONDARY),
|
||||||
intval(DIRECTORY_MODE_PRIMARY),
|
intval(DIRECTORY_MODE_PRIMARY),
|
||||||
dbesc($realm)
|
dbesc($realm)
|
||||||
@@ -232,19 +251,13 @@ class Site {
|
|||||||
);
|
);
|
||||||
|
|
||||||
$discover_tab = get_config('system','disable_discover_tab');
|
$discover_tab = get_config('system','disable_discover_tab');
|
||||||
|
|
||||||
// $disable public streams by default
|
// $disable public streams by default
|
||||||
if($discover_tab === false)
|
if($discover_tab === false)
|
||||||
$discover_tab = 1;
|
$discover_tab = 1;
|
||||||
// now invert the logic for the setting.
|
// now invert the logic for the setting.
|
||||||
$discover_tab = (1 - $discover_tab);
|
$discover_tab = (1 - $discover_tab);
|
||||||
|
|
||||||
$server_roles = [
|
|
||||||
'basic' => t('Basic/Minimal Social Networking'),
|
|
||||||
'standard' => t('Standard Configuration (default)'),
|
|
||||||
'pro' => t('Professional')
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
$techlevels = [
|
$techlevels = [
|
||||||
'0' => t('Beginner/Basic'),
|
'0' => t('Beginner/Basic'),
|
||||||
'1' => t('Novice - not skilled but willing to learn'),
|
'1' => t('Novice - not skilled but willing to learn'),
|
||||||
@@ -254,9 +267,6 @@ class Site {
|
|||||||
'5' => t('Wizard - I probably know more than you do')
|
'5' => t('Wizard - I probably know more than you do')
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$homelogin = get_config('system','login_on_homepage');
|
$homelogin = get_config('system','login_on_homepage');
|
||||||
$enable_context_help = get_config('system','enable_context_help');
|
$enable_context_help = get_config('system','enable_context_help');
|
||||||
|
|
||||||
@@ -274,19 +284,17 @@ class Site {
|
|||||||
// name, label, value, help string, extra data...
|
// name, label, value, help string, extra data...
|
||||||
'$sitename' => array('sitename', t("Site name"), htmlspecialchars(get_config('system','sitename'), ENT_QUOTES, 'UTF-8'),''),
|
'$sitename' => array('sitename', t("Site name"), htmlspecialchars(get_config('system','sitename'), ENT_QUOTES, 'UTF-8'),''),
|
||||||
|
|
||||||
'$server_role' => array('server_role', t("Server Configuration/Role"), get_config('system','server_role'),'',$server_roles),
|
|
||||||
|
|
||||||
'$techlevel' => [ 'techlevel', t('Site default technical skill level'), get_config('system','techlevel'), t('Used to provide a member experience matched to technical comfort level'), $techlevels ],
|
'$techlevel' => [ 'techlevel', t('Site default technical skill level'), get_config('system','techlevel'), t('Used to provide a member experience matched to technical comfort level'), $techlevels ],
|
||||||
|
|
||||||
'$techlock' => [ 'techlock', t('Lock the technical skill level setting'), get_config('system','techlevel_lock'), t('Members can set their own technical comfort level by default') ],
|
'$techlock' => [ 'techlock', t('Lock the technical skill level setting'), get_config('system','techlevel_lock'), t('Members can set their own technical comfort level by default') ],
|
||||||
|
|
||||||
|
|
||||||
'$banner' => array('banner', t("Banner/Logo"), $banner, ""),
|
'$banner' => array('banner', t("Banner/Logo"), $banner, ""),
|
||||||
'$admininfo' => array('admininfo', t("Administrator Information"), $admininfo, t("Contact information for site administrators. Displayed on siteinfo page. BBCode can be used here")),
|
'$admininfo' => array('admininfo', t("Administrator Information"), $admininfo, t("Contact information for site administrators. Displayed on siteinfo page. BBCode can be used here")),
|
||||||
|
'$siteinfo' => array('siteinfo', t('Site Information'), get_config('system','siteinfo'), t("Publicly visible description of this site. Displayed on siteinfo page. BBCode can be used here")),
|
||||||
'$language' => array('language', t("System language"), get_config('system','language'), "", $lang_choices),
|
'$language' => array('language', t("System language"), get_config('system','language'), "", $lang_choices),
|
||||||
'$theme' => array('theme', t("System theme"), get_config('system','theme'), t("Default system theme - may be over-ridden by user profiles - <a href='#' id='cnftheme'>change theme settings</a>"), $theme_choices),
|
'$theme' => array('theme', t("System theme"), get_config('system','theme'), t("Default system theme - may be over-ridden by user profiles - <a href='#' id='cnftheme'>change theme settings</a>"), $theme_choices),
|
||||||
'$theme_mobile' => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile_theme'), t("Theme for mobile devices"), $theme_choices_mobile),
|
'$theme_mobile' => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile_theme'), t("Theme for mobile devices"), $theme_choices_mobile),
|
||||||
// '$site_channel' => array('site_channel', t("Channel to use for this website's static pages"), get_config('system','site_channel'), t("Site Channel")),
|
// '$site_channel' => array('site_channel', t("Channel to use for this website's static pages"), get_config('system','site_channel'), t("Site Channel")),
|
||||||
'$feed_contacts' => array('feed_contacts', t('Allow Feeds as Connections'),get_config('system','feed_contacts'),t('(Heavy system resource usage)')),
|
'$feed_contacts' => array('feed_contacts', t('Allow Feeds as Connections'),get_config('system','feed_contacts'),t('(Heavy system resource usage)')),
|
||||||
'$maximagesize' => array('maximagesize', t("Maximum image size"), intval(get_config('system','maximagesize')), t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")),
|
'$maximagesize' => array('maximagesize', t("Maximum image size"), intval(get_config('system','maximagesize')), t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")),
|
||||||
'$register_policy' => array('register_policy', t("Does this site allow new member registration?"), get_config('system','register_policy'), "", $register_choices),
|
'$register_policy' => array('register_policy', t("Does this site allow new member registration?"), get_config('system','register_policy'), "", $register_choices),
|
||||||
@@ -303,6 +311,10 @@ class Site {
|
|||||||
'$login_on_homepage' => array('login_on_homepage', t("Login on Homepage"),((intval($homelogin) || $homelogin === false) ? 1 : '') , t("Present a login box to visitors on the home page if no other content has been configured.")),
|
'$login_on_homepage' => array('login_on_homepage', t("Login on Homepage"),((intval($homelogin) || $homelogin === false) ? 1 : '') , t("Present a login box to visitors on the home page if no other content has been configured.")),
|
||||||
'$enable_context_help' => array('enable_context_help', t("Enable context help"),((intval($enable_context_help) === 1 || $enable_context_help === false) ? 1 : 0) , t("Display contextual help for the current page when the help button is pressed.")),
|
'$enable_context_help' => array('enable_context_help', t("Enable context help"),((intval($enable_context_help) === 1 || $enable_context_help === false) ? 1 : 0) , t("Display contextual help for the current page when the help button is pressed.")),
|
||||||
|
|
||||||
|
'$reply_address' => [ 'reply_address', t('Reply-to email address for system generated email.'), get_config('system','reply_address','noreply@' . \App::get_hostname()),'' ],
|
||||||
|
'$from_email' => [ 'from_email', t('Sender (From) email address for system generated email.'), get_config('system','from_email','Administrator@' . \App::get_hostname()),'' ],
|
||||||
|
'$from_email_name' => [ 'from_email_name', t('Name of email sender for system generated email.'), get_config('system','from_email_name',\Zotlabs\Lib\System::get_site_name()),'' ],
|
||||||
|
|
||||||
'$directory_server' => (($dir_choices) ? array('directory_server', t("Directory Server URL"), get_config('system','directory_server'), t("Default directory server"), $dir_choices) : null),
|
'$directory_server' => (($dir_choices) ? array('directory_server', t("Directory Server URL"), get_config('system','directory_server'), t("Default directory server"), $dir_choices) : null),
|
||||||
|
|
||||||
'$proxyuser' => array('proxyuser', t("Proxy user"), get_config('system','proxyuser'), ""),
|
'$proxyuser' => array('proxyuser', t("Proxy user"), get_config('system','proxyuser'), ""),
|
||||||
@@ -310,14 +322,14 @@ class Site {
|
|||||||
'$timeout' => array('timeout', t("Network timeout"), (x(get_config('system','curl_timeout'))?get_config('system','curl_timeout'):60), t("Value is in seconds. Set to 0 for unlimited (not recommended).")),
|
'$timeout' => array('timeout', t("Network timeout"), (x(get_config('system','curl_timeout'))?get_config('system','curl_timeout'):60), t("Value is in seconds. Set to 0 for unlimited (not recommended).")),
|
||||||
'$delivery_interval' => array('delivery_interval', t("Delivery interval"), (x(get_config('system','delivery_interval'))?get_config('system','delivery_interval'):2), t("Delay background delivery processes by this many seconds to reduce system load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 for large dedicated servers.")),
|
'$delivery_interval' => array('delivery_interval', t("Delivery interval"), (x(get_config('system','delivery_interval'))?get_config('system','delivery_interval'):2), t("Delay background delivery processes by this many seconds to reduce system load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 for large dedicated servers.")),
|
||||||
'$delivery_batch_count' => array('delivery_batch_count', t('Deliveries per process'),(x(get_config('system','delivery_batch_count'))?get_config('system','delivery_batch_count'):1), t("Number of deliveries to attempt in a single operating system process. Adjust if necessary to tune system performance. Recommend: 1-5.")),
|
'$delivery_batch_count' => array('delivery_batch_count', t('Deliveries per process'),(x(get_config('system','delivery_batch_count'))?get_config('system','delivery_batch_count'):1), t("Number of deliveries to attempt in a single operating system process. Adjust if necessary to tune system performance. Recommend: 1-5.")),
|
||||||
|
'$force_queue' => array('force_queue', t("Queue Threshold"), get_config('system','force_queue_threshold',300), t("Always defer immediate delivery if queue contains more than this number of entries.")),
|
||||||
'$poll_interval' => array('poll_interval', t("Poll interval"), (x(get_config('system','poll_interval'))?get_config('system','poll_interval'):2), t("Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval.")),
|
'$poll_interval' => array('poll_interval', t("Poll interval"), (x(get_config('system','poll_interval'))?get_config('system','poll_interval'):2), t("Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval.")),
|
||||||
|
'$imagick_path' => array('imagick_path', t("Path to ImageMagick convert program"), get_config('system','imagick_convert_path'), t("If set, use this program to generate photo thumbnails for huge images ( > 4000 pixels in either dimension), otherwise memory exhaustion may occur. Example: /usr/bin/convert")),
|
||||||
|
'$thumbnail_security' => array('thumbnail_security', t("Allow SVG thumbnails in file browser"), get_config('system','thumbnail_security',0), t("WARNING: SVG images may contain malicious code.")),
|
||||||
'$maxloadavg' => array('maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")),
|
'$maxloadavg' => array('maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")),
|
||||||
'$default_expire_days' => array('default_expire_days', t('Expiration period in days for imported (grid/network) content'), intval(get_config('system','default_expire_days')), t('0 for no expiration of imported content')),
|
'$default_expire_days' => array('default_expire_days', t('Expiration period in days for imported (grid/network) content'), intval(get_config('system','default_expire_days')), t('0 for no expiration of imported content')),
|
||||||
'$form_security_token' => get_form_security_token("admin_site"),
|
'$form_security_token' => get_form_security_token("admin_site"),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2,16 +2,24 @@
|
|||||||
|
|
||||||
namespace Zotlabs\Module\Admin;
|
namespace Zotlabs\Module\Admin;
|
||||||
|
|
||||||
|
use \Michelf\MarkdownExtra;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Admin area theme settings.
|
||||||
|
*/
|
||||||
class Themes {
|
class Themes {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
*/
|
||||||
function post() {
|
function post() {
|
||||||
|
|
||||||
$theme = argv(2);
|
$theme = argv(2);
|
||||||
if (is_file("view/theme/$theme/php/config.php")){
|
if (is_file("view/theme/$theme/php/config.php")){
|
||||||
require_once("view/theme/$theme/php/config.php");
|
require_once("view/theme/$theme/php/config.php");
|
||||||
// fixme add parent theme if derived
|
/// @FIXME add parent theme if derived
|
||||||
if (function_exists("theme_admin_post")){
|
if (function_exists('theme_admin_post')){
|
||||||
theme_admin_post($a);
|
theme_admin_post($a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -23,17 +31,12 @@ class Themes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Themes admin page.
|
* @brief Themes admin page.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string with parsed HTML
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function get(){
|
function get(){
|
||||||
|
|
||||||
$allowed_themes_str = get_config('system', 'allowed_themes');
|
$allowed_themes_str = get_config('system', 'allowed_themes');
|
||||||
$allowed_themes_raw = explode(',', $allowed_themes_str);
|
$allowed_themes_raw = explode(',', $allowed_themes_str);
|
||||||
$allowed_themes = array();
|
$allowed_themes = array();
|
||||||
@@ -87,7 +90,6 @@ class Themes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// display theme details
|
// display theme details
|
||||||
require_once('library/markdown.php');
|
|
||||||
|
|
||||||
if ($this->theme_status($themes,$theme)) {
|
if ($this->theme_status($themes,$theme)) {
|
||||||
$status="on"; $action= t("Disable");
|
$status="on"; $action= t("Disable");
|
||||||
@@ -98,9 +100,9 @@ class Themes {
|
|||||||
$readme=Null;
|
$readme=Null;
|
||||||
if (is_file("view/theme/$theme/README.md")){
|
if (is_file("view/theme/$theme/README.md")){
|
||||||
$readme = file_get_contents("view/theme/$theme/README.md");
|
$readme = file_get_contents("view/theme/$theme/README.md");
|
||||||
$readme = Markdown($readme);
|
$readme = MarkdownExtra::defaultTransform($readme);
|
||||||
} else if (is_file("view/theme/$theme/README")){
|
} else if (is_file("view/theme/$theme/README")){
|
||||||
$readme = "<pre>". file_get_contents("view/theme/$theme/README") ."</pre>";
|
$readme = '<pre>'. file_get_contents("view/theme/$theme/README") .'</pre>';
|
||||||
}
|
}
|
||||||
|
|
||||||
$admin_form = '';
|
$admin_form = '';
|
||||||
@@ -164,11 +166,12 @@ class Themes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $themes
|
* @brief Toggle a theme.
|
||||||
* @param string $th
|
*
|
||||||
* @param int $result
|
* @param array &$themes
|
||||||
|
* @param[in] string $th
|
||||||
|
* @param[out] int &$result
|
||||||
*/
|
*/
|
||||||
function toggle_theme(&$themes, $th, &$result) {
|
function toggle_theme(&$themes, $th, &$result) {
|
||||||
for($x = 0; $x < count($themes); $x ++) {
|
for($x = 0; $x < count($themes); $x ++) {
|
||||||
@@ -204,7 +207,6 @@ class Themes {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $themes
|
* @param array $themes
|
||||||
* @return string
|
* @return string
|
||||||
@@ -223,11 +225,4 @@ class Themes {
|
|||||||
return $o;
|
return $o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3,10 +3,22 @@ namespace Zotlabs\Module;
|
|||||||
|
|
||||||
require_once('include/api.php');
|
require_once('include/api.php');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Api extends \Zotlabs\Web\Controller {
|
class Api extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
zot_api_init();
|
||||||
|
|
||||||
|
api_register_func('api/client/register', 'api_client_register', false);
|
||||||
|
api_register_func('api/oauth/request_token', 'api_oauth_request_token', false);
|
||||||
|
api_register_func('api/oauth/access_token', 'api_oauth_access_token', false);
|
||||||
|
|
||||||
|
$args = [];
|
||||||
|
call_hooks('api_register',$args);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
function post() {
|
function post() {
|
||||||
if(! local_channel()) {
|
if(! local_channel()) {
|
||||||
notice( t('Permission denied.') . EOL);
|
notice( t('Permission denied.') . EOL);
|
||||||
@@ -17,13 +29,13 @@ class Api extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
|
||||||
if(\App::$cmd=='api/oauth/authorize'){
|
if(\App::$cmd === 'api/oauth/authorize'){
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* api/oauth/authorize interact with the user. return a standard page
|
* api/oauth/authorize interact with the user. return a standard page
|
||||||
*/
|
*/
|
||||||
|
|
||||||
\App::$page['template'] = "minimal";
|
\App::$page['template'] = 'minimal';
|
||||||
|
|
||||||
// get consumer/client from request token
|
// get consumer/client from request token
|
||||||
try {
|
try {
|
||||||
@@ -42,8 +54,8 @@ class Api extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$consumer = new OAuth1Consumer($app['client_id'], $app['pw'], $app['redirect_uri']);
|
$consumer = new OAuth1Consumer($app['client_id'], $app['pw'], $app['redirect_uri']);
|
||||||
|
|
||||||
$verifier = md5($app['secret'].local_channel());
|
$verifier = md5($app['secret'] . local_channel());
|
||||||
set_config("oauth", $verifier, local_channel());
|
set_config('oauth', $verifier, local_channel());
|
||||||
|
|
||||||
|
|
||||||
if($consumer->callback_url != null) {
|
if($consumer->callback_url != null) {
|
||||||
@@ -78,11 +90,11 @@ class Api extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$tpl = get_markup_template('oauth_authorize.tpl');
|
$tpl = get_markup_template('oauth_authorize.tpl');
|
||||||
$o = replace_macros($tpl, array(
|
$o = replace_macros($tpl, array(
|
||||||
'$title' => t('Authorize application connection'),
|
'$title' => t('Authorize application connection'),
|
||||||
'$app' => $app,
|
'$app' => $app,
|
||||||
'$authorize' => t('Do you want to authorize this application to access your posts and contacts, and/or create new posts for you?'),
|
'$authorize' => t('Do you want to authorize this application to access your posts and contacts, and/or create new posts for you?'),
|
||||||
'$yes' => t('Yes'),
|
'$yes' => t('Yes'),
|
||||||
'$no' => t('No'),
|
'$no' => t('No'),
|
||||||
));
|
));
|
||||||
|
|
||||||
//echo "<pre>"; var_dump($app); killme();
|
//echo "<pre>"; var_dump($app); killme();
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class Appman extends \Zotlabs\Web\Controller {
|
|||||||
'price' => escape_tags($_REQUEST['price']),
|
'price' => escape_tags($_REQUEST['price']),
|
||||||
'requires' => escape_tags($_REQUEST['requires']),
|
'requires' => escape_tags($_REQUEST['requires']),
|
||||||
'system' => intval($_REQUEST['system']),
|
'system' => intval($_REQUEST['system']),
|
||||||
|
'plugin' => escape_tags($_REQUEST['plugin']),
|
||||||
'sig' => escape_tags($_REQUEST['sig']),
|
'sig' => escape_tags($_REQUEST['sig']),
|
||||||
'categories' => escape_tags($_REQUEST['categories'])
|
'categories' => escape_tags($_REQUEST['categories'])
|
||||||
);
|
);
|
||||||
@@ -36,7 +37,8 @@ class Appman extends \Zotlabs\Web\Controller {
|
|||||||
if(Zlib\Apps::app_installed(local_channel(),$arr))
|
if(Zlib\Apps::app_installed(local_channel(),$arr))
|
||||||
info( t('App installed.') . EOL);
|
info( t('App installed.') . EOL);
|
||||||
|
|
||||||
return;
|
goaway(z_root() . '/apps');
|
||||||
|
return; //not reached
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -61,8 +63,17 @@ class Appman extends \Zotlabs\Web\Controller {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($_POST['feature']) {
|
||||||
|
Zlib\Apps::app_feature(local_channel(), $papp, $_POST['feature']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($_POST['pin']) {
|
||||||
|
Zlib\Apps::app_feature(local_channel(), $papp, $_POST['pin']);
|
||||||
|
}
|
||||||
|
|
||||||
if($_SESSION['return_url'])
|
if($_SESSION['return_url'])
|
||||||
goaway(z_root() . '/' . $_SESSION['return_url']);
|
goaway(z_root() . '/' . $_SESSION['return_url']);
|
||||||
|
|
||||||
goaway(z_root() . '/apps');
|
goaway(z_root() . '/apps');
|
||||||
|
|
||||||
|
|
||||||
@@ -77,6 +88,20 @@ class Appman extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$channel = \App::get_channel();
|
$channel = \App::get_channel();
|
||||||
|
|
||||||
|
if(argc() > 2) {
|
||||||
|
if(argv(2) === 'moveup') {
|
||||||
|
Zlib\Apps::moveup(local_channel(),argv(1));
|
||||||
|
}
|
||||||
|
if(argv(2) === 'movedown') {
|
||||||
|
Zlib\Apps::movedown(local_channel(),argv(1));
|
||||||
|
}
|
||||||
|
goaway(z_root() . '/apporder');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$app = null;
|
$app = null;
|
||||||
$embed = null;
|
$embed = null;
|
||||||
if($_REQUEST['appid']) {
|
if($_REQUEST['appid']) {
|
||||||
@@ -121,6 +146,7 @@ class Appman extends \Zotlabs\Web\Controller {
|
|||||||
'$price' => array('price', t('Price of app'),(($app) ? $app['app_price'] : ''), ''),
|
'$price' => array('price', t('Price of app'),(($app) ? $app['app_price'] : ''), ''),
|
||||||
'$page' => array('page', t('Location (URL) to purchase app'),(($app) ? $app['app_page'] : ''), ''),
|
'$page' => array('page', t('Location (URL) to purchase app'),(($app) ? $app['app_page'] : ''), ''),
|
||||||
'$system' => (($app) ? intval($app['app_system']) : 0),
|
'$system' => (($app) ? intval($app['app_system']) : 0),
|
||||||
|
'$plugin' => (($app) ? $app['app_plugin'] : ''),
|
||||||
'$requires' => (($app) ? $app['app_requires'] : ''),
|
'$requires' => (($app) ? $app['app_requires'] : ''),
|
||||||
'$embed' => $embed,
|
'$embed' => $embed,
|
||||||
'$submit' => t('Submit')
|
'$submit' => t('Submit')
|
||||||
|
|||||||
51
Zotlabs/Module/Apporder.php
Normal file
51
Zotlabs/Module/Apporder.php
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zotlabs\Module;
|
||||||
|
|
||||||
|
use \Zotlabs\Lib as Zlib;
|
||||||
|
|
||||||
|
class Apporder extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
|
function post() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function get() {
|
||||||
|
|
||||||
|
if(! local_channel())
|
||||||
|
return;
|
||||||
|
|
||||||
|
nav_set_selected('Order Apps');
|
||||||
|
|
||||||
|
$syslist = array();
|
||||||
|
$list = Zlib\Apps::app_list(local_channel(), false, ['nav_featured_app', 'nav_pinned_app']);
|
||||||
|
if($list) {
|
||||||
|
foreach($list as $li) {
|
||||||
|
$syslist[] = Zlib\Apps::app_encode($li);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Zlib\Apps::translate_system_apps($syslist);
|
||||||
|
|
||||||
|
usort($syslist,'Zotlabs\\Lib\\Apps::app_name_compare');
|
||||||
|
|
||||||
|
$syslist = Zlib\Apps::app_order(local_channel(),$syslist);
|
||||||
|
|
||||||
|
foreach($syslist as $app) {
|
||||||
|
if(strpos($app['categories'],'nav_pinned_app') !== false) {
|
||||||
|
$navbar_apps[] = Zlib\Apps::app_render($app,'nav-order');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$nav_apps[] = Zlib\Apps::app_render($app,'nav-order');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return replace_macros(get_markup_template('apporder.tpl'),
|
||||||
|
[
|
||||||
|
'$header' => [t('Change Order of Pinned Navbar Apps'), t('Change Order of App Tray Apps')],
|
||||||
|
'$desc' => [t('Use arrows to move the corresponding app left (top) or right (bottom) in the navbar'), t('Use arrows to move the corresponding app up or down in the app tray')],
|
||||||
|
'$nav_apps' => $nav_apps,
|
||||||
|
'$navbar_apps' => $navbar_apps
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,20 +8,22 @@ class Apps extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
|
||||||
|
nav_set_selected('Apps');
|
||||||
|
|
||||||
if(argc() == 2 && argv(1) == 'edit')
|
if(argc() == 2 && argv(1) == 'edit')
|
||||||
$mode = 'edit';
|
$mode = 'edit';
|
||||||
else
|
else
|
||||||
$mode = 'list';
|
$mode = 'list';
|
||||||
|
|
||||||
$_SESSION['return_url'] = \App::$cmd;
|
$_SESSION['return_url'] = \App::$query_string;
|
||||||
|
|
||||||
$apps = array();
|
$apps = array();
|
||||||
|
|
||||||
|
|
||||||
if(local_channel()) {
|
if(local_channel()) {
|
||||||
Zlib\Apps::import_system_apps();
|
Zlib\Apps::import_system_apps();
|
||||||
$syslist = array();
|
$syslist = array();
|
||||||
$list = Zlib\Apps::app_list(local_channel(), false, $_GET['cat']);
|
$cat = ((array_key_exists('cat',$_GET) && $_GET['cat']) ? [ escape_tags($_GET['cat']) ] : '');
|
||||||
|
$list = Zlib\Apps::app_list(local_channel(), (($mode == 'edit') ? true : false), $cat);
|
||||||
if($list) {
|
if($list) {
|
||||||
foreach($list as $x) {
|
foreach($list as $x) {
|
||||||
$syslist[] = Zlib\Apps::app_encode($x);
|
$syslist[] = Zlib\Apps::app_encode($x);
|
||||||
@@ -42,9 +44,12 @@ class Apps extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
return replace_macros(get_markup_template('myapps.tpl'), array(
|
return replace_macros(get_markup_template('myapps.tpl'), array(
|
||||||
'$sitename' => get_config('system','sitename'),
|
'$sitename' => get_config('system','sitename'),
|
||||||
'$cat' => ((array_key_exists('cat',$_GET) && $_GET['cat']) ? ' - ' . escape_tags($_GET['cat']) : ''),
|
'$cat' => $cat,
|
||||||
'$title' => t('Apps'),
|
'$title' => t('Apps'),
|
||||||
'$apps' => $apps,
|
'$apps' => $apps,
|
||||||
|
'$authed' => ((local_channel()) ? true : false),
|
||||||
|
'$manage' => t('Manage apps'),
|
||||||
|
'$create' => (($mode == 'edit') ? t('Create new app') : '')
|
||||||
));
|
));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
138
Zotlabs/Module/Article_edit.php
Normal file
138
Zotlabs/Module/Article_edit.php
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
<?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'),
|
||||||
|
'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);
|
||||||
|
|
||||||
|
$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'],
|
||||||
|
'$editor' => $editor
|
||||||
|
));
|
||||||
|
|
||||||
|
return $o;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
187
Zotlabs/Module/Articles.php
Normal file
187
Zotlabs/Module/Articles.php
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
<?php
|
||||||
|
namespace Zotlabs\Module;
|
||||||
|
|
||||||
|
require_once('include/channel.php');
|
||||||
|
require_once('include/conversation.php');
|
||||||
|
require_once('include/acl_selectors.php');
|
||||||
|
|
||||||
|
|
||||||
|
class Articles extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
|
||||||
|
if(argc() > 1)
|
||||||
|
$which = argv(1);
|
||||||
|
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(! feature_enabled(\App::$profile_uid,'articles')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav_set_selected(t('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 = 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('Create'),
|
||||||
|
'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,
|
||||||
|
\Zotlabs\Lib\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);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$editor = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$sql_extra = item_permissions_sql($owner);
|
||||||
|
|
||||||
|
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_extra .= "and item.id = " . intval($r[0]['iid']) . " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$r = q("select * from item
|
||||||
|
where item.uid = %d and item_type = %d
|
||||||
|
$sql_extra order by item.created desc",
|
||||||
|
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) {
|
||||||
|
|
||||||
|
$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 = conv_sort($items,'updated');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
$items = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$mode = 'articles';
|
||||||
|
|
||||||
|
$content = conversation($items,$mode,false,'traditional');
|
||||||
|
|
||||||
|
$o = replace_macros(get_markup_template('cards.tpl'), [
|
||||||
|
'$title' => t('Articles'),
|
||||||
|
'$editor' => $editor,
|
||||||
|
'$content' => $content,
|
||||||
|
'$pager' => alt_pager($a,count($items))
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $o;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -31,7 +31,7 @@ class Attach extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$unsafe_types = array('text/html','text/css','application/javascript');
|
$unsafe_types = array('text/html','text/css','application/javascript');
|
||||||
|
|
||||||
if(in_array($r['data']['filetype'],$unsafe_types)) {
|
if(in_array($r['data']['filetype'],$unsafe_types) && (! channel_codeallowed($r['data']['uid']))) {
|
||||||
header('Content-type: text/plain');
|
header('Content-type: text/plain');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
71
Zotlabs/Module/Authorize.php
Normal file
71
Zotlabs/Module/Authorize.php
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zotlabs\Module;
|
||||||
|
|
||||||
|
|
||||||
|
class Authorize extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
|
|
||||||
|
function get() {
|
||||||
|
|
||||||
|
|
||||||
|
// workaround for HTTP-auth in CGI mode
|
||||||
|
if (x($_SERVER, 'REDIRECT_REMOTE_USER')) {
|
||||||
|
$userpass = base64_decode(substr($_SERVER["REDIRECT_REMOTE_USER"], 6)) ;
|
||||||
|
if(strlen($userpass)) {
|
||||||
|
list($name, $password) = explode(':', $userpass);
|
||||||
|
$_SERVER['PHP_AUTH_USER'] = $name;
|
||||||
|
$_SERVER['PHP_AUTH_PW'] = $password;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x($_SERVER, 'HTTP_AUTHORIZATION')) {
|
||||||
|
$userpass = base64_decode(substr($_SERVER["HTTP_AUTHORIZATION"], 6)) ;
|
||||||
|
if(strlen($userpass)) {
|
||||||
|
list($name, $password) = explode(':', $userpass);
|
||||||
|
$_SERVER['PHP_AUTH_USER'] = $name;
|
||||||
|
$_SERVER['PHP_AUTH_PW'] = $password;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
require_once('include/oauth2.php');
|
||||||
|
|
||||||
|
$request = \OAuth2\Request::createFromGlobals();
|
||||||
|
$response = new \OAuth2\Response();
|
||||||
|
|
||||||
|
// validate the authorize request
|
||||||
|
if (! $oauth2_server->validateAuthorizeRequest($request, $response)) {
|
||||||
|
$response->send();
|
||||||
|
killme();
|
||||||
|
}
|
||||||
|
|
||||||
|
// display an authorization form
|
||||||
|
if (empty($_POST)) {
|
||||||
|
|
||||||
|
return '
|
||||||
|
<form method="post">
|
||||||
|
<label>Do You Authorize TestClient?</label><br />
|
||||||
|
<input type="submit" name="authorized" value="yes">
|
||||||
|
<input type="submit" name="authorized" value="no">
|
||||||
|
</form>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// print the authorization code if the user has authorized your client
|
||||||
|
$is_authorized = ($_POST['authorized'] === 'yes');
|
||||||
|
$oauth2_server->handleAuthorizeRequest($request, $response, $is_authorized);
|
||||||
|
if ($is_authorized) {
|
||||||
|
// this is only here so that you get to see your code in the cURL request. Otherwise,
|
||||||
|
// we'd redirect back to the client
|
||||||
|
$code = substr($response->getHttpHeader('Location'), strpos($response->getHttpHeader('Location'), 'code=')+5, 40);
|
||||||
|
echo("SUCCESS! Authorization Code: $code");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$response->send();
|
||||||
|
killme();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,8 +3,6 @@ namespace Zotlabs\Module;
|
|||||||
|
|
||||||
require_once('include/items.php');
|
require_once('include/items.php');
|
||||||
require_once('include/conversation.php');
|
require_once('include/conversation.php');
|
||||||
require_once('include/page_widgets.php');
|
|
||||||
|
|
||||||
|
|
||||||
class Block extends \Zotlabs\Web\Controller {
|
class Block extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ class Bookmarks extends \Zotlabs\Web\Controller {
|
|||||||
function init() {
|
function init() {
|
||||||
if(! local_channel())
|
if(! local_channel())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
nav_set_selected('View Bookmarks');
|
||||||
|
|
||||||
$item_id = intval($_REQUEST['item']);
|
$item_id = intval($_REQUEST['item']);
|
||||||
$burl = trim($_REQUEST['burl']);
|
$burl = trim($_REQUEST['burl']);
|
||||||
|
|
||||||
@@ -68,7 +71,8 @@ class Bookmarks extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$channel = \App::get_channel();
|
$channel = \App::get_channel();
|
||||||
|
|
||||||
$o = profile_tabs($a,true,$channel['channel_address']);
|
//$o = profile_tabs($a,true,$channel['channel_address']);
|
||||||
|
$o = '';
|
||||||
|
|
||||||
$o .= '<div class="generic-content-wrapper-styled">';
|
$o .= '<div class="generic-content-wrapper-styled">';
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ class Cal extends \Zotlabs\Web\Controller {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nav_set_selected('Calendar');
|
||||||
|
|
||||||
$sql_extra = permissions_sql($channel['channel_id'],get_observer_hash(),'event');
|
$sql_extra = permissions_sql($channel['channel_id'],get_observer_hash(),'event');
|
||||||
|
|
||||||
$first_day = get_pconfig(local_channel(),'system','cal_first_day');
|
$first_day = get_pconfig(local_channel(),'system','cal_first_day');
|
||||||
@@ -86,7 +88,8 @@ class Cal extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$o = '';
|
$o = '';
|
||||||
|
|
||||||
$tabs = profile_tabs($a, True, $channel['channel_address']);
|
//$tabs = profile_tabs($a, True, $channel['channel_address']);
|
||||||
|
$tabs = '';
|
||||||
|
|
||||||
$mode = 'view';
|
$mode = 'view';
|
||||||
$y = 0;
|
$y = 0;
|
||||||
@@ -109,7 +112,7 @@ class Cal extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
/* edit/create form */
|
/* edit/create form */
|
||||||
if($event_id) {
|
if($event_id) {
|
||||||
$r = q("SELECT * FROM `event` WHERE event_hash = '%s' AND `uid` = %d LIMIT 1",
|
$r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1",
|
||||||
dbesc($event_id),
|
dbesc($event_id),
|
||||||
intval($channel['channel_id'])
|
intval($channel['channel_id'])
|
||||||
);
|
);
|
||||||
@@ -209,6 +212,10 @@ class Cal extends \Zotlabs\Web\Controller {
|
|||||||
$adjust_start = datetime_convert('UTC', date_default_timezone_get(), $start);
|
$adjust_start = datetime_convert('UTC', date_default_timezone_get(), $start);
|
||||||
$adjust_finish = datetime_convert('UTC', date_default_timezone_get(), $finish);
|
$adjust_finish = datetime_convert('UTC', date_default_timezone_get(), $finish);
|
||||||
|
|
||||||
|
|
||||||
|
if(! perm_is_allowed(\App::$profile['uid'],get_observer_hash(),'view_contacts'))
|
||||||
|
$sql_extra .= " and etype != 'birthday' ";
|
||||||
|
|
||||||
if (x($_GET,'id')){
|
if (x($_GET,'id')){
|
||||||
$r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan
|
$r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan
|
||||||
from event left join item on resource_id = event_hash where resource_type = 'event' and event.uid = %d and event.id = %d $sql_extra limit 1",
|
from event left join item on resource_id = event_hash where resource_type = 'event' and event.uid = %d and event.id = %d $sql_extra limit 1",
|
||||||
@@ -224,7 +231,7 @@ class Cal extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan
|
$r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan
|
||||||
from event left join item on event_hash = resource_id
|
from event left join item on event_hash = resource_id
|
||||||
where resource_type = 'event' and event.uid = %d $ignored
|
where resource_type = 'event' and event.uid = %d and event.uid = item.uid $ignored
|
||||||
AND (( adjust = 0 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )
|
AND (( adjust = 0 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )
|
||||||
OR ( adjust = 1 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )) $sql_extra ",
|
OR ( adjust = 1 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )) $sql_extra ",
|
||||||
intval($channel['channel_id']),
|
intval($channel['channel_id']),
|
||||||
@@ -288,8 +295,8 @@ class Cal extends \Zotlabs\Web\Controller {
|
|||||||
$title = strip_tags(html_entity_decode($title,ENT_QUOTES,'UTF-8'));
|
$title = strip_tags(html_entity_decode($title,ENT_QUOTES,'UTF-8'));
|
||||||
}
|
}
|
||||||
$html = format_event_html($rr);
|
$html = format_event_html($rr);
|
||||||
$rr['desc'] = bbcode($rr['desc']);
|
$rr['desc'] = zidify_links(smilies(bbcode($rr['desc'])));
|
||||||
$rr['location'] = bbcode($rr['location']);
|
$rr['location'] = zidify_links(smilies(bbcode($rr['location'])));
|
||||||
$events[] = array(
|
$events[] = array(
|
||||||
'id'=>$rr['id'],
|
'id'=>$rr['id'],
|
||||||
'hash' => $rr['event_hash'],
|
'hash' => $rr['event_hash'],
|
||||||
|
|||||||
138
Zotlabs/Module/Card_edit.php
Normal file
138
Zotlabs/Module/Card_edit.php
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
<?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'),
|
||||||
|
'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);
|
||||||
|
|
||||||
|
$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'],
|
||||||
|
'$editor' => $editor
|
||||||
|
));
|
||||||
|
|
||||||
|
return $o;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
187
Zotlabs/Module/Cards.php
Normal file
187
Zotlabs/Module/Cards.php
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
<?php
|
||||||
|
namespace Zotlabs\Module;
|
||||||
|
|
||||||
|
require_once('include/channel.php');
|
||||||
|
require_once('include/conversation.php');
|
||||||
|
require_once('include/acl_selectors.php');
|
||||||
|
|
||||||
|
|
||||||
|
class Cards extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
|
||||||
|
if(argc() > 1)
|
||||||
|
$which = argv(1);
|
||||||
|
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(! feature_enabled(\App::$profile_uid,'cards')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav_set_selected(t('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 = 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_CARD,
|
||||||
|
'is_owner' => true,
|
||||||
|
'content_label' => t('Add Card'),
|
||||||
|
'button' => t('Create'),
|
||||||
|
'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,
|
||||||
|
\Zotlabs\Lib\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);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$editor = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$sql_extra = item_permissions_sql($owner);
|
||||||
|
|
||||||
|
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_extra .= "and item.id = " . intval($r[0]['iid']) . " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$r = q("select * from item
|
||||||
|
where item.uid = %d and item_type = %d
|
||||||
|
$sql_extra order by item.created desc",
|
||||||
|
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 ";
|
||||||
|
|
||||||
|
if($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 = conv_sort($items,'updated');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
$items = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$mode = 'cards';
|
||||||
|
|
||||||
|
$content = conversation($items,$mode,false,'traditional');
|
||||||
|
|
||||||
|
$o = replace_macros(get_markup_template('cards.tpl'), [
|
||||||
|
'$title' => t('Cards'),
|
||||||
|
'$editor' => $editor,
|
||||||
|
'$content' => $content,
|
||||||
|
'$pager' => alt_pager($a,count($items))
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $o;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
1259
Zotlabs/Module/Cdav.php
Normal file
1259
Zotlabs/Module/Cdav.php
Normal file
File diff suppressed because it is too large
Load Diff
88
Zotlabs/Module/Changeaddr.php
Normal file
88
Zotlabs/Module/Changeaddr.php
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
namespace Zotlabs\Module;
|
||||||
|
|
||||||
|
|
||||||
|
class Changeaddr extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
|
function post() {
|
||||||
|
|
||||||
|
if(! local_channel())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if($_SESSION['delegate'])
|
||||||
|
return;
|
||||||
|
|
||||||
|
if((! x($_POST,'qxz_password')) || (! strlen(trim($_POST['qxz_password']))))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if((! x($_POST,'verify')) || (! strlen(trim($_POST['verify']))))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if($_POST['verify'] !== $_SESSION['remove_account_verify'])
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
$account = \App::get_account();
|
||||||
|
$channel = \App::get_channel();
|
||||||
|
|
||||||
|
$x = account_verify_password($account['account_email'],$_POST['qxz_password']);
|
||||||
|
if(! ($x && $x['account']))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if($account['account_password_changed'] > NULL_DATE) {
|
||||||
|
$d1 = datetime_convert('UTC','UTC','now - 48 hours');
|
||||||
|
if($account['account_password_changed'] > d1) {
|
||||||
|
notice( t('Channel name changes are not allowed within 48 hours of changing the account password.') . EOL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$new_address = trim($_POST['newname']);
|
||||||
|
|
||||||
|
if($new_address === $channel['channel_address'])
|
||||||
|
return;
|
||||||
|
|
||||||
|
if($new_address === 'sys') {
|
||||||
|
notice( t('Reserved nickname. Please choose another.') . EOL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(check_webbie(array($new_address)) !== $new_address) {
|
||||||
|
notice( t('Nickname has unsupported characters or is already being used on this site.') . EOL);
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
channel_change_address($channel,$new_address);
|
||||||
|
|
||||||
|
goaway(z_root() . '/changeaddr');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function get() {
|
||||||
|
|
||||||
|
if(! local_channel())
|
||||||
|
goaway(z_root());
|
||||||
|
|
||||||
|
$channel = \App::get_channel();
|
||||||
|
|
||||||
|
$hash = random_string();
|
||||||
|
|
||||||
|
$_SESSION['remove_account_verify'] = $hash;
|
||||||
|
|
||||||
|
$tpl = get_markup_template('channel_rename.tpl');
|
||||||
|
$o .= replace_macros($tpl, array(
|
||||||
|
'$basedir' => z_root(),
|
||||||
|
'$hash' => $hash,
|
||||||
|
'$title' => t('Change channel nickname/address'),
|
||||||
|
'$desc' => array(t('WARNING: '), t('Any/all connections on other networks will be lost!')),
|
||||||
|
'$passwd' => t('Please enter your password for verification:'),
|
||||||
|
'$newname' => array('newname', t('New channel address'),$channel['channel_address'], ''),
|
||||||
|
'$submit' => t('Rename Channel')
|
||||||
|
));
|
||||||
|
|
||||||
|
return $o;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Zotlabs\Module;
|
|
||||||
|
|
||||||
|
namespace Zotlabs\Module;
|
||||||
|
|
||||||
require_once('include/contact_widgets.php');
|
require_once('include/contact_widgets.php');
|
||||||
require_once('include/items.php');
|
require_once('include/items.php');
|
||||||
@@ -10,6 +10,10 @@ require_once('include/conversation.php');
|
|||||||
require_once('include/acl_selectors.php');
|
require_once('include/acl_selectors.php');
|
||||||
require_once('include/permissions.php');
|
require_once('include/permissions.php');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Channel Controller
|
||||||
|
*
|
||||||
|
*/
|
||||||
class Channel extends \Zotlabs\Web\Controller {
|
class Channel extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
@@ -37,23 +41,29 @@ class Channel extends \Zotlabs\Web\Controller {
|
|||||||
$profile = argv(1);
|
$profile = argv(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" title="' . t('Posts and comments') . '" href="' . z_root() . '/feed/' . $which . '" />' . "\r\n" ;
|
head_add_link( [
|
||||||
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" title="' . t('Only posts') . '" href="' . z_root() . '/feed/' . $which . '?top=1" />' . "\r\n" ;
|
'rel' => 'alternate',
|
||||||
|
'type' => 'application/atom+xml',
|
||||||
|
'title' => t('Posts and comments'),
|
||||||
|
'href' => z_root() . '/feed/' . $which
|
||||||
|
]);
|
||||||
|
|
||||||
|
head_add_link( [
|
||||||
|
'rel' => 'alternate',
|
||||||
|
'type' => 'application/atom+xml',
|
||||||
|
'title' => t('Only posts'),
|
||||||
|
'href' => z_root() . '/feed/' . $which . '?f=&top=1'
|
||||||
|
]);
|
||||||
|
|
||||||
// Not yet ready for prime time
|
|
||||||
// \App::$page['htmlhead'] .= '<link rel="openid.server" href="' . z_root() . '/id/' . $which .'?f=" />' . "\r\n" ;
|
|
||||||
// \App::$page['htmlhead'] .= '<link rel="openid.delegate" href="' . z_root() . '/channel/' . $which .'" />' . "\r\n" ;
|
|
||||||
|
|
||||||
// Run profile_load() here to make sure the theme is set before
|
// Run profile_load() here to make sure the theme is set before
|
||||||
// we start loading content
|
// we start loading content
|
||||||
|
|
||||||
profile_load($which,$profile);
|
profile_load($which,$profile);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function get($update = 0, $load = false) {
|
function get($update = 0, $load = false) {
|
||||||
|
|
||||||
|
|
||||||
if($load)
|
if($load)
|
||||||
$_SESSION['loadtime'] = datetime_convert();
|
$_SESSION['loadtime'] = datetime_convert();
|
||||||
|
|
||||||
@@ -72,6 +82,7 @@ class Channel extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$category = ((x($_REQUEST,'cat')) ? $_REQUEST['cat'] : '');
|
$category = ((x($_REQUEST,'cat')) ? $_REQUEST['cat'] : '');
|
||||||
$hashtags = ((x($_REQUEST,'tag')) ? $_REQUEST['tag'] : '');
|
$hashtags = ((x($_REQUEST,'tag')) ? $_REQUEST['tag'] : '');
|
||||||
|
$static = ((array_key_exists('static',$_REQUEST)) ? intval($_REQUEST['static']) : 0);
|
||||||
|
|
||||||
$groups = array();
|
$groups = array();
|
||||||
|
|
||||||
@@ -81,11 +92,6 @@ class Channel extends \Zotlabs\Web\Controller {
|
|||||||
// Ensure we've got a profile owner if updating.
|
// Ensure we've got a profile owner if updating.
|
||||||
\App::$profile['profile_uid'] = \App::$profile_uid = $update;
|
\App::$profile['profile_uid'] = \App::$profile_uid = $update;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if(\App::$profile['profile_uid'] == local_channel()) {
|
|
||||||
nav_set_selected('home');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$is_owner = (((local_channel()) && (\App::$profile['profile_uid'] == local_channel())) ? true : false);
|
$is_owner = (((local_channel()) && (\App::$profile['profile_uid'] == local_channel())) ? true : false);
|
||||||
|
|
||||||
@@ -108,9 +114,13 @@ class Channel extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
if(! $update) {
|
if(! $update) {
|
||||||
|
|
||||||
$o .= profile_tabs($a, $is_owner, \App::$profile['channel_address']);
|
nav_set_selected('Channel Home');
|
||||||
|
|
||||||
$o .= common_friends_visitor_widget(\App::$profile['profile_uid']);
|
$static = channel_manual_conv_update(\App::$profile['profile_uid']);
|
||||||
|
|
||||||
|
//$o .= profile_tabs($a, $is_owner, \App::$profile['channel_address']);
|
||||||
|
|
||||||
|
// $o .= common_friends_visitor_widget(\App::$profile['profile_uid']);
|
||||||
|
|
||||||
if($channel && $is_owner) {
|
if($channel && $is_owner) {
|
||||||
$channel_acl = array(
|
$channel_acl = array(
|
||||||
@@ -143,9 +153,9 @@ class Channel extends \Zotlabs\Web\Controller {
|
|||||||
'bbco_autocomplete' => 'bbcode',
|
'bbco_autocomplete' => 'bbcode',
|
||||||
'bbcode' => true,
|
'bbcode' => true,
|
||||||
'jotnets' => true
|
'jotnets' => true
|
||||||
);
|
);
|
||||||
|
|
||||||
$o .= status_editor($a,$x);
|
$o .= status_editor($a,$x);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -156,6 +166,7 @@ class Channel extends \Zotlabs\Web\Controller {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
$item_normal = item_normal();
|
$item_normal = item_normal();
|
||||||
|
$item_normal_update = item_normal_update();
|
||||||
$sql_extra = item_permissions_sql(\App::$profile['profile_uid']);
|
$sql_extra = item_permissions_sql(\App::$profile['profile_uid']);
|
||||||
|
|
||||||
if(get_pconfig(\App::$profile['profile_uid'],'system','channel_list_mode') && (! $mid))
|
if(get_pconfig(\App::$profile['profile_uid'],'system','channel_list_mode') && (! $mid))
|
||||||
@@ -167,17 +178,25 @@ class Channel extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$simple_update = (($update) ? " AND item_unseen = 1 " : '');
|
$simple_update = (($update) ? " AND item_unseen = 1 " : '');
|
||||||
|
|
||||||
\App::$page['htmlhead'] .= "\r\n" . '<link rel="alternate" type="application/json+oembed" href="' . z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string) . '" title="oembed" />' . "\r\n";
|
head_add_link([
|
||||||
|
'rel' => 'alternate',
|
||||||
|
'type' => 'application/json+oembed',
|
||||||
|
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string),
|
||||||
|
'title' => 'oembed'
|
||||||
|
]);
|
||||||
|
|
||||||
if($update && $_SESSION['loadtime'])
|
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']) . "' ) ";
|
$simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) ";
|
||||||
if($load)
|
if($load)
|
||||||
$simple_update = '';
|
$simple_update = '';
|
||||||
|
|
||||||
|
if($static && $simple_update)
|
||||||
|
$simple_update .= " and author_xchan = '" . protect_sprintf(get_observer_hash()) . "' ";
|
||||||
|
|
||||||
if(($update) && (! $load)) {
|
if(($update) && (! $load)) {
|
||||||
|
|
||||||
if($mid) {
|
if($mid) {
|
||||||
$r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal
|
$r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal_update
|
||||||
AND item_wall = 1 $simple_update $sql_extra limit 1",
|
AND item_wall = 1 $simple_update $sql_extra limit 1",
|
||||||
dbesc($mid . '%'),
|
dbesc($mid . '%'),
|
||||||
intval(\App::$profile['profile_uid'])
|
intval(\App::$profile['profile_uid'])
|
||||||
@@ -185,9 +204,9 @@ class Channel extends \Zotlabs\Web\Controller {
|
|||||||
$_SESSION['loadtime'] = datetime_convert();
|
$_SESSION['loadtime'] = datetime_convert();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$r = q("SELECT distinct parent AS `item_id`, created from item
|
$r = q("SELECT distinct parent AS item_id, created from item
|
||||||
left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
|
left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
|
||||||
WHERE uid = %d $item_normal
|
WHERE uid = %d $item_normal_update
|
||||||
AND item_wall = 1 $simple_update
|
AND item_wall = 1 $simple_update
|
||||||
AND (abook.abook_blocked = 0 or abook.abook_flags is null)
|
AND (abook.abook_blocked = 0 or abook.abook_flags is null)
|
||||||
$sql_extra
|
$sql_extra
|
||||||
@@ -201,10 +220,10 @@ class Channel extends \Zotlabs\Web\Controller {
|
|||||||
else {
|
else {
|
||||||
|
|
||||||
if(x($category)) {
|
if(x($category)) {
|
||||||
$sql_extra .= protect_sprintf(term_query('item', $category, TERM_CATEGORY));
|
$sql_extra2 .= protect_sprintf(term_item_parent_query(\App::$profile['profile_uid'],'item', $category, TERM_CATEGORY));
|
||||||
}
|
}
|
||||||
if(x($hashtags)) {
|
if(x($hashtags)) {
|
||||||
$sql_extra .= protect_sprintf(term_query('item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG));
|
$sql_extra2 .= protect_sprintf(term_item_parent_query(\App::$profile['profile_uid'],'item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG));
|
||||||
}
|
}
|
||||||
|
|
||||||
if($datequery) {
|
if($datequery) {
|
||||||
@@ -220,15 +239,14 @@ class Channel extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
if($load || ($checkjs->disabled())) {
|
if($load || ($checkjs->disabled())) {
|
||||||
if($mid) {
|
if($mid) {
|
||||||
$r = q("SELECT parent AS item_id from item where mid = '%s' and uid = %d $item_normal
|
$r = q("SELECT distinct parent AS item_id from item where mid like '%s' and uid = %d $item_normal
|
||||||
AND item_wall = 1 $sql_extra limit 1",
|
AND item_wall = 1 $sql_extra limit 1",
|
||||||
dbesc($mid),
|
dbesc($mid . '%'),
|
||||||
intval(\App::$profile['profile_uid'])
|
intval(\App::$profile['profile_uid'])
|
||||||
);
|
);
|
||||||
if (! $r) {
|
if (! $r) {
|
||||||
notice( t('Permission denied.') . EOL);
|
notice( t('Permission denied.') . EOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$r = q("SELECT distinct id AS item_id, created FROM item
|
$r = q("SELECT distinct id AS item_id, created FROM item
|
||||||
@@ -251,10 +269,10 @@ class Channel extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$parents_str = ids_to_querystr($r,'item_id');
|
$parents_str = ids_to_querystr($r,'item_id');
|
||||||
|
|
||||||
$items = q("SELECT `item`.*, `item`.`id` AS `item_id`
|
$items = q("SELECT item.*, item.id AS item_id
|
||||||
FROM `item`
|
FROM item
|
||||||
WHERE `item`.`uid` = %d $item_normal
|
WHERE item.uid = %d $item_normal
|
||||||
AND `item`.`parent` IN ( %s )
|
AND item.parent IN ( %s )
|
||||||
$sql_extra ",
|
$sql_extra ",
|
||||||
intval(\App::$profile['profile_uid']),
|
intval(\App::$profile['profile_uid']),
|
||||||
dbesc($parents_str)
|
dbesc($parents_str)
|
||||||
@@ -270,8 +288,7 @@ class Channel extends \Zotlabs\Web\Controller {
|
|||||||
notice( t('Permission denied.') . EOL);
|
notice( t('Permission denied.') . EOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
$items = array();
|
$items = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,20 +321,22 @@ class Channel extends \Zotlabs\Web\Controller {
|
|||||||
'$nouveau' => '0',
|
'$nouveau' => '0',
|
||||||
'$wall' => '1',
|
'$wall' => '1',
|
||||||
'$fh' => '0',
|
'$fh' => '0',
|
||||||
|
'$static' => $static,
|
||||||
'$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1),
|
'$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1),
|
||||||
'$search' => '',
|
'$search' => '',
|
||||||
|
'$xchan' => '',
|
||||||
'$order' => '',
|
'$order' => '',
|
||||||
'$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0),
|
'$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0),
|
||||||
'$file' => '',
|
'$file' => '',
|
||||||
'$cats' => (($category) ? $category : ''),
|
'$cats' => (($category) ? urlencode($category) : ''),
|
||||||
'$tags' => (($hashtags) ? $hashtags : ''),
|
'$tags' => (($hashtags) ? urlencode($hashtags) : ''),
|
||||||
'$mid' => $mid,
|
'$mid' => $mid,
|
||||||
'$verb' => '',
|
'$verb' => '',
|
||||||
|
'$net' => '',
|
||||||
'$dend' => $datequery,
|
'$dend' => $datequery,
|
||||||
'$dbegin' => $datequery2
|
'$dbegin' => $datequery2
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$update_unseen = '';
|
$update_unseen = '';
|
||||||
@@ -343,17 +362,21 @@ class Channel extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($is_owner && $update_unseen) {
|
if($is_owner && $update_unseen) {
|
||||||
$r = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 and item_wall = 1 AND uid = %d $update_unseen",
|
$x = [ 'channel_id' => local_channel(), 'update' => 'unset' ];
|
||||||
intval(local_channel())
|
call_hooks('update_unseen',$x);
|
||||||
);
|
if($x['update'] === 'unset' || intval($x['update'])) {
|
||||||
|
$r = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 and item_wall = 1 AND uid = %d $update_unseen",
|
||||||
|
intval(local_channel())
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if($checkjs->disabled()) {
|
if($checkjs->disabled()) {
|
||||||
$o .= conversation($a,$items,'channel',$update,'traditional');
|
$o .= conversation($items,'channel',$update,'traditional');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$o .= conversation($a,$items,'channel',$update,$page_mode);
|
$o .= conversation($items,'channel',$update,$page_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((! $update) || ($checkjs->disabled())) {
|
if((! $update) || ($checkjs->disabled())) {
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ class Chanview extends \Zotlabs\Web\Controller {
|
|||||||
logger('mod_chanview: constructed address ' . print_r($matches,true));
|
logger('mod_chanview: constructed address ' . print_r($matches,true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$r = null;
|
||||||
|
|
||||||
if($_REQUEST['address']) {
|
if($_REQUEST['address']) {
|
||||||
$j = \Zotlabs\Zot\Finger::run($_REQUEST['address'],null);
|
$j = \Zotlabs\Zot\Finger::run($_REQUEST['address'],null);
|
||||||
if($j['success']) {
|
if($j['success']) {
|
||||||
@@ -66,40 +68,79 @@ class Chanview extends \Zotlabs\Web\Controller {
|
|||||||
$r = q("select * from xchan where xchan_addr = '%s' limit 1",
|
$r = q("select * from xchan where xchan_addr = '%s' limit 1",
|
||||||
dbesc($_REQUEST['address'])
|
dbesc($_REQUEST['address'])
|
||||||
);
|
);
|
||||||
if($r)
|
if($r) {
|
||||||
\App::$poi = $r[0];
|
\App::$poi = $r[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(! $r) {
|
||||||
|
if(discover_by_webbie($_REQUEST['address'])) {
|
||||||
|
$r = q("select * from xchan where xchan_addr = '%s' limit 1",
|
||||||
|
dbesc($_REQUEST['address'])
|
||||||
|
);
|
||||||
|
if($r) {
|
||||||
|
\App::$poi = $r[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(! \App::$poi) {
|
if(! \App::$poi) {
|
||||||
// We don't know who this is, and we can't figure it out from the URL
|
|
||||||
// On the plus side, there's a good chance we know somebody else at that
|
// We don't know who this is, and we can't figure it out from the URL
|
||||||
// hub so sending them there with a Zid will probably work anyway.
|
// On the plus side, there's a good chance we know somebody else at that
|
||||||
|
// hub so sending them there with a Zid will probably work anyway.
|
||||||
|
|
||||||
$url = ($_REQUEST['url']);
|
$url = ($_REQUEST['url']);
|
||||||
|
if(! $url) {
|
||||||
|
notice( t('Channel not found.') . EOL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if($observer)
|
if($observer)
|
||||||
$url = zid($url);
|
$url = zid($url);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$is_zot = false;
|
||||||
|
$connected = false;
|
||||||
|
|
||||||
if (\App::$poi) {
|
if (\App::$poi) {
|
||||||
$url = \App::$poi['xchan_url'];
|
$url = \App::$poi['xchan_url'];
|
||||||
if($observer)
|
if(\App::$poi['xchan_network'] === 'zot') {
|
||||||
$url = zid($url);
|
$is_zot = true;
|
||||||
|
}
|
||||||
|
if(local_channel()) {
|
||||||
|
$c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s' limit 1",
|
||||||
|
intval(local_channel()),
|
||||||
|
dbesc(\App::$poi['xchan_hash'])
|
||||||
|
);
|
||||||
|
if($c)
|
||||||
|
$connected = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// let somebody over-ride the iframed viewport presentation
|
|
||||||
// or let's just declare this a failed experiment.
|
|
||||||
|
|
||||||
// if((! local_channel()) || (get_pconfig(local_channel(),'system','chanview_full')))
|
// We will load the chanview template if it's a foreign network,
|
||||||
|
// just so that we can provide a connect button along with a profile
|
||||||
|
// photo. Chances are we can't load the remote profile into an iframe
|
||||||
|
// because of cross-domain security headers. So provide a link to
|
||||||
|
// the remote profile.
|
||||||
|
// If we are already connected, just go to the profile.
|
||||||
|
// Zot channels will usually have a connect link.
|
||||||
|
|
||||||
goaway($url);
|
if($is_zot || $connected) {
|
||||||
|
if($is_zot && $observer) {
|
||||||
// $o = replace_macros(get_markup_template('chanview.tpl'),array(
|
$url = zid($url);
|
||||||
// '$url' => $url,
|
}
|
||||||
// '$full' => t('toggle full screen mode')
|
goaway($url);
|
||||||
// ));
|
}
|
||||||
|
else {
|
||||||
// return $o;
|
$o = replace_macros(get_markup_template('chanview.tpl'),array(
|
||||||
|
'$url' => $url,
|
||||||
|
'$full' => t('toggle full screen mode')
|
||||||
|
));
|
||||||
|
|
||||||
|
return $o;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,8 +34,6 @@ class Chat extends \Zotlabs\Web\Controller {
|
|||||||
$profile = argv(1);
|
$profile = argv(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which .'" />' . "\r\n" ;
|
|
||||||
|
|
||||||
// Run profile_load() here to make sure the theme is set before
|
// Run profile_load() here to make sure the theme is set before
|
||||||
// we start loading content
|
// we start loading content
|
||||||
|
|
||||||
@@ -91,8 +89,10 @@ class Chat extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
|
||||||
if(local_channel())
|
if(local_channel()) {
|
||||||
$channel = \App::get_channel();
|
$channel = \App::get_channel();
|
||||||
|
nav_set_selected('My Chatrooms');
|
||||||
|
}
|
||||||
|
|
||||||
$ob = \App::get_observer();
|
$ob = \App::get_observer();
|
||||||
$observer = get_observer_hash();
|
$observer = get_observer_hash();
|
||||||
@@ -212,7 +212,8 @@ class Chat extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
require_once('include/conversation.php');
|
require_once('include/conversation.php');
|
||||||
|
|
||||||
$o = profile_tabs($a,((local_channel() && local_channel() == \App::$profile['profile_uid']) ? true : false),\App::$profile['channel_address']);
|
//$o = profile_tabs($a,((local_channel() && local_channel() == \App::$profile['profile_uid']) ? true : false),\App::$profile['channel_address']);
|
||||||
|
$o = '';
|
||||||
|
|
||||||
if(! feature_enabled(\App::$profile['profile_uid'],'ajaxchat')) {
|
if(! feature_enabled(\App::$profile['profile_uid'],'ajaxchat')) {
|
||||||
notice( t('Feature disabled.') . EOL);
|
notice( t('Feature disabled.') . EOL);
|
||||||
|
|||||||
@@ -111,8 +111,22 @@ class Chatsvc extends \Zotlabs\Web\Controller {
|
|||||||
intval(\App::$data['chat']['room_id'])
|
intval(\App::$data['chat']['room_id'])
|
||||||
);
|
);
|
||||||
if($r) {
|
if($r) {
|
||||||
foreach($r as $rr) {
|
foreach($r as $rv) {
|
||||||
switch($rr['cp_status']) {
|
if(! $rv['xchan_name']) {
|
||||||
|
$rv['xchan_hash'] = $rv['cp_xchan'];
|
||||||
|
$rv['xchan_name'] = substr($rv['cp_xchan'],strrpos($rv['cp_xchan'],'.')+1);
|
||||||
|
$rv['xchan_addr'] = '';
|
||||||
|
$rv['xchan_network'] = 'unknown';
|
||||||
|
$rv['xchan_url'] = z_root();
|
||||||
|
$rv['xchan_hidden'] = 1;
|
||||||
|
$rv['xchan_photo_mimetype'] = 'image/jpeg';
|
||||||
|
$rv['xchan_photo_l'] = get_default_profile_photo(300);
|
||||||
|
$rv['xchan_photo_m'] = get_default_profile_photo(80);
|
||||||
|
$rv['xchan_photo_s'] = get_default_profile_photo(48);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($rv['cp_status']) {
|
||||||
case 'away':
|
case 'away':
|
||||||
$status = t('Away');
|
$status = t('Away');
|
||||||
$status_class = 'away';
|
$status_class = 'away';
|
||||||
@@ -124,7 +138,7 @@ class Chatsvc extends \Zotlabs\Web\Controller {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$inroom[] = array('img' => zid($rr['xchan_photo_m']), 'img_type' => $rr['xchan_photo_mimetype'],'name' => $rr['xchan_name'], 'status' => $status, 'status_class' => $status_class);
|
$inroom[] = array('img' => zid($rv['xchan_photo_m']), 'img_type' => $rv['xchan_photo_mimetype'],'name' => $rv['xchan_name'], 'status' => $status, 'status_class' => $status_class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +157,7 @@ class Chatsvc extends \Zotlabs\Web\Controller {
|
|||||||
'name' => $rr['xchan_name'],
|
'name' => $rr['xchan_name'],
|
||||||
'isotime' => datetime_convert('UTC', date_default_timezone_get(), $rr['created'], 'c'),
|
'isotime' => datetime_convert('UTC', date_default_timezone_get(), $rr['created'], 'c'),
|
||||||
'localtime' => datetime_convert('UTC', date_default_timezone_get(), $rr['created'], 'r'),
|
'localtime' => datetime_convert('UTC', date_default_timezone_get(), $rr['created'], 'r'),
|
||||||
'text' => smilies(bbcode($rr['chat_text'])),
|
'text' => zidify_links(smilies(bbcode($rr['chat_text']))),
|
||||||
'self' => ((get_observer_hash() == $rr['chat_xchan']) ? 'self' : '')
|
'self' => ((get_observer_hash() == $rr['chat_xchan']) ? 'self' : '')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Zotlabs\Module;
|
namespace Zotlabs\Module;
|
||||||
/**
|
/**
|
||||||
* @file mod/cloud.php
|
* @file Zotlabs/Module/Cloud.php
|
||||||
* @brief Initialize Hubzilla's cloud (SabreDAV).
|
* @brief Initialize Hubzilla's cloud (SabreDAV).
|
||||||
*
|
*
|
||||||
* Module for accessing the DAV storage area.
|
* Module for accessing the DAV storage area.
|
||||||
@@ -17,14 +17,15 @@ require_once('include/attach.php');
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Fires up the SabreDAV server.
|
* @brief Cloud Module.
|
||||||
*
|
*
|
||||||
* @param App &$a
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
class Cloud extends \Zotlabs\Web\Controller {
|
class Cloud extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fires up the SabreDAV server.
|
||||||
|
*
|
||||||
|
*/
|
||||||
function init() {
|
function init() {
|
||||||
|
|
||||||
if (! is_dir('store'))
|
if (! is_dir('store'))
|
||||||
@@ -36,8 +37,6 @@ class Cloud extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$profile = 0;
|
$profile = 0;
|
||||||
|
|
||||||
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which . '" />' . "\r\n";
|
|
||||||
|
|
||||||
if ($which)
|
if ($which)
|
||||||
profile_load( $which, $profile);
|
profile_load( $which, $profile);
|
||||||
|
|
||||||
@@ -58,16 +57,12 @@ class Cloud extends \Zotlabs\Web\Controller {
|
|||||||
$auth->observer = $ob_hash;
|
$auth->observer = $ob_hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($_GET['davguest'])
|
// if we arrived at this path with any query parameters in the url, build a clean url without
|
||||||
$_SESSION['davguest'] = true;
|
// them and redirect.
|
||||||
|
|
||||||
$_SERVER['QUERY_STRING'] = str_replace(array('?f=', '&f='), array('', ''), $_SERVER['QUERY_STRING']);
|
$x = clean_query_string();
|
||||||
$_SERVER['QUERY_STRING'] = strip_zids($_SERVER['QUERY_STRING']);
|
if($x !== \App::$query_string)
|
||||||
$_SERVER['QUERY_STRING'] = preg_replace('/[\?&]davguest=(.*?)([\?&]|$)/ism', '', $_SERVER['QUERY_STRING']);
|
goaway(z_root() . '/' . $x);
|
||||||
|
|
||||||
$_SERVER['REQUEST_URI'] = str_replace(array('?f=', '&f='), array('', ''), $_SERVER['REQUEST_URI']);
|
|
||||||
$_SERVER['REQUEST_URI'] = strip_zids($_SERVER['REQUEST_URI']);
|
|
||||||
$_SERVER['REQUEST_URI'] = preg_replace('/[\?&]davguest=(.*?)([\?&]|$)/ism', '', $_SERVER['REQUEST_URI']);
|
|
||||||
|
|
||||||
$rootDirectory = new \Zotlabs\Storage\Directory('/', $auth);
|
$rootDirectory = new \Zotlabs\Storage\Directory('/', $auth);
|
||||||
|
|
||||||
@@ -88,16 +83,42 @@ class Cloud extends \Zotlabs\Web\Controller {
|
|||||||
$server->addPlugin($browser);
|
$server->addPlugin($browser);
|
||||||
|
|
||||||
// Experimental QuotaPlugin
|
// Experimental QuotaPlugin
|
||||||
// require_once('\Zotlabs\Storage/QuotaPlugin.php');
|
// require_once('\Zotlabs\Storage/QuotaPlugin.php');
|
||||||
// $server->addPlugin(new \Zotlabs\Storage\\QuotaPlugin($auth));
|
// $server->addPlugin(new \Zotlabs\Storage\\QuotaPlugin($auth));
|
||||||
|
|
||||||
|
|
||||||
|
// over-ride the default XML output on thrown exceptions
|
||||||
|
|
||||||
|
$server->on('exception', [ $this, 'DAVException' ]);
|
||||||
|
|
||||||
ob_start();
|
|
||||||
// All we need to do now, is to fire up the server
|
// All we need to do now, is to fire up the server
|
||||||
|
|
||||||
$server->exec();
|
$server->exec();
|
||||||
|
|
||||||
ob_end_flush();
|
if($browser->build_page)
|
||||||
|
construct_page();
|
||||||
|
|
||||||
|
killme();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function DAVException($err) {
|
||||||
|
|
||||||
|
if($err instanceof \Sabre\DAV\Exception\NotFound) {
|
||||||
|
notice( t('Not found') . EOL);
|
||||||
|
}
|
||||||
|
elseif($err instanceof \Sabre\DAV\Exception\Forbidden) {
|
||||||
|
notice( t('Permission denied') . EOL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
notice( t('Unknown error') . EOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
construct_page();
|
||||||
|
|
||||||
killme();
|
killme();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
21
Zotlabs/Module/Cloud_tiles.php
Normal file
21
Zotlabs/Module/Cloud_tiles.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zotlabs\Module;
|
||||||
|
|
||||||
|
class Cloud_tiles extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
|
||||||
|
if(intval($_SESSION['cloud_tiles']))
|
||||||
|
$_SESSION['cloud_tiles'] = 0;
|
||||||
|
else
|
||||||
|
$_SESSION['cloud_tiles'] = 1;
|
||||||
|
|
||||||
|
if(local_channel()) {
|
||||||
|
set_pconfig(local_channel(),'system','cloud_tiles',$_SESSION['cloud_tiles']);
|
||||||
|
}
|
||||||
|
|
||||||
|
goaway(z_root() . '/' . hex2bin(argv(1)));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,7 +25,7 @@ class Common extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
|
||||||
$o = '';
|
$o = '';
|
||||||
|
|
||||||
@@ -34,39 +34,38 @@ class Common extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$observer_hash = get_observer_hash();
|
$observer_hash = get_observer_hash();
|
||||||
|
|
||||||
|
|
||||||
if(! perm_is_allowed(\App::$profile['profile_uid'],$observer_hash,'view_contacts')) {
|
if(! perm_is_allowed(\App::$profile['profile_uid'],$observer_hash,'view_contacts')) {
|
||||||
notice( t('Permission denied.') . EOL);
|
notice( t('Permission denied.') . EOL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$o .= '<h2>' . t('Common connections') . '</h2>';
|
|
||||||
|
|
||||||
$t = count_common_friends(\App::$profile['profile_uid'],$observer_hash);
|
$t = count_common_friends(\App::$profile['profile_uid'],$observer_hash);
|
||||||
|
|
||||||
if(! $t) {
|
if(! $t) {
|
||||||
notice( t('No connections in common.') . EOL);
|
notice( t('No connections in common.') . EOL);
|
||||||
return $o;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$r = common_friends(\App::$profile['profile_uid'],$observer_hash);
|
$r = common_friends(\App::$profile['profile_uid'],$observer_hash);
|
||||||
|
|
||||||
if($r) {
|
if($r) {
|
||||||
|
|
||||||
$tpl = get_markup_template('common_friends.tpl');
|
|
||||||
|
|
||||||
foreach($r as $rr) {
|
foreach($r as $rr) {
|
||||||
$o .= replace_macros($tpl,array(
|
$items[] = [
|
||||||
'$url' => $rr['xchan_url'],
|
'url' => $rr['xchan_url'],
|
||||||
'$name' => $rr['xchan_name'],
|
'name' => $rr['xchan_name'],
|
||||||
'$photo' => $rr['xchan_photo_m'],
|
'photo' => $rr['xchan_photo_m'],
|
||||||
'$tags' => ''
|
'tags' => ''
|
||||||
));
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$o .= cleardiv();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$tpl = get_markup_template('common_friends.tpl');
|
||||||
|
|
||||||
|
$o = replace_macros($tpl, [
|
||||||
|
'$title' => t('View Common Connections'),
|
||||||
|
'$items' => $items
|
||||||
|
]);
|
||||||
|
|
||||||
return $o;
|
return $o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class Connect extends \Zotlabs\Web\Controller {
|
|||||||
profile_load($which,'');
|
profile_load($which,'');
|
||||||
}
|
}
|
||||||
|
|
||||||
function post() {
|
function post() {
|
||||||
|
|
||||||
if(! array_key_exists('channel', \App::$data))
|
if(! array_key_exists('channel', \App::$data))
|
||||||
return;
|
return;
|
||||||
@@ -78,7 +78,7 @@ class Connect extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
|
||||||
$edit = ((local_channel() && (local_channel() == \App::$data['channel']['channel_id'])) ? true : false);
|
$edit = ((local_channel() && (local_channel() == \App::$data['channel']['channel_id'])) ? true : false);
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,6 @@ namespace Zotlabs\Module;
|
|||||||
require_once('include/socgraph.php');
|
require_once('include/socgraph.php');
|
||||||
require_once('include/selectors.php');
|
require_once('include/selectors.php');
|
||||||
require_once('include/group.php');
|
require_once('include/group.php');
|
||||||
require_once('include/contact_widgets.php');
|
|
||||||
require_once('include/zot.php');
|
|
||||||
require_once('include/widgets.php');
|
|
||||||
|
|
||||||
|
|
||||||
class Connections extends \Zotlabs\Web\Controller {
|
class Connections extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
@@ -23,7 +19,7 @@ class Connections extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
|
||||||
$sort_type = 0;
|
$sort_type = 0;
|
||||||
$o = '';
|
$o = '';
|
||||||
@@ -34,6 +30,8 @@ class Connections extends \Zotlabs\Web\Controller {
|
|||||||
return login();
|
return login();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nav_set_selected('Connections');
|
||||||
|
|
||||||
$blocked = false;
|
$blocked = false;
|
||||||
$hidden = false;
|
$hidden = false;
|
||||||
$ignored = false;
|
$ignored = false;
|
||||||
@@ -67,15 +65,14 @@ class Connections extends \Zotlabs\Web\Controller {
|
|||||||
$hidden = true;
|
$hidden = true;
|
||||||
break;
|
break;
|
||||||
case 'archived':
|
case 'archived':
|
||||||
$search_flags = " and abook_archived = 1 ";
|
$search_flags = " and ( abook_archived = 1 OR abook_not_here = 1) ";
|
||||||
$head = t('Archived');
|
$head = t('Archived/Unreachable');
|
||||||
$archived = true;
|
$archived = true;
|
||||||
break;
|
break;
|
||||||
case 'pending':
|
case 'pending':
|
||||||
$search_flags = " and abook_pending = 1 ";
|
$search_flags = " and abook_pending = 1 ";
|
||||||
$head = t('New');
|
$head = t('New');
|
||||||
$pending = true;
|
$pending = true;
|
||||||
nav_set_selected('intros');
|
|
||||||
break;
|
break;
|
||||||
case 'ifpending':
|
case 'ifpending':
|
||||||
$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_pending = 1 and abook_self = 0 and abook_ignored = 0 and xchan_deleted = 0 and xchan_orphan = 0 ",
|
$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_pending = 1 and abook_self = 0 and abook_ignored = 0 and xchan_deleted = 0 and xchan_orphan = 0 ",
|
||||||
@@ -85,7 +82,6 @@ class Connections extends \Zotlabs\Web\Controller {
|
|||||||
$search_flags = " and abook_pending = 1 ";
|
$search_flags = " and abook_pending = 1 ";
|
||||||
$head = t('New');
|
$head = t('New');
|
||||||
$pending = true;
|
$pending = true;
|
||||||
nav_set_selected('intros');
|
|
||||||
\App::$argv[1] = 'pending';
|
\App::$argv[1] = 'pending';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -95,7 +91,6 @@ class Connections extends \Zotlabs\Web\Controller {
|
|||||||
\App::$argc = 1;
|
\App::$argc = 1;
|
||||||
unset(\App::$argv[1]);
|
unset(\App::$argv[1]);
|
||||||
}
|
}
|
||||||
nav_set_selected('intros');
|
|
||||||
break;
|
break;
|
||||||
// case 'unconnected':
|
// case 'unconnected':
|
||||||
// $search_flags = " and abook_unconnected = 1 ";
|
// $search_flags = " and abook_unconnected = 1 ";
|
||||||
@@ -172,10 +167,10 @@ class Connections extends \Zotlabs\Web\Controller {
|
|||||||
),
|
),
|
||||||
|
|
||||||
'archived' => array(
|
'archived' => array(
|
||||||
'label' => t('Archived'),
|
'label' => t('Archived/Unreachable'),
|
||||||
'url' => z_root() . '/connections/archived',
|
'url' => z_root() . '/connections/archived',
|
||||||
'sel' => ($archived) ? 'active' : '',
|
'sel' => ($archived) ? 'active' : '',
|
||||||
'title' => t('Only show archived connections'),
|
'title' => t('Only show archived/unreachable connections'),
|
||||||
),
|
),
|
||||||
|
|
||||||
'hidden' => array(
|
'hidden' => array(
|
||||||
@@ -228,18 +223,27 @@ class Connections extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$contacts = array();
|
$contacts = array();
|
||||||
|
|
||||||
if(count($r)) {
|
if($r) {
|
||||||
|
|
||||||
|
vcard_query($r);
|
||||||
|
|
||||||
|
|
||||||
foreach($r as $rr) {
|
foreach($r as $rr) {
|
||||||
if($rr['xchan_url']) {
|
if($rr['xchan_url']) {
|
||||||
|
|
||||||
|
if(($rr['vcard']) && is_array($rr['vcard']['tels']) && $rr['vcard']['tels'][0]['nr'])
|
||||||
|
$phone = ((\App::$is_mobile || \App::$is_tablet) ? $rr['vcard']['tels'][0]['nr'] : '');
|
||||||
|
else
|
||||||
|
$phone = '';
|
||||||
|
|
||||||
$status_str = '';
|
$status_str = '';
|
||||||
$status = array(
|
$status = array(
|
||||||
((intval($rr['abook_pending'])) ? t('Pending approval') : ''),
|
((intval($rr['abook_pending'])) ? t('Pending approval') : ''),
|
||||||
((intval($rr['abook_archived'])) ? t('Archived') : ''),
|
((intval($rr['abook_archived'])) ? t('Archived') : ''),
|
||||||
((intval($rr['abook_hidden'])) ? t('Hidden') : ''),
|
((intval($rr['abook_hidden'])) ? t('Hidden') : ''),
|
||||||
((intval($rr['abook_ignored'])) ? t('Ignored') : ''),
|
((intval($rr['abook_ignored'])) ? t('Ignored') : ''),
|
||||||
((intval($rr['abook_blocked'])) ? t('Blocked') : '')
|
((intval($rr['abook_blocked'])) ? t('Blocked') : ''),
|
||||||
|
((intval($rr['abook_not_here'])) ? t('Not connected at this location') : '')
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach($status as $str) {
|
foreach($status as $str) {
|
||||||
@@ -253,20 +257,23 @@ class Connections extends \Zotlabs\Web\Controller {
|
|||||||
$contacts[] = array(
|
$contacts[] = array(
|
||||||
'img_hover' => sprintf( t('%1$s [%2$s]'),$rr['xchan_name'],$rr['xchan_url']),
|
'img_hover' => sprintf( t('%1$s [%2$s]'),$rr['xchan_name'],$rr['xchan_url']),
|
||||||
'edit_hover' => t('Edit connection'),
|
'edit_hover' => t('Edit connection'),
|
||||||
|
'edit' => t('Edit'),
|
||||||
'delete_hover' => t('Delete connection'),
|
'delete_hover' => t('Delete connection'),
|
||||||
'id' => $rr['abook_id'],
|
'id' => $rr['abook_id'],
|
||||||
'thumb' => $rr['xchan_photo_m'],
|
'thumb' => $rr['xchan_photo_m'],
|
||||||
'name' => $rr['xchan_name'],
|
'name' => $rr['xchan_name'],
|
||||||
'classes' => (intval($rr['abook_archived']) ? 'archived' : ''),
|
'classes' => ((intval($rr['abook_archived']) || intval($rr['abook_not_here'])) ? 'archived' : ''),
|
||||||
'link' => z_root() . '/connedit/' . $rr['abook_id'],
|
'link' => z_root() . '/connedit/' . $rr['abook_id'],
|
||||||
'deletelink' => z_root() . '/connedit/' . intval($rr['abook_id']) . '/drop',
|
'deletelink' => z_root() . '/connedit/' . intval($rr['abook_id']) . '/drop',
|
||||||
'delete' => t('Delete'),
|
'delete' => t('Delete'),
|
||||||
'url' => chanlink_url($rr['xchan_url']),
|
'url' => chanlink_hash($rr['xchan_hash']),
|
||||||
'webbie_label' => t('Channel address'),
|
'webbie_label' => t('Channel address'),
|
||||||
'webbie' => $rr['xchan_addr'],
|
'webbie' => $rr['xchan_addr'],
|
||||||
'network_label' => t('Network'),
|
'network_label' => t('Network'),
|
||||||
'network' => network_to_name($rr['xchan_network']),
|
'network' => network_to_name($rr['xchan_network']),
|
||||||
'public_forum' => ((intval($rr['xchan_pubforum'])) ? true : false),
|
'public_forum' => ((intval($rr['xchan_pubforum'])) ? true : false),
|
||||||
|
'call' => t('Call'),
|
||||||
|
'phone' => $phone,
|
||||||
'status_label' => t('Status'),
|
'status_label' => t('Status'),
|
||||||
'status' => $status_str,
|
'status' => $status_str,
|
||||||
'connected_label' => t('Connected'),
|
'connected_label' => t('Connected'),
|
||||||
|
|||||||
@@ -11,9 +11,6 @@ namespace Zotlabs\Module;
|
|||||||
require_once('include/socgraph.php');
|
require_once('include/socgraph.php');
|
||||||
require_once('include/selectors.php');
|
require_once('include/selectors.php');
|
||||||
require_once('include/group.php');
|
require_once('include/group.php');
|
||||||
require_once('include/contact_widgets.php');
|
|
||||||
require_once('include/zot.php');
|
|
||||||
require_once('include/widgets.php');
|
|
||||||
require_once('include/photos.php');
|
require_once('include/photos.php');
|
||||||
|
|
||||||
|
|
||||||
@@ -37,16 +34,18 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
intval(argv(1))
|
intval(argv(1))
|
||||||
);
|
);
|
||||||
if($r) {
|
if($r) {
|
||||||
\App::$poi = $r[0];
|
\App::$poi = array_shift($r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$channel = \App::get_channel();
|
$channel = \App::get_channel();
|
||||||
if($channel)
|
if($channel)
|
||||||
head_set_icon($channel['xchan_photo_s']);
|
head_set_icon($channel['xchan_photo_s']);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* @brief Evaluate posted values and set changes
|
/* @brief Evaluate posted values and set changes
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -84,6 +83,12 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
call_hooks('contact_edit_post', $_POST);
|
call_hooks('contact_edit_post', $_POST);
|
||||||
|
|
||||||
|
$vc = get_abconfig(local_channel(),$orig_record['abook_xchan'],'system','vcard');
|
||||||
|
$vcard = (($vc) ? \Sabre\VObject\Reader::read($vc) : null);
|
||||||
|
$serialised_vcard = update_vcard($_REQUEST,$vcard);
|
||||||
|
if($serialised_vcard)
|
||||||
|
set_abconfig(local_channel(),$orig_record[0]['abook_xchan'],'system','vcard',$serialised_vcard);
|
||||||
|
|
||||||
if(intval($orig_record[0]['abook_self'])) {
|
if(intval($orig_record[0]['abook_self'])) {
|
||||||
$autoperms = intval($_POST['autoperms']);
|
$autoperms = intval($_POST['autoperms']);
|
||||||
$is_self = true;
|
$is_self = true;
|
||||||
@@ -96,7 +101,7 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$profile_id = $_POST['profile_assign'];
|
$profile_id = $_POST['profile_assign'];
|
||||||
if($profile_id) {
|
if($profile_id) {
|
||||||
$r = q("SELECT profile_guid FROM profile WHERE profile_guid = '%s' AND `uid` = %d LIMIT 1",
|
$r = q("SELECT profile_guid FROM profile WHERE profile_guid = '%s' AND uid = %d LIMIT 1",
|
||||||
dbesc($profile_id),
|
dbesc($profile_id),
|
||||||
intval(local_channel())
|
intval(local_channel())
|
||||||
);
|
);
|
||||||
@@ -204,6 +209,7 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(($_REQUEST['pending']) && intval($orig_record[0]['abook_pending'])) {
|
if(($_REQUEST['pending']) && intval($orig_record[0]['abook_pending'])) {
|
||||||
|
|
||||||
$new_friend = true;
|
$new_friend = true;
|
||||||
|
|
||||||
// @fixme it won't be common, but when you accept a new connection request
|
// @fixme it won't be common, but when you accept a new connection request
|
||||||
@@ -213,21 +219,13 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
// request. The workaround is to approve the connection, then go back and
|
// request. The workaround is to approve the connection, then go back and
|
||||||
// adjust permissions as desired.
|
// adjust permissions as desired.
|
||||||
|
|
||||||
$abook_my_perms = get_channel_default_perms(local_channel());
|
$p = \Zotlabs\Access\Permissions::connect_perms(local_channel());
|
||||||
|
$my_perms = $p['perms'];
|
||||||
$role = get_pconfig(local_channel(),'system','permissions_role');
|
if($my_perms) {
|
||||||
if($role) {
|
foreach($my_perms as $k => $v) {
|
||||||
$x = \Zotlabs\Access\PermissionRoles::role_perms($role);
|
set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$k,$v);
|
||||||
if($x['perms_connect']) {
|
|
||||||
$abook_my_perms = $x['perms_connect'];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$filled_perms = \Zotlabs\Access\Permissions::FilledPerms($abook_my_perms);
|
|
||||||
foreach($filled_perms as $k => $v) {
|
|
||||||
set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$k,$v);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$abook_pending = (($new_friend) ? 0 : $orig_record[0]['abook_pending']);
|
$abook_pending = (($new_friend) ? 0 : $orig_record[0]['abook_pending']);
|
||||||
@@ -244,20 +242,16 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
intval(local_channel())
|
intval(local_channel())
|
||||||
);
|
);
|
||||||
|
|
||||||
if($orig_record[0]['abook_profile'] != $profile_id) {
|
|
||||||
//Update profile photo permissions
|
|
||||||
|
|
||||||
logger('A new profile was assigned - updating profile photos');
|
|
||||||
profile_photo_set_profile_perms(local_channel(),$profile_id);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if($r)
|
if($r)
|
||||||
info( t('Connection updated.') . EOL);
|
info( t('Connection updated.') . EOL);
|
||||||
else
|
else
|
||||||
notice( t('Failed to update connection record.') . EOL);
|
notice( t('Failed to update connection record.') . EOL);
|
||||||
|
|
||||||
if(! intval(\App::$poi['abook_self'])) {
|
if(! intval(\App::$poi['abook_self'])) {
|
||||||
|
if($new_friend) {
|
||||||
|
\Zotlabs\Daemon\Master::Summon( [ 'Notifier', 'permission_accept', $contact_id ] );
|
||||||
|
}
|
||||||
|
|
||||||
\Zotlabs\Daemon\Master::Summon( [
|
\Zotlabs\Daemon\Master::Summon( [
|
||||||
'Notifier',
|
'Notifier',
|
||||||
(($new_friend) ? 'permission_create' : 'permission_update'),
|
(($new_friend) ? 'permission_create' : 'permission_update'),
|
||||||
@@ -365,7 +359,7 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
intval(\App::$poi['abook_id'])
|
intval(\App::$poi['abook_id'])
|
||||||
);
|
);
|
||||||
if($r) {
|
if($r) {
|
||||||
\App::$poi = $r[0];
|
\App::$poi = array_shift($r);
|
||||||
}
|
}
|
||||||
|
|
||||||
$clone = \App::$poi;
|
$clone = \App::$poi;
|
||||||
@@ -396,31 +390,24 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
return login();
|
return login();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$section = ((array_key_exists('section',$_REQUEST)) ? $_REQUEST['section'] : '');
|
||||||
$channel = \App::get_channel();
|
$channel = \App::get_channel();
|
||||||
$my_perms = get_channel_default_perms(local_channel());
|
|
||||||
$role = get_pconfig(local_channel(),'system','permissions_role');
|
|
||||||
if($role) {
|
|
||||||
$x = \Zotlabs\Access\PermissionRoles::role_perms($role);
|
|
||||||
if($x['perms_connect'])
|
|
||||||
$my_perms = $x['perms_connect'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$yes_no = array(t('No'),t('Yes'));
|
$yes_no = array(t('No'),t('Yes'));
|
||||||
|
|
||||||
if($my_perms) {
|
$connect_perms = \Zotlabs\Access\Permissions::connect_perms(local_channel());
|
||||||
$o .= "<script>function connectDefaultShare() {
|
|
||||||
\$('.abook-edit-me').each(function() {
|
$o .= "<script>function connectDefaultShare() {
|
||||||
if(! $(this).is(':disabled'))
|
\$('.abook-edit-me').each(function() {
|
||||||
$(this).prop('checked', false);
|
if(! $(this).is(':disabled'))
|
||||||
});\n\n";
|
$(this).prop('checked', false);
|
||||||
$perms = get_perms();
|
});\n\n";
|
||||||
foreach($perms as $p => $v) {
|
foreach($connect_perms['perms'] as $p => $v) {
|
||||||
if($my_perms & $v[1]) {
|
if($v) {
|
||||||
$o .= "\$('#me_id_perms_" . $p . "').prop('checked', true); \n";
|
$o .= "\$('#me_id_perms_" . $p . "').prop('checked', true); \n";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$o .= " }\n</script>\n";
|
|
||||||
}
|
}
|
||||||
|
$o .= " }\n</script>\n";
|
||||||
|
|
||||||
if(argc() == 3) {
|
if(argc() == 3) {
|
||||||
|
|
||||||
@@ -447,8 +434,36 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
goaway(z_root() . '/connedit/' . $contact_id);
|
goaway(z_root() . '/connedit/' . $contact_id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($cmd === 'fetchvc') {
|
||||||
|
$url = str_replace('/channel/','/profile/',$orig_record[0]['xchan_url']) . '/vcard';
|
||||||
|
$recurse = 0;
|
||||||
|
$x = z_fetch_url(zid($url),false,$recurse,['session' => true]);
|
||||||
|
if($x['success']) {
|
||||||
|
$h = new \Zotlabs\Web\HTTPHeaders($x['header']);
|
||||||
|
$fields = $h->fetch();
|
||||||
|
if($fields) {
|
||||||
|
foreach($fields as $y) {
|
||||||
|
if(array_key_exists('content-type',$y)) {
|
||||||
|
$type = explode(';',trim($y['content-type']));
|
||||||
|
if($type && $type[0] === 'text/vcard' && $x['body']) {
|
||||||
|
$vc = \Sabre\VObject\Reader::read($x['body']);
|
||||||
|
$vcard = $vc->serialize();
|
||||||
|
if($vcard) {
|
||||||
|
set_abconfig(local_channel(),$orig_record[0]['abook_xchan'],'system','vcard',$vcard);
|
||||||
|
$this->connedit_clone($a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goaway(z_root() . '/connedit/' . $contact_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if($cmd === 'resetphoto') {
|
if($cmd === 'resetphoto') {
|
||||||
q("update xchan set xchan_photo_date = '2001-01-01 00:00:00' where xchan_hash = '%s' limit 1",
|
q("update xchan set xchan_photo_date = '2001-01-01 00:00:00' where xchan_hash = '%s'",
|
||||||
dbesc($orig_record[0]['xchan_hash'])
|
dbesc($orig_record[0]['xchan_hash'])
|
||||||
);
|
);
|
||||||
$cmd = 'refresh';
|
$cmd = 'refresh';
|
||||||
@@ -521,11 +536,12 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
if($cmd === 'drop') {
|
if($cmd === 'drop') {
|
||||||
|
|
||||||
|
|
||||||
// FIXME
|
// @FIXME
|
||||||
// We need to send either a purge or a refresh packet to the other side (the channel being unfriended).
|
// We need to send either a purge or a refresh packet to the other side (the channel being unfriended).
|
||||||
// The issue is that the abook DB record _may_ get destroyed when we call contact_remove. As the notifier runs
|
// The issue is that the abook DB record _may_ get destroyed when we call contact_remove. As the notifier
|
||||||
// in the background there could be a race condition preventing this packet from being sent in all cases.
|
// runs in the background there could be a race condition preventing this packet from being sent in all
|
||||||
// PLACEHOLDER
|
// cases.
|
||||||
|
// PLACEHOLDER
|
||||||
|
|
||||||
contact_remove(local_channel(), $orig_record[0]['abook_id']);
|
contact_remove(local_channel(), $orig_record[0]['abook_id']);
|
||||||
build_sync_packet(0 /* use the current local_channel */,
|
build_sync_packet(0 /* use the current local_channel */,
|
||||||
@@ -545,9 +561,33 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
if(\App::$poi) {
|
if(\App::$poi) {
|
||||||
|
|
||||||
|
$abook_prev = 0;
|
||||||
|
$abook_next = 0;
|
||||||
|
|
||||||
$contact_id = \App::$poi['abook_id'];
|
$contact_id = \App::$poi['abook_id'];
|
||||||
$contact = \App::$poi;
|
$contact = \App::$poi;
|
||||||
|
|
||||||
|
$cn = q("SELECT abook_id, xchan_name from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_self = 0 and xchan_deleted = 0 order by xchan_name",
|
||||||
|
intval(local_channel())
|
||||||
|
);
|
||||||
|
|
||||||
|
if($cn) {
|
||||||
|
$pntotal = count($cn);
|
||||||
|
|
||||||
|
for($x = 0; $x < $pntotal; $x ++) {
|
||||||
|
if($cn[$x]['abook_id'] == $contact_id) {
|
||||||
|
if($x === 0)
|
||||||
|
$abook_prev = 0;
|
||||||
|
else
|
||||||
|
$abook_prev = $cn[$x - 1]['abook_id'];
|
||||||
|
if($x === $pntotal)
|
||||||
|
$abook_next = 0;
|
||||||
|
else
|
||||||
|
$abook_next = $cn[$x +1]['abook_id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$tools = array(
|
$tools = array(
|
||||||
|
|
||||||
'view' => array(
|
'view' => array(
|
||||||
@@ -564,6 +604,13 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
'title' => t('Fetch updated permissions'),
|
'title' => t('Fetch updated permissions'),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
'rephoto' => array(
|
||||||
|
'label' => t('Refresh Photo'),
|
||||||
|
'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/resetphoto',
|
||||||
|
'sel' => '',
|
||||||
|
'title' => t('Fetch updated photo'),
|
||||||
|
),
|
||||||
|
|
||||||
'recent' => array(
|
'recent' => array(
|
||||||
'label' => t('Recent Activity'),
|
'label' => t('Recent Activity'),
|
||||||
'url' => z_root() . '/network/?f=&cid=' . $contact['abook_id'],
|
'url' => z_root() . '/network/?f=&cid=' . $contact['abook_id'],
|
||||||
@@ -612,22 +659,59 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if($contact['xchan_network'] === 'zot') {
|
||||||
|
$tools['fetchvc'] = [
|
||||||
|
'label' => t('Fetch Vcard'),
|
||||||
|
'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/fetchvc',
|
||||||
|
'sel' => '',
|
||||||
|
'title' => t('Fetch electronic calling card for this connection')
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$sections = [];
|
||||||
|
|
||||||
|
$sections['perms'] = [
|
||||||
|
'label' => t('Permissions'),
|
||||||
|
'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/?f=§ion=perms',
|
||||||
|
'sel' => '',
|
||||||
|
'title' => t('Open Individual Permissions section by default'),
|
||||||
|
];
|
||||||
|
|
||||||
$self = false;
|
$self = false;
|
||||||
|
|
||||||
if(intval($contact['abook_self']))
|
if(intval($contact['abook_self'])) {
|
||||||
$self = true;
|
$self = true;
|
||||||
|
$abook_prev = $abook_next = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$vc = get_abconfig(local_channel(),$contact['abook_xchan'],'system','vcard');
|
||||||
|
|
||||||
|
$vctmp = (($vc) ? \Sabre\VObject\Reader::read($vc) : null);
|
||||||
|
$vcard = (($vctmp) ? get_vcard_array($vctmp,$contact['abook_id']) : [] );
|
||||||
|
if(! $vcard)
|
||||||
|
$vcard['fn'] = $contact['xchan_name'];
|
||||||
|
|
||||||
|
|
||||||
$tpl = get_markup_template("abook_edit.tpl");
|
$tpl = get_markup_template("abook_edit.tpl");
|
||||||
|
|
||||||
if(feature_enabled(local_channel(),'affinity')) {
|
if(feature_enabled(local_channel(),'affinity')) {
|
||||||
|
|
||||||
$labels = array(
|
$sections['affinity'] = [
|
||||||
|
'label' => t('Affinity'),
|
||||||
|
'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/?f=§ion=affinity',
|
||||||
|
'sel' => '',
|
||||||
|
'title' => t('Open Set Affinity section by default'),
|
||||||
|
];
|
||||||
|
|
||||||
|
$labels = [
|
||||||
t('Me'),
|
t('Me'),
|
||||||
t('Family'),
|
t('Family'),
|
||||||
t('Friends'),
|
t('Friends'),
|
||||||
t('Acquaintances'),
|
t('Acquaintances'),
|
||||||
t('All')
|
t('All')
|
||||||
);
|
];
|
||||||
call_hooks('affinity_labels',$labels);
|
call_hooks('affinity_labels',$labels);
|
||||||
$label_str = '';
|
$label_str = '';
|
||||||
|
|
||||||
@@ -650,6 +734,15 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(feature_enabled(local_channel(),'connfilter')) {
|
||||||
|
$sections['filter'] = [
|
||||||
|
'label' => t('Filter'),
|
||||||
|
'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/?f=§ion=filter',
|
||||||
|
'sel' => '',
|
||||||
|
'title' => t('Open Custom Filter section by default'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
$rating_val = 0;
|
$rating_val = 0;
|
||||||
$rating_text = '';
|
$rating_text = '';
|
||||||
|
|
||||||
@@ -724,6 +817,15 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
$perms[] = array('perms_' . $k, $v, ((array_key_exists($k,$their_perms)) ? intval($their_perms[$k]) : ''),$thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '' : '1'), '', $checkinherited);
|
$perms[] = array('perms_' . $k, $v, ((array_key_exists($k,$their_perms)) ? intval($their_perms[$k]) : ''),$thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '' : '1'), '', $checkinherited);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$pcat = new \Zotlabs\Lib\Permcat(local_channel());
|
||||||
|
$pcatlist = $pcat->listing();
|
||||||
|
$permcats = [];
|
||||||
|
if($pcatlist) {
|
||||||
|
foreach($pcatlist as $pc) {
|
||||||
|
$permcats[$pc['name']] = $pc['localname'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$locstr = '';
|
$locstr = '';
|
||||||
|
|
||||||
$locs = q("select hubloc_addr as location from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s'
|
$locs = q("select hubloc_addr as location from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s'
|
||||||
@@ -743,16 +845,39 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
$locstr = t('none');
|
$locstr = $contact['xchan_url'];
|
||||||
|
|
||||||
$o .= replace_macros($tpl,array(
|
$clone_warn = '';
|
||||||
|
$clonable = (in_array($contact['xchan_network'],['zot','rss']) ? true : false);
|
||||||
|
if(! $clonable) {
|
||||||
|
$clone_warn = '<strong>';
|
||||||
|
$clone_warn .= ((intval($contact['abook_not_here']))
|
||||||
|
? t('This connection is unreachable from this location.')
|
||||||
|
: t('This connection may be unreachable from other channel locations.')
|
||||||
|
);
|
||||||
|
$clone_warn .= '</strong><br>' . t('Location independence is not supported by their network.');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(intval($contact['abook_not_here']) && $unclonable)
|
||||||
|
$not_here = t('This connection is unreachable from this location. Location independence is not supported by their network.');
|
||||||
|
|
||||||
|
$o .= replace_macros($tpl, [
|
||||||
'$header' => (($self) ? t('Connection Default Permissions') : sprintf( t('Connection: %s'),$contact['xchan_name'])),
|
'$header' => (($self) ? t('Connection Default Permissions') : sprintf( t('Connection: %s'),$contact['xchan_name'])),
|
||||||
'$autoperms' => array('autoperms',t('Apply these permissions automatically'), ((get_pconfig(local_channel(),'system','autoperms')) ? 1 : 0), t('Connection requests will be approved without your interaction'), $yes_no),
|
'$autoperms' => array('autoperms',t('Apply these permissions automatically'), ((get_pconfig(local_channel(),'system','autoperms')) ? 1 : 0), t('Connection requests will be approved without your interaction'), $yes_no),
|
||||||
|
'$permcat' => [ 'permcat', t('Permission role'), '', '',$permcats ],
|
||||||
|
'$permcat_new' => t('Add permission role'),
|
||||||
|
'$permcat_enable' => feature_enabled(local_channel(),'permcats'),
|
||||||
'$addr' => $contact['xchan_addr'],
|
'$addr' => $contact['xchan_addr'],
|
||||||
|
'$primeurl' => $contact['xchan_url'],
|
||||||
|
'$section' => $section,
|
||||||
|
'$sections' => $sections,
|
||||||
|
'$vcard' => $vcard,
|
||||||
'$addr_text' => t('This connection\'s primary address is'),
|
'$addr_text' => t('This connection\'s primary address is'),
|
||||||
'$loc_text' => t('Available locations:'),
|
'$loc_text' => t('Available locations:'),
|
||||||
'$locstr' => $locstr,
|
'$locstr' => $locstr,
|
||||||
|
'$unclonable' => $clone_warn,
|
||||||
'$notself' => (($self) ? '' : '1'),
|
'$notself' => (($self) ? '' : '1'),
|
||||||
'$self' => (($self) ? '1' : ''),
|
'$self' => (($self) ? '1' : ''),
|
||||||
'$autolbl' => t('The permissions indicated on this page will be applied to all new connections.'),
|
'$autolbl' => t('The permissions indicated on this page will be applied to all new connections.'),
|
||||||
@@ -787,12 +912,42 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
'$permnote_self' => t('Some permissions may be inherited from your channel\'s <a href="settings"><strong>privacy settings</strong></a>, which have higher priority than individual settings. You can change those settings here but they wont have any impact unless the inherited setting changes.'),
|
'$permnote_self' => t('Some permissions may be inherited from your channel\'s <a href="settings"><strong>privacy settings</strong></a>, which have higher priority than individual settings. You can change those settings here but they wont have any impact unless the inherited setting changes.'),
|
||||||
'$lastupdtext' => t('Last update:'),
|
'$lastupdtext' => t('Last update:'),
|
||||||
'$last_update' => relative_date($contact['abook_connected']),
|
'$last_update' => relative_date($contact['abook_connected']),
|
||||||
|
'$is_mobile' => ((\App::$is_mobile || \App::$is_tablet) ? true : false),
|
||||||
'$profile_select' => contact_profile_assign($contact['abook_profile']),
|
'$profile_select' => contact_profile_assign($contact['abook_profile']),
|
||||||
'$multiprofs' => $multiprofs,
|
'$multiprofs' => $multiprofs,
|
||||||
'$contact_id' => $contact['abook_id'],
|
'$contact_id' => $contact['abook_id'],
|
||||||
'$name' => $contact['xchan_name'],
|
'$name' => $contact['xchan_name'],
|
||||||
|
'$abook_prev' => $abook_prev,
|
||||||
));
|
'$abook_next' => $abook_next,
|
||||||
|
'$vcard_label' => t('Details'),
|
||||||
|
'$displayname' => $displayname,
|
||||||
|
'$name_label' => t('Name'),
|
||||||
|
'$org_label' => t('Organisation'),
|
||||||
|
'$title_label' => t('Title'),
|
||||||
|
'$tel_label' => t('Phone'),
|
||||||
|
'$email_label' => t('Email'),
|
||||||
|
'$impp_label' => t('Instant messenger'),
|
||||||
|
'$url_label' => t('Website'),
|
||||||
|
'$adr_label' => t('Address'),
|
||||||
|
'$note_label' => t('Note'),
|
||||||
|
'$mobile' => t('Mobile'),
|
||||||
|
'$home' => t('Home'),
|
||||||
|
'$work' => t('Work'),
|
||||||
|
'$other' => t('Other'),
|
||||||
|
'$add_card' => t('Add Contact'),
|
||||||
|
'$add_field' => t('Add Field'),
|
||||||
|
'$create' => t('Create'),
|
||||||
|
'$update' => t('Update'),
|
||||||
|
'$delete' => t('Delete'),
|
||||||
|
'$cancel' => t('Cancel'),
|
||||||
|
'$po_box' => t('P.O. Box'),
|
||||||
|
'$extra' => t('Additional'),
|
||||||
|
'$street' => t('Street'),
|
||||||
|
'$locality' => t('Locality'),
|
||||||
|
'$region' => t('Region'),
|
||||||
|
'$zip_code' => t('ZIP Code'),
|
||||||
|
'$country' => t('Country')
|
||||||
|
]);
|
||||||
|
|
||||||
$arr = array('contact' => $contact,'output' => $o);
|
$arr = array('contact' => $contact,'output' => $o);
|
||||||
|
|
||||||
@@ -801,8 +956,5 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
return $arr['output'];
|
return $arr['output'];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class Contactgroup extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
if((argc() > 1) && (intval(argv(1)))) {
|
if((argc() > 1) && (intval(argv(1)))) {
|
||||||
|
|
||||||
$r = q("SELECT * FROM `groups` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1",
|
$r = q("SELECT * FROM groups WHERE id = %d AND uid = %d AND deleted = 0 LIMIT 1",
|
||||||
intval(argv(1)),
|
intval(argv(1)),
|
||||||
intval(local_channel())
|
intval(local_channel())
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -23,19 +23,17 @@ require_once('include/channel.php');
|
|||||||
class Cover_photo extends \Zotlabs\Web\Controller {
|
class Cover_photo extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
|
|
||||||
if(! local_channel()) {
|
if(! local_channel()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$channel = \App::get_channel();
|
$channel = \App::get_channel();
|
||||||
profile_load($channel['channel_address']);
|
profile_load($channel['channel_address']);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @brief Evaluate posted values
|
/**
|
||||||
|
* @brief Evaluate posted values
|
||||||
*
|
*
|
||||||
* @param $a Current application
|
|
||||||
* @return void
|
* @return void
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -88,7 +86,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
|||||||
if($r) {
|
if($r) {
|
||||||
|
|
||||||
$base_image = $r[0];
|
$base_image = $r[0];
|
||||||
$base_image['content'] = (($r[0]['os_storage']) ? @file_get_contents($base_image['content']) : dbunescbin($base_image['content']));
|
$base_image['content'] = (($r[0]['os_storage']) ? @file_get_contents(dbunescbin($base_image['content'])) : dbunescbin($base_image['content']));
|
||||||
|
|
||||||
$im = photo_factory($base_image['content'], $base_image['mimetype']);
|
$im = photo_factory($base_image['content'], $base_image['mimetype']);
|
||||||
if($im->is_valid()) {
|
if($im->is_valid()) {
|
||||||
@@ -130,8 +128,15 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$aid = get_account_id();
|
$aid = get_account_id();
|
||||||
|
|
||||||
$p = array('aid' => $aid, 'uid' => local_channel(), 'resource_id' => $base_image['resource_id'],
|
$p = [
|
||||||
'filename' => $base_image['filename'], 'album' => t('Cover Photos'));
|
'aid' => $aid,
|
||||||
|
'uid' => local_channel(),
|
||||||
|
'resource_id' => $base_image['resource_id'],
|
||||||
|
'filename' => $base_image['filename'],
|
||||||
|
'album' => t('Cover Photos'),
|
||||||
|
'os_path' => $base_image['os_path'],
|
||||||
|
'display_path' => $base_image['display_path']
|
||||||
|
];
|
||||||
|
|
||||||
$p['imgscale'] = 7;
|
$p['imgscale'] = 7;
|
||||||
$p['photo_usage'] = PHOTO_COVER;
|
$p['photo_usage'] = PHOTO_COVER;
|
||||||
@@ -195,11 +200,10 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
|||||||
$os_storage = false;
|
$os_storage = false;
|
||||||
|
|
||||||
foreach($i as $ii) {
|
foreach($i as $ii) {
|
||||||
$smallest = intval($ii['imgscale']);
|
$smallest = intval($ii['imgscale']);
|
||||||
$os_storage = intval($ii['os_storage']);
|
$os_storage = intval($ii['os_storage']);
|
||||||
$imagedata = $ii['content'];
|
$imagedata = $ii['content'];
|
||||||
$filetype = $ii['mimetype'];
|
$filetype = $ii['mimetype'];
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,10 +267,10 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* @brief Generate content of profile-photo view
|
/**
|
||||||
|
* @brief Generate content of profile-photo view
|
||||||
*
|
*
|
||||||
* @param $a Current application
|
* @return string
|
||||||
* @return void
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -309,7 +313,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
|||||||
$havescale = true;
|
$havescale = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$r = q("SELECT `content`, `mimetype`, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1",
|
$r = q("SELECT content, mimetype, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1",
|
||||||
intval($r[0]['id']),
|
intval($r[0]['id']),
|
||||||
intval(local_channel())
|
intval(local_channel())
|
||||||
|
|
||||||
@@ -320,7 +324,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(intval($r[0]['os_storage']))
|
if(intval($r[0]['os_storage']))
|
||||||
$data = @file_get_contents($r[0]['content']);
|
$data = @file_get_contents(dbunescbin($r[0]['content']));
|
||||||
else
|
else
|
||||||
$data = dbunescbin($r[0]['content']);
|
$data = dbunescbin($r[0]['content']);
|
||||||
|
|
||||||
@@ -350,15 +354,15 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
|||||||
$tpl = get_markup_template('cover_photo.tpl');
|
$tpl = get_markup_template('cover_photo.tpl');
|
||||||
|
|
||||||
$o .= replace_macros($tpl,array(
|
$o .= replace_macros($tpl,array(
|
||||||
'$user' => \App::$channel['channel_address'],
|
'$user' => \App::$channel['channel_address'],
|
||||||
'$lbl_upfile' => t('Upload File:'),
|
'$lbl_upfile' => t('Upload File:'),
|
||||||
'$lbl_profiles' => t('Select a profile:'),
|
'$lbl_profiles' => t('Select a profile:'),
|
||||||
'$title' => t('Upload Cover Photo'),
|
'$title' => t('Upload Cover Photo'),
|
||||||
'$submit' => t('Upload'),
|
'$submit' => t('Upload'),
|
||||||
'$profiles' => $profiles,
|
'$profiles' => $profiles,
|
||||||
'$form_security_token' => get_form_security_token("cover_photo"),
|
'$form_security_token' => get_form_security_token("cover_photo"),
|
||||||
// FIXME - yuk
|
/// @FIXME - yuk
|
||||||
'$select' => sprintf('%s %s', t('or'), ($newuser) ? '<a href="' . z_root() . '">' . t('skip this step') . '</a>' : '<a href="'. z_root() . '/photos/' . \App::$channel['channel_address'] . '">' . t('select a photo from your photo albums') . '</a>')
|
'$select' => sprintf('%s %s', t('or'), ($newuser) ? '<a href="' . z_root() . '">' . t('skip this step') . '</a>' : '<a href="'. z_root() . '/photos/' . \App::$channel['channel_address'] . '">' . t('select a photo from your photo albums') . '</a>')
|
||||||
));
|
));
|
||||||
|
|
||||||
call_hooks('cover_photo_content_end', $o);
|
call_hooks('cover_photo_content_end', $o);
|
||||||
@@ -370,14 +374,14 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
|||||||
$resolution = 3;
|
$resolution = 3;
|
||||||
$tpl = get_markup_template("cropcover.tpl");
|
$tpl = get_markup_template("cropcover.tpl");
|
||||||
$o .= replace_macros($tpl,array(
|
$o .= replace_macros($tpl,array(
|
||||||
'$filename' => $filename,
|
'$filename' => $filename,
|
||||||
'$profile' => intval($_REQUEST['profile']),
|
'$profile' => intval($_REQUEST['profile']),
|
||||||
'$resource' => \App::$data['imagecrop'] . '-3',
|
'$resource' => \App::$data['imagecrop'] . '-3',
|
||||||
'$image_url' => z_root() . '/photo/' . $filename,
|
'$image_url' => z_root() . '/photo/' . $filename,
|
||||||
'$title' => t('Crop Image'),
|
'$title' => t('Crop Image'),
|
||||||
'$desc' => t('Please adjust the image cropping for optimum viewing.'),
|
'$desc' => t('Please adjust the image cropping for optimum viewing.'),
|
||||||
'$form_security_token' => get_form_security_token("cover_photo"),
|
'$form_security_token' => get_form_security_token("cover_photo"),
|
||||||
'$done' => t('Done Editing')
|
'$done' => t('Done Editing')
|
||||||
));
|
));
|
||||||
return $o;
|
return $o;
|
||||||
}
|
}
|
||||||
@@ -393,8 +397,6 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function cover_photo_crop_ui_head(&$a, $ph, $hash, $smallest){
|
function cover_photo_crop_ui_head(&$a, $ph, $hash, $smallest){
|
||||||
|
|
||||||
$max_length = get_config('system','max_image_length');
|
$max_length = get_config('system','max_image_length');
|
||||||
|
|||||||
@@ -1,47 +1,88 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Zotlabs\Module;
|
|
||||||
/**
|
/**
|
||||||
* @file mod/dav.php
|
* @file Zotlabs/Module/Dav.php
|
||||||
* @brief Initialize Hubzilla's cloud (SabreDAV).
|
* @brief Initialize Hubzilla's cloud (SabreDAV).
|
||||||
*
|
*
|
||||||
* Module for accessing the DAV storage area from a DAV client.
|
* Module for accessing the DAV storage area from a DAV client.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace Zotlabs\Module;
|
||||||
|
|
||||||
use \Sabre\DAV as SDAV;
|
use \Sabre\DAV as SDAV;
|
||||||
use \Zotlabs\Storage;
|
use \Zotlabs\Storage;
|
||||||
|
|
||||||
// composer autoloader for SabreDAV
|
|
||||||
require_once('vendor/autoload.php');
|
|
||||||
|
|
||||||
require_once('include/attach.php');
|
require_once('include/attach.php');
|
||||||
|
require_once('include/auth.php');
|
||||||
|
require_once('include/security.php');
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Fires up the SabreDAV server.
|
|
||||||
*
|
|
||||||
* @param App &$a
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Dav extends \Zotlabs\Web\Controller {
|
class Dav extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fires up the SabreDAV server.
|
||||||
|
*
|
||||||
|
*/
|
||||||
function init() {
|
function init() {
|
||||||
|
|
||||||
// workaround for HTTP-auth in CGI mode
|
foreach([ 'REDIRECT_REMOTE_USER', 'HTTP_AUTHORIZATION' ] as $head) {
|
||||||
if (x($_SERVER, 'REDIRECT_REMOTE_USER')) {
|
|
||||||
$userpass = base64_decode(substr($_SERVER["REDIRECT_REMOTE_USER"], 6)) ;
|
|
||||||
if(strlen($userpass)) {
|
|
||||||
list($name, $password) = explode(':', $userpass);
|
|
||||||
$_SERVER['PHP_AUTH_USER'] = $name;
|
|
||||||
$_SERVER['PHP_AUTH_PW'] = $password;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x($_SERVER, 'HTTP_AUTHORIZATION')) {
|
/* Basic authentication */
|
||||||
$userpass = base64_decode(substr($_SERVER["HTTP_AUTHORIZATION"], 6)) ;
|
|
||||||
if(strlen($userpass)) {
|
if(array_key_exists($head,$_SERVER) && substr(trim($_SERVER[$head]),0,5) === 'Basic') {
|
||||||
list($name, $password) = explode(':', $userpass);
|
$userpass = @base64_decode(substr(trim($_SERVER[$head]),6)) ;
|
||||||
$_SERVER['PHP_AUTH_USER'] = $name;
|
if(strlen($userpass)) {
|
||||||
$_SERVER['PHP_AUTH_PW'] = $password;
|
list($name, $password) = explode(':', $userpass);
|
||||||
|
$_SERVER['PHP_AUTH_USER'] = $name;
|
||||||
|
$_SERVER['PHP_AUTH_PW'] = $password;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Signature authentication */
|
||||||
|
|
||||||
|
if(array_key_exists($head,$_SERVER) && substr(trim($_SERVER[$head]),0,9) === 'Signature') {
|
||||||
|
if($head !== 'HTTP_AUTHORIZATION') {
|
||||||
|
$_SERVER['HTTP_AUTHORIZATION'] = $_SERVER[$head];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sigblock = \Zotlabs\Web\HTTPSig::parse_sigheader($_SERVER[$head]);
|
||||||
|
if($sigblock) {
|
||||||
|
$keyId = str_replace('acct:','',$sigblock['keyId']);
|
||||||
|
if($keyId) {
|
||||||
|
$r = q("select * from hubloc where hubloc_addr = '%s' limit 1",
|
||||||
|
dbesc($keyId)
|
||||||
|
);
|
||||||
|
if($r) {
|
||||||
|
$c = channelx_by_hash($r[0]['hubloc_hash']);
|
||||||
|
if($c) {
|
||||||
|
$a = q("select * from account where account_id = %d limit 1",
|
||||||
|
intval($c['channel_account_id'])
|
||||||
|
);
|
||||||
|
if($a) {
|
||||||
|
$record = [ 'channel' => $c, 'account' => $a[0] ];
|
||||||
|
$channel_login = $c['channel_id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(! $record)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if($record) {
|
||||||
|
$verified = \Zotlabs\Web\HTTPSig::verify('',$record['channel']['channel_pubkey']);
|
||||||
|
if(! ($verified && $verified['header_signed'] && $verified['header_valid'])) {
|
||||||
|
$record = null;
|
||||||
|
}
|
||||||
|
if($record['account']) {
|
||||||
|
authenticate_success($record['account']);
|
||||||
|
if($channel_login) {
|
||||||
|
change_channel($channel_login);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +117,6 @@ class Dav extends \Zotlabs\Web\Controller {
|
|||||||
$auth->setBrowserPlugin($browser);
|
$auth->setBrowserPlugin($browser);
|
||||||
|
|
||||||
// Experimental QuotaPlugin
|
// Experimental QuotaPlugin
|
||||||
// require_once('Zotlabs/Storage/QuotaPlugin.php');
|
|
||||||
// $server->addPlugin(new \Zotlabs\Storage\QuotaPlugin($auth));
|
// $server->addPlugin(new \Zotlabs\Storage\QuotaPlugin($auth));
|
||||||
|
|
||||||
// All we need to do now, is to fire up the server
|
// All we need to do now, is to fire up the server
|
||||||
|
|||||||
267
Zotlabs/Module/Defperms.php
Normal file
267
Zotlabs/Module/Defperms.php
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
<?php
|
||||||
|
namespace Zotlabs\Module;
|
||||||
|
|
||||||
|
|
||||||
|
require_once('include/socgraph.php');
|
||||||
|
require_once('include/selectors.php');
|
||||||
|
require_once('include/group.php');
|
||||||
|
require_once('include/photos.php');
|
||||||
|
|
||||||
|
|
||||||
|
class Defperms extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
|
/* @brief Initialize the connection-editor
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
|
||||||
|
if(! local_channel())
|
||||||
|
return;
|
||||||
|
|
||||||
|
$r = q("SELECT abook.*, xchan.*
|
||||||
|
FROM abook left join xchan on abook_xchan = xchan_hash
|
||||||
|
WHERE abook_self = 1 and abook_id = %d LIMIT 1",
|
||||||
|
intval(local_channel())
|
||||||
|
);
|
||||||
|
if($r) {
|
||||||
|
\App::$poi = $r[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$channel = \App::get_channel();
|
||||||
|
if($channel)
|
||||||
|
head_set_icon($channel['xchan_photo_s']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @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();
|
||||||
|
|
||||||
|
$orig_record = q("SELECT * FROM abook WHERE abook_id = %d AND abook_channel = %d LIMIT 1",
|
||||||
|
intval($contact_id),
|
||||||
|
intval(local_channel())
|
||||||
|
);
|
||||||
|
|
||||||
|
if(! $orig_record) {
|
||||||
|
notice( t('Could not access contact record.') . EOL);
|
||||||
|
goaway(z_root() . '/connections');
|
||||||
|
return; // NOTREACHED
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(intval($orig_record[0]['abook_self'])) {
|
||||||
|
$autoperms = intval($_POST['autoperms']);
|
||||||
|
$is_self = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$autoperms = null;
|
||||||
|
$is_self = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$all_perms = \Zotlabs\Access\Permissions::Perms();
|
||||||
|
|
||||||
|
if($all_perms) {
|
||||||
|
foreach($all_perms as $perm => $desc) {
|
||||||
|
|
||||||
|
$checkinherited = \Zotlabs\Access\PermissionLimits::Get(local_channel(),$perm);
|
||||||
|
$inherited = (($checkinherited & PERMS_SPECIFIC) ? false : true);
|
||||||
|
|
||||||
|
if(array_key_exists('perms_' . $perm, $_POST)) {
|
||||||
|
set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$perm,
|
||||||
|
intval($_POST['perms_' . $perm]));
|
||||||
|
if($autoperms) {
|
||||||
|
set_pconfig($channel['channel_id'],'autoperms',$perm,intval($_POST['perms_' . $perm]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$perm,0);
|
||||||
|
if($autoperms) {
|
||||||
|
set_pconfig($channel['channel_id'],'autoperms',$perm,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(! is_null($autoperms))
|
||||||
|
set_pconfig($channel['channel_id'],'system','autoperms',$autoperms);
|
||||||
|
|
||||||
|
|
||||||
|
notice( t('Settings updated.') . EOL);
|
||||||
|
|
||||||
|
|
||||||
|
// Refresh the structure in memory with the new data
|
||||||
|
|
||||||
|
$r = q("SELECT abook.*, xchan.*
|
||||||
|
FROM abook left join xchan on abook_xchan = xchan_hash
|
||||||
|
WHERE abook_channel = %d and abook_id = %d LIMIT 1",
|
||||||
|
intval(local_channel()),
|
||||||
|
intval($contact_id)
|
||||||
|
);
|
||||||
|
if($r) {
|
||||||
|
\App::$poi = $r[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$this->defperms_clone($a);
|
||||||
|
|
||||||
|
goaway(z_root() . '/defperms');
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @brief Clone connection
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function defperms_clone(&$a) {
|
||||||
|
|
||||||
|
if(! \App::$poi)
|
||||||
|
return;
|
||||||
|
|
||||||
|
$channel = \App::get_channel();
|
||||||
|
|
||||||
|
$r = q("SELECT abook.*, xchan.*
|
||||||
|
FROM abook left join xchan on abook_xchan = xchan_hash
|
||||||
|
WHERE abook_channel = %d and abook_id = %d LIMIT 1",
|
||||||
|
intval(local_channel()),
|
||||||
|
intval(\App::$poi['abook_id'])
|
||||||
|
);
|
||||||
|
if($r) {
|
||||||
|
\App::$poi = array_shift($r);
|
||||||
|
}
|
||||||
|
|
||||||
|
$clone = \App::$poi;
|
||||||
|
|
||||||
|
unset($clone['abook_id']);
|
||||||
|
unset($clone['abook_account']);
|
||||||
|
unset($clone['abook_channel']);
|
||||||
|
|
||||||
|
$abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']);
|
||||||
|
if($abconfig)
|
||||||
|
$clone['abconfig'] = $abconfig;
|
||||||
|
|
||||||
|
build_sync_packet(0 /* use the current local_channel */, array('abook' => array($clone)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @brief Generate content of connection default permissions page
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function get() {
|
||||||
|
|
||||||
|
$sort_type = 0;
|
||||||
|
$o = '';
|
||||||
|
|
||||||
|
if(! local_channel()) {
|
||||||
|
notice( t('Permission denied.') . EOL);
|
||||||
|
return login();
|
||||||
|
}
|
||||||
|
|
||||||
|
$section = ((array_key_exists('section',$_REQUEST)) ? $_REQUEST['section'] : '');
|
||||||
|
$channel = \App::get_channel();
|
||||||
|
|
||||||
|
$yes_no = array(t('No'),t('Yes'));
|
||||||
|
|
||||||
|
$connect_perms = \Zotlabs\Access\Permissions::connect_perms(local_channel());
|
||||||
|
|
||||||
|
$o .= "<script>function connectDefaultShare() {
|
||||||
|
\$('.abook-edit-me').each(function() {
|
||||||
|
if(! $(this).is(':disabled'))
|
||||||
|
$(this).prop('checked', false);
|
||||||
|
});\n\n";
|
||||||
|
foreach($connect_perms['perms'] as $p => $v) {
|
||||||
|
if($v) {
|
||||||
|
$o .= "\$('#me_id_perms_" . $p . "').prop('checked', true); \n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$o .= " }\n</script>\n";
|
||||||
|
|
||||||
|
if(\App::$poi) {
|
||||||
|
|
||||||
|
$sections = [];
|
||||||
|
|
||||||
|
$self = false;
|
||||||
|
|
||||||
|
$tpl = get_markup_template('defperms.tpl');
|
||||||
|
|
||||||
|
|
||||||
|
$perms = array();
|
||||||
|
$channel = \App::get_channel();
|
||||||
|
|
||||||
|
$contact = \App::$poi;
|
||||||
|
|
||||||
|
$global_perms = \Zotlabs\Access\Permissions::Perms();
|
||||||
|
|
||||||
|
$existing = get_all_perms(local_channel(),$contact['abook_xchan']);
|
||||||
|
$hidden_perms = [];
|
||||||
|
|
||||||
|
foreach($global_perms as $k => $v) {
|
||||||
|
$thisperm = get_abconfig(local_channel(),$contact['abook_xchan'],'my_perms',$k);
|
||||||
|
|
||||||
|
$checkinherited = \Zotlabs\Access\PermissionLimits::Get(local_channel(),$k);
|
||||||
|
|
||||||
|
$inherited = (($checkinherited & PERMS_SPECIFIC) ? false : true);
|
||||||
|
|
||||||
|
$perms[] = [ 'perms_' . $k, $v, intval($thisperm), '', $yes_no, (($inherited) ? ' disabled="disabled" ' : '') ];
|
||||||
|
if($inherited) {
|
||||||
|
$hidden_perms[] = [ 'perms_' . $k, intval($thisperm) ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pcat = new \Zotlabs\Lib\Permcat(local_channel());
|
||||||
|
$pcatlist = $pcat->listing();
|
||||||
|
$permcats = [];
|
||||||
|
if($pcatlist) {
|
||||||
|
foreach($pcatlist as $pc) {
|
||||||
|
$permcats[$pc['name']] = $pc['localname'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$o .= replace_macros($tpl, [
|
||||||
|
'$header' => t('Connection Default Permissions'),
|
||||||
|
'$autoperms' => array('autoperms',t('Apply these permissions automatically'), ((get_pconfig(local_channel(),'system','autoperms')) ? 1 : 0), t('If enabled, connection requests will be approved without your interaction'), $yes_no),
|
||||||
|
'$permcat' => [ 'permcat', t('Permission role'), '', '',$permcats ],
|
||||||
|
'$permcat_new' => t('Add permission role'),
|
||||||
|
'$permcat_enable' => feature_enabled(local_channel(),'permcats'),
|
||||||
|
'$section' => $section,
|
||||||
|
'$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'),
|
||||||
|
'$perms' => $perms,
|
||||||
|
'$hidden_perms' => $hidden_perms,
|
||||||
|
'$permlbl' => t('Individual Permissions'),
|
||||||
|
'$permnote_self' => t('Some individual permissions may have been preset or locked based on your channel type and privacy settings.'),
|
||||||
|
'$contact_id' => $contact['abook_id'],
|
||||||
|
'$name' => $contact['xchan_name'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$arr = array('contact' => $contact,'output' => $o);
|
||||||
|
|
||||||
|
call_hooks('contact_edit', $arr);
|
||||||
|
|
||||||
|
return $arr['output'];
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Zotlabs\Module;
|
namespace Zotlabs\Module;
|
||||||
|
|
||||||
require_once('include/socgraph.php');
|
require_once('include/socgraph.php');
|
||||||
require_once('include/dir_fns.php');
|
require_once('include/dir_fns.php');
|
||||||
require_once('include/widgets.php');
|
|
||||||
require_once('include/bbcode.php');
|
require_once('include/bbcode.php');
|
||||||
|
|
||||||
|
|
||||||
@@ -64,9 +64,15 @@ class Directory extends \Zotlabs\Web\Controller {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(get_config('system','block_public_directory',false) && (! get_observer_hash())) {
|
||||||
|
notice( t('Public access denied.') . EOL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$observer = get_observer_hash();
|
$observer = get_observer_hash();
|
||||||
|
|
||||||
$globaldir = get_directory_setting($observer, 'globaldir');
|
$globaldir = get_directory_setting($observer, 'globaldir');
|
||||||
|
|
||||||
// override your personal global search pref if we're doing a navbar search of the directory
|
// override your personal global search pref if we're doing a navbar search of the directory
|
||||||
if(intval($_REQUEST['navsearch']))
|
if(intval($_REQUEST['navsearch']))
|
||||||
$globaldir = 1;
|
$globaldir = 1;
|
||||||
@@ -76,7 +82,7 @@ class Directory extends \Zotlabs\Web\Controller {
|
|||||||
$pubforums = get_directory_setting($observer, 'pubforums');
|
$pubforums = get_directory_setting($observer, 'pubforums');
|
||||||
|
|
||||||
$o = '';
|
$o = '';
|
||||||
nav_set_selected('directory');
|
nav_set_selected('Directory');
|
||||||
|
|
||||||
if(x($_POST,'search'))
|
if(x($_POST,'search'))
|
||||||
$search = notags(trim($_POST['search']));
|
$search = notags(trim($_POST['search']));
|
||||||
@@ -101,7 +107,7 @@ class Directory extends \Zotlabs\Web\Controller {
|
|||||||
$common = array();
|
$common = array();
|
||||||
$index = 0;
|
$index = 0;
|
||||||
foreach($r as $rr) {
|
foreach($r as $rr) {
|
||||||
$common[$rr['xchan_addr']] = $rr['total'];
|
$common[$rr['xchan_addr']] = ((intval($rr['total']) > 0) ? intval($rr['total']) - 1 : 0);
|
||||||
$addresses[$rr['xchan_addr']] = $index++;
|
$addresses[$rr['xchan_addr']] = $index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,7 +238,7 @@ class Directory extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$age = '';
|
$age = '';
|
||||||
if(strlen($rr['birthday'])) {
|
if(strlen($rr['birthday'])) {
|
||||||
if(($years = age($rr['birthday'],'UTC','')) != 0)
|
if(($years = age($rr['birthday'],'UTC','')) > 0)
|
||||||
$age = $years;
|
$age = $years;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,7 +267,7 @@ class Directory extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$hometown = ((x($profile,'hometown') == 1) ? $profile['hometown'] : False);
|
$hometown = ((x($profile,'hometown') == 1) ? $profile['hometown'] : False);
|
||||||
|
|
||||||
$about = ((x($profile,'about') == 1) ? bbcode($profile['about']) : False);
|
$about = ((x($profile,'about') == 1) ? zidify_links(bbcode($profile['about'])) : False);
|
||||||
|
|
||||||
$keywords = ((x($profile,'keywords')) ? $profile['keywords'] : '');
|
$keywords = ((x($profile,'keywords')) ? $profile['keywords'] : '');
|
||||||
|
|
||||||
@@ -333,7 +339,7 @@ class Directory extends \Zotlabs\Web\Controller {
|
|||||||
'ignlink' => $suggest ? z_root() . '/directory?ignore=' . $rr['hash'] : '',
|
'ignlink' => $suggest ? z_root() . '/directory?ignore=' . $rr['hash'] : '',
|
||||||
'ignore_label' => t('Don\'t suggest'),
|
'ignore_label' => t('Don\'t suggest'),
|
||||||
'common_friends' => (($common[$rr['address']]) ? intval($common[$rr['address']]) : ''),
|
'common_friends' => (($common[$rr['address']]) ? intval($common[$rr['address']]) : ''),
|
||||||
'common_label' => t('Common connections:'),
|
'common_label' => t('Common connections (estimated):'),
|
||||||
'common_count' => intval($common[$rr['address']]),
|
'common_count' => intval($common[$rr['address']]),
|
||||||
'safe' => $safe_mode
|
'safe' => $safe_mode
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class Dirsearch extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
|
||||||
$ret = array('success' => false);
|
$ret = array('success' => false);
|
||||||
|
|
||||||
@@ -185,7 +185,7 @@ class Dirsearch extends \Zotlabs\Web\Controller {
|
|||||||
else {
|
else {
|
||||||
$qlimit = " LIMIT " . intval($perpage) . " OFFSET " . intval($startrec);
|
$qlimit = " LIMIT " . intval($perpage) . " OFFSET " . intval($startrec);
|
||||||
if($return_total) {
|
if($return_total) {
|
||||||
$r = q("SELECT COUNT(xchan_hash) AS `total` FROM xchan left join xprof on xchan_hash = xprof_hash where $logic $sql_extra and xchan_network = 'zot' and xchan_hidden = 0 and xchan_orphan = 0 and xchan_deleted = 0 $safesql ");
|
$r = q("SELECT COUNT(xchan_hash) AS total FROM xchan left join xprof on xchan_hash = xprof_hash where $logic $sql_extra and xchan_network = 'zot' and xchan_hidden = 0 and xchan_orphan = 0 and xchan_deleted = 0 $safesql ");
|
||||||
if($r) {
|
if($r) {
|
||||||
$ret['total_items'] = $r[0]['total'];
|
$ret['total_items'] = $r[0]['total'];
|
||||||
}
|
}
|
||||||
@@ -410,13 +410,13 @@ class Dirsearch extends \Zotlabs\Web\Controller {
|
|||||||
$rand = db_getfunc('rand');
|
$rand = db_getfunc('rand');
|
||||||
$realm = get_directory_realm();
|
$realm = get_directory_realm();
|
||||||
if($realm == DIRECTORY_REALM) {
|
if($realm == DIRECTORY_REALM) {
|
||||||
$r = q("select * from site where site_access != 0 and site_register !=0 and ( site_realm = '%s' or site_realm = '') and site_type = %d order by $rand",
|
$r = q("select * from site where site_access != 0 and site_register !=0 and ( site_realm = '%s' or site_realm = '') and site_type = %d and site_dead = 0 order by $rand",
|
||||||
dbesc($realm),
|
dbesc($realm),
|
||||||
intval(SITE_TYPE_ZOT)
|
intval(SITE_TYPE_ZOT)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$r = q("select * from site where site_access != 0 and site_register !=0 and site_realm = '%s' and site_type = %d order by $rand",
|
$r = q("select * from site where site_access != 0 and site_register !=0 and site_realm = '%s' and site_type = %d and site_dead = 0 order by $rand",
|
||||||
dbesc($realm),
|
dbesc($realm),
|
||||||
intval(SITE_TYPE_ZOT)
|
intval(SITE_TYPE_ZOT)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,40 +1,46 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Zotlabs\Module;
|
namespace Zotlabs\Module;
|
||||||
|
|
||||||
|
require_once("include/bbcode.php");
|
||||||
|
require_once('include/security.php');
|
||||||
|
require_once('include/conversation.php');
|
||||||
|
require_once('include/acl_selectors.php');
|
||||||
|
require_once('include/items.php');
|
||||||
|
|
||||||
|
|
||||||
class Display extends \Zotlabs\Web\Controller {
|
class Display extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
function get($update = 0, $load = false) {
|
function get($update = 0, $load = false) {
|
||||||
|
|
||||||
|
$module_format = 'html';
|
||||||
|
|
||||||
|
|
||||||
|
if(argc() > 1) {
|
||||||
|
$module_format = substr(argv(1),strrpos(argv(1),'.') + 1);
|
||||||
|
if(! in_array($module_format,['atom','zot','json']))
|
||||||
|
$module_format = 'html';
|
||||||
|
}
|
||||||
|
|
||||||
$checkjs = new \Zotlabs\Web\CheckJS(1);
|
$checkjs = new \Zotlabs\Web\CheckJS(1);
|
||||||
|
|
||||||
if($load)
|
if($load)
|
||||||
$_SESSION['loadtime'] = datetime_convert();
|
$_SESSION['loadtime'] = datetime_convert();
|
||||||
|
|
||||||
|
|
||||||
if(observer_prohibited()) {
|
if(observer_prohibited()) {
|
||||||
notice( t('Public access denied.') . EOL);
|
notice( t('Public access denied.') . EOL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once("include/bbcode.php");
|
if(argc() > 1) {
|
||||||
require_once('include/security.php');
|
|
||||||
require_once('include/conversation.php');
|
|
||||||
require_once('include/acl_selectors.php');
|
|
||||||
require_once('include/items.php');
|
|
||||||
|
|
||||||
|
|
||||||
\App::$page['htmlhead'] .= replace_macros(get_markup_template('display-head.tpl'), array());
|
|
||||||
|
|
||||||
if(argc() > 1 && argv(1) !== 'load')
|
|
||||||
$item_hash = argv(1);
|
$item_hash = argv(1);
|
||||||
|
if($module_format !== 'html') {
|
||||||
|
$item_hash = substr($item_hash,0,strrpos($item_hash,'.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if($_REQUEST['mid'])
|
if($_REQUEST['mid'])
|
||||||
$item_hash = $_REQUEST['mid'];
|
$item_hash = $_REQUEST['mid'];
|
||||||
|
|
||||||
|
|
||||||
if(! $item_hash) {
|
if(! $item_hash) {
|
||||||
\App::$error = 404;
|
\App::$error = 404;
|
||||||
notice( t('Item not found.') . EOL);
|
notice( t('Item not found.') . EOL);
|
||||||
@@ -42,45 +48,42 @@ class Display extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$observer_is_owner = false;
|
$observer_is_owner = false;
|
||||||
|
$updateable = false;
|
||||||
|
|
||||||
if(local_channel() && (! $update)) {
|
if(local_channel() && (! $update)) {
|
||||||
|
|
||||||
$channel = \App::get_channel();
|
$channel = \App::get_channel();
|
||||||
|
|
||||||
|
|
||||||
$channel_acl = array(
|
$channel_acl = array(
|
||||||
'allow_cid' => $channel['channel_allow_cid'],
|
'allow_cid' => $channel['channel_allow_cid'],
|
||||||
'allow_gid' => $channel['channel_allow_gid'],
|
'allow_gid' => $channel['channel_allow_gid'],
|
||||||
'deny_cid' => $channel['channel_deny_cid'],
|
'deny_cid' => $channel['channel_deny_cid'],
|
||||||
'deny_gid' => $channel['channel_deny_gid']
|
'deny_gid' => $channel['channel_deny_gid']
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
$x = array(
|
$x = array(
|
||||||
'is_owner' => true,
|
'is_owner' => true,
|
||||||
'allow_location' => ((intval(get_pconfig($channel['channel_id'],'system','use_browser_location'))) ? '1' : ''),
|
'allow_location' => ((intval(get_pconfig($channel['channel_id'],'system','use_browser_location'))) ? '1' : ''),
|
||||||
'default_location' => $channel['channel_location'],
|
'default_location' => $channel['channel_location'],
|
||||||
'nickname' => $channel['channel_address'],
|
'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' => (($group || $cid || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
|
||||||
|
|
||||||
'acl' => populate_acl($channel_acl),
|
'acl' => populate_acl($channel_acl),
|
||||||
'permissions' => $channel_acl,
|
'permissions' => $channel_acl,
|
||||||
'bang' => '',
|
'bang' => '',
|
||||||
'visitor' => true,
|
'visitor' => true,
|
||||||
'profile_uid' => local_channel(),
|
'profile_uid' => local_channel(),
|
||||||
'return_path' => 'channel/' . $channel['channel_address'],
|
'return_path' => 'channel/' . $channel['channel_address'],
|
||||||
'expanded' => true,
|
'expanded' => true,
|
||||||
'editor_autocomplete' => true,
|
'editor_autocomplete' => true,
|
||||||
'bbco_autocomplete' => 'bbcode',
|
'bbco_autocomplete' => 'bbcode',
|
||||||
'bbcode' => true,
|
'bbcode' => true,
|
||||||
'jotnets' => true
|
'jotnets' => true
|
||||||
);
|
);
|
||||||
|
|
||||||
$o = '<div id="jot-popup">';
|
$o = '<div id="jot-popup">';
|
||||||
$o .= status_editor($a,$x);
|
$o .= status_editor($a,$x);
|
||||||
$o .= '</div>';
|
$o .= '</div>';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This page can be viewed by anybody so the query could be complicated
|
// This page can be viewed by anybody so the query could be complicated
|
||||||
@@ -94,7 +97,12 @@ class Display extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$target_item = null;
|
$target_item = null;
|
||||||
|
|
||||||
$r = q("select id, uid, mid, parent_mid, item_type, item_deleted from item where mid like '%s' limit 1",
|
if(strpos($item_hash,'b64.') === 0)
|
||||||
|
$decoded = @base64url_decode(substr($item_hash,4));
|
||||||
|
if($decoded)
|
||||||
|
$item_hash = $decoded;
|
||||||
|
|
||||||
|
$r = q("select id, uid, mid, parent_mid, thr_parent, verb, item_type, item_deleted, item_blocked from item where mid like '%s' limit 1",
|
||||||
dbesc($item_hash . '%')
|
dbesc($item_hash . '%')
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -102,6 +110,11 @@ class Display extends \Zotlabs\Web\Controller {
|
|||||||
$target_item = $r[0];
|
$target_item = $r[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if the item is to be moderated redirect to /moderate
|
||||||
|
if($target_item['item_blocked'] == ITEM_MODERATED) {
|
||||||
|
goaway(z_root() . '/moderate/' . $target_item['id']);
|
||||||
|
}
|
||||||
|
|
||||||
$r = null;
|
$r = null;
|
||||||
|
|
||||||
if($target_item['item_type'] == ITEM_TYPE_WEBPAGE) {
|
if($target_item['item_type'] == ITEM_TYPE_WEBPAGE) {
|
||||||
@@ -122,6 +135,8 @@ class Display extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$static = ((array_key_exists('static',$_REQUEST)) ? intval($_REQUEST['static']) : 0);
|
||||||
|
|
||||||
|
|
||||||
$simple_update = (($update) ? " AND item_unseen = 1 " : '');
|
$simple_update = (($update) ? " AND item_unseen = 1 " : '');
|
||||||
|
|
||||||
@@ -130,10 +145,20 @@ class Display extends \Zotlabs\Web\Controller {
|
|||||||
if($load)
|
if($load)
|
||||||
$simple_update = '';
|
$simple_update = '';
|
||||||
|
|
||||||
|
if($static && $simple_update)
|
||||||
|
$simple_update .= " and item_thread_top = 0 and author_xchan = '" . protect_sprintf(get_observer_hash()) . "' ";
|
||||||
|
|
||||||
if((! $update) && (! $load)) {
|
if((! $update) && (! $load)) {
|
||||||
|
|
||||||
|
$static = ((local_channel()) ? channel_manual_conv_update(local_channel()) : 1);
|
||||||
|
|
||||||
|
// if the target item is not a post (eg a like) we want to address its thread parent
|
||||||
|
|
||||||
|
$mid = ((($target_item['verb'] == ACTIVITY_LIKE) || ($target_item['verb'] == ACTIVITY_DISLIKE)) ? $target_item['thr_parent'] : $target_item['mid']);
|
||||||
|
|
||||||
|
// if we got a decoded hash we must encode it again before handing to javascript
|
||||||
|
if($decoded)
|
||||||
|
$mid = 'b64.' . base64url_encode($mid);
|
||||||
|
|
||||||
$o .= '<div id="live-display"></div>' . "\r\n";
|
$o .= '<div id="live-display"></div>' . "\r\n";
|
||||||
$o .= "<script> var profile_uid = " . ((intval(local_channel())) ? local_channel() : (-1))
|
$o .= "<script> var profile_uid = " . ((intval(local_channel())) ? local_channel() : (-1))
|
||||||
@@ -141,47 +166,55 @@ class Display extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
\App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array(
|
\App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array(
|
||||||
'$baseurl' => z_root(),
|
'$baseurl' => z_root(),
|
||||||
'$pgtype' => 'display',
|
'$pgtype' => 'display',
|
||||||
'$uid' => '0',
|
'$uid' => '0',
|
||||||
'$gid' => '0',
|
'$gid' => '0',
|
||||||
'$cid' => '0',
|
'$cid' => '0',
|
||||||
'$cmin' => '0',
|
'$cmin' => '0',
|
||||||
'$cmax' => '99',
|
'$cmax' => '99',
|
||||||
'$star' => '0',
|
'$star' => '0',
|
||||||
'$liked' => '0',
|
'$liked' => '0',
|
||||||
'$conv' => '0',
|
'$conv' => '0',
|
||||||
'$spam' => '0',
|
'$spam' => '0',
|
||||||
'$fh' => '0',
|
'$fh' => '0',
|
||||||
'$nouveau' => '0',
|
'$nouveau' => '0',
|
||||||
'$wall' => '0',
|
'$wall' => '0',
|
||||||
'$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1),
|
'$static' => $static,
|
||||||
'$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0),
|
'$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1),
|
||||||
'$search' => '',
|
'$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0),
|
||||||
'$order' => '',
|
'$search' => '',
|
||||||
'$file' => '',
|
'$xchan' => '',
|
||||||
'$cats' => '',
|
'$order' => '',
|
||||||
'$tags' => '',
|
'$file' => '',
|
||||||
'$dend' => '',
|
'$cats' => '',
|
||||||
'$dbegin' => '',
|
'$tags' => '',
|
||||||
'$verb' => '',
|
'$dend' => '',
|
||||||
'$mid' => $item_hash
|
'$dbegin' => '',
|
||||||
|
'$verb' => '',
|
||||||
|
'$net' => '',
|
||||||
|
'$mid' => $mid
|
||||||
));
|
));
|
||||||
|
|
||||||
|
head_add_link([
|
||||||
|
'rel' => 'alternate',
|
||||||
|
'type' => 'application/json+oembed',
|
||||||
|
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string),
|
||||||
|
'title' => 'oembed'
|
||||||
|
]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$observer_hash = get_observer_hash();
|
$observer_hash = get_observer_hash();
|
||||||
$item_normal = item_normal();
|
$item_normal = item_normal();
|
||||||
|
$item_normal_update = item_normal_update();
|
||||||
|
|
||||||
$sql_extra = public_permissions_sql($observer_hash);
|
$sql_extra = public_permissions_sql($observer_hash);
|
||||||
|
|
||||||
if(($update && $load) || ($checkjs->disabled())) {
|
if(($update && $load) || ($checkjs->disabled()) || ($module_format !== 'html')) {
|
||||||
|
|
||||||
$updateable = false;
|
|
||||||
|
|
||||||
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']),intval(\App::$pager['start']));
|
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']),intval(\App::$pager['start']));
|
||||||
|
|
||||||
if($load || ($checkjs->disabled())) {
|
if($load || ($checkjs->disabled()) || ($module_format !== 'html')) {
|
||||||
$r = null;
|
$r = null;
|
||||||
|
|
||||||
require_once('include/channel.php');
|
require_once('include/channel.php');
|
||||||
@@ -189,7 +222,7 @@ class Display extends \Zotlabs\Web\Controller {
|
|||||||
$sysid = $sys['channel_id'];
|
$sysid = $sys['channel_id'];
|
||||||
|
|
||||||
if(local_channel()) {
|
if(local_channel()) {
|
||||||
$r = q("SELECT * from item
|
$r = q("SELECT item.id as item_id from item
|
||||||
WHERE uid = %d
|
WHERE uid = %d
|
||||||
and mid = '%s'
|
and mid = '%s'
|
||||||
$item_normal
|
$item_normal
|
||||||
@@ -199,24 +232,22 @@ class Display extends \Zotlabs\Web\Controller {
|
|||||||
);
|
);
|
||||||
if($r) {
|
if($r) {
|
||||||
$updateable = true;
|
$updateable = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if($r === null) {
|
if($r === null) {
|
||||||
|
|
||||||
// in case somebody turned off public access to sys channel content using permissions
|
// in case somebody turned off public access to sys channel content using permissions
|
||||||
// make that content unsearchable by ensuring the owner_xchan can't match
|
// make that content unsearchable by ensuring the owner uid can't match
|
||||||
|
|
||||||
if(! perm_is_allowed($sysid,$observer_hash,'view_stream'))
|
if(! perm_is_allowed($sysid,$observer_hash,'view_stream'))
|
||||||
$sysid = 0;
|
$sysid = 0;
|
||||||
|
|
||||||
|
$r = q("SELECT item.id as item_id from item
|
||||||
$r = q("SELECT * from item
|
|
||||||
WHERE mid = '%s'
|
WHERE mid = '%s'
|
||||||
AND (((( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = ''
|
AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
|
||||||
AND `item`.`deny_gid` = '' AND item_private = 0 )
|
AND item.deny_gid = '' AND item_private = 0 )
|
||||||
and owner_xchan in ( " . stream_perms_xchans(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " ))
|
and uid in ( " . stream_perms_api_uids(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " ))
|
||||||
OR uid = %d )
|
OR uid = %d )
|
||||||
$sql_extra )
|
$sql_extra )
|
||||||
$item_normal
|
$item_normal
|
||||||
@@ -224,7 +255,6 @@ class Display extends \Zotlabs\Web\Controller {
|
|||||||
dbesc($target_item['parent_mid']),
|
dbesc($target_item['parent_mid']),
|
||||||
intval($sysid)
|
intval($sysid)
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,10 +267,10 @@ class Display extends \Zotlabs\Web\Controller {
|
|||||||
$sysid = $sys['channel_id'];
|
$sysid = $sys['channel_id'];
|
||||||
|
|
||||||
if(local_channel()) {
|
if(local_channel()) {
|
||||||
$r = q("SELECT * from item
|
$r = q("SELECT item.parent AS item_id from item
|
||||||
WHERE uid = %d
|
WHERE uid = %d
|
||||||
and mid = '%s'
|
and parent_mid = '%s'
|
||||||
$item_normal
|
$item_normal_update
|
||||||
$simple_update
|
$simple_update
|
||||||
limit 1",
|
limit 1",
|
||||||
intval(local_channel()),
|
intval(local_channel()),
|
||||||
@@ -250,20 +280,20 @@ class Display extends \Zotlabs\Web\Controller {
|
|||||||
$updateable = true;
|
$updateable = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($r === null) {
|
if($r === null) {
|
||||||
// in case somebody turned off public access to sys channel content using permissions
|
// in case somebody turned off public access to sys channel content using permissions
|
||||||
// make that content unsearchable by ensuring the owner_xchan can't match
|
// make that content unsearchable by ensuring the owner_xchan can't match
|
||||||
if(! perm_is_allowed($sysid,$observer_hash,'view_stream'))
|
if(! perm_is_allowed($sysid,$observer_hash,'view_stream'))
|
||||||
$sysid = 0;
|
$sysid = 0;
|
||||||
|
$r = q("SELECT item.parent AS item_id from item
|
||||||
$r = q("SELECT * from item
|
WHERE parent_mid = '%s'
|
||||||
WHERE mid = '%s'
|
AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
|
||||||
AND (((( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = ''
|
AND item.deny_gid = '' AND item_private = 0 )
|
||||||
AND `item`.`deny_gid` = '' AND item_private = 0 )
|
and uid in ( " . stream_perms_api_uids(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " ))
|
||||||
and owner_xchan in ( " . stream_perms_xchans(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " ))
|
|
||||||
OR uid = %d )
|
OR uid = %d )
|
||||||
$sql_extra )
|
$sql_extra )
|
||||||
$item_normal
|
$item_normal_update
|
||||||
$simple_update
|
$simple_update
|
||||||
limit 1",
|
limit 1",
|
||||||
dbesc($target_item['parent_mid']),
|
dbesc($target_item['parent_mid']),
|
||||||
@@ -278,53 +308,94 @@ class Display extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($r) {
|
if($r) {
|
||||||
|
$parents_str = ids_to_querystr($r,'item_id');
|
||||||
$parents_str = ids_to_querystr($r,'id');
|
|
||||||
if($parents_str) {
|
if($parents_str) {
|
||||||
|
$items = q("SELECT item.*, item.id AS item_id
|
||||||
$items = q("SELECT `item`.*, `item`.`id` AS `item_id`
|
FROM item
|
||||||
FROM `item`
|
|
||||||
WHERE parent in ( %s ) $item_normal ",
|
WHERE parent in ( %s ) $item_normal ",
|
||||||
dbesc($parents_str)
|
dbesc($parents_str)
|
||||||
);
|
);
|
||||||
|
|
||||||
xchan_query($items);
|
xchan_query($items);
|
||||||
$items = fetch_post_tags($items,true);
|
$items = fetch_post_tags($items,true);
|
||||||
$items = conv_sort($items,'created');
|
$items = conv_sort($items,'created');
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
$items = array();
|
$items = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($checkjs->disabled()) {
|
switch($module_format) {
|
||||||
$o .= conversation($a, $items, 'display', $update, 'traditional');
|
|
||||||
if ($items[0]['title'])
|
case 'html':
|
||||||
\App::$page['title'] = $items[0]['title'] . " - " . \App::$page['title'];
|
|
||||||
}
|
if ($checkjs->disabled()) {
|
||||||
else {
|
$o .= conversation($items, 'display', $update, 'traditional');
|
||||||
$o .= conversation($a, $items, 'display', $update, 'client');
|
if ($items[0]['title'])
|
||||||
|
\App::$page['title'] = $items[0]['title'] . " - " . \App::$page['title'];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$o .= conversation($items, 'display', $update, 'client');
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'atom':
|
||||||
|
|
||||||
|
$atom = replace_macros(get_markup_template('atom_feed.tpl'), array(
|
||||||
|
'$version' => xmlify(\Zotlabs\Lib\System::get_project_version()),
|
||||||
|
'$red' => xmlify(\Zotlabs\Lib\System::get_platform_name()),
|
||||||
|
'$feed_id' => xmlify(\App::$cmd),
|
||||||
|
'$feed_title' => xmlify(t('Article')),
|
||||||
|
'$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now', ATOM_TIME)),
|
||||||
|
'$author' => '',
|
||||||
|
'$owner' => '',
|
||||||
|
'$profile_page' => xmlify(z_root() . '/display/' . $target_item['mid']),
|
||||||
|
));
|
||||||
|
|
||||||
|
$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);
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
$atom .= '</feed>' . "\r\n";
|
||||||
|
|
||||||
|
header('Content-type: application/atom+xml');
|
||||||
|
echo $atom;
|
||||||
|
killme();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if($updateable) {
|
if($updateable) {
|
||||||
$x = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 AND uid = %d and parent = %d ",
|
$x = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 AND uid = %d and parent = %d ",
|
||||||
intval(local_channel()),
|
intval(local_channel()),
|
||||||
intval($r[0]['parent'])
|
intval($r[0]['item_id'])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$o .= '<div id="content-complete"></div>';
|
$o .= '<div id="content-complete"></div>';
|
||||||
|
|
||||||
return $o;
|
if((($update && $load) || $checkjs->disabled()) && (! $items)) {
|
||||||
|
|
||||||
|
$r = q("SELECT id, item_deleted FROM item WHERE mid = '%s' LIMIT 1",
|
||||||
/*
|
|
||||||
elseif((! $update) && (! {
|
|
||||||
|
|
||||||
$r = q("SELECT `id`, item_flags FROM `item` WHERE `id` = '%s' OR `mid` = '%s' LIMIT 1",
|
|
||||||
dbesc($item_hash),
|
|
||||||
dbesc($item_hash)
|
dbesc($item_hash)
|
||||||
);
|
);
|
||||||
|
|
||||||
if($r) {
|
if($r) {
|
||||||
if(intval($r[0]['item_deleted'])) {
|
if(intval($r[0]['item_deleted'])) {
|
||||||
notice( t('Item has been removed.') . EOL );
|
notice( t('Item has been removed.') . EOL );
|
||||||
@@ -338,8 +409,9 @@ class Display extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
return $o;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,10 +21,11 @@ class Dreport extends \Zotlabs\Web\Controller {
|
|||||||
$table = 'push';
|
$table = 'push';
|
||||||
$mid = ((argc() > 2) ? argv(2) : '');
|
$mid = ((argc() > 2) ? argv(2) : '');
|
||||||
if($mid) {
|
if($mid) {
|
||||||
$i = q("select id from item where mid = '%s' and author_xchan = '%s' and uid = %d",
|
$i = q("select id from item where mid = '%s' and uid = %d and ( author_xchan = '%s' or ( owner_xchan = '%s' and item_wall = 1 )) ",
|
||||||
dbesc($mid),
|
dbesc($mid),
|
||||||
|
intval($channel['channel_id']),
|
||||||
dbesc($channel['channel_hash']),
|
dbesc($channel['channel_hash']),
|
||||||
intval($channel['channel_id'])
|
dbesc($channel['channel_hash'])
|
||||||
);
|
);
|
||||||
if($i) {
|
if($i) {
|
||||||
\Zotlabs\Daemon\Master::Summon([ 'Notifier', 'edit_post', $i[0]['id'] ]);
|
\Zotlabs\Daemon\Master::Summon([ 'Notifier', 'edit_post', $i[0]['id'] ]);
|
||||||
@@ -47,8 +48,9 @@ class Dreport extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
switch($table) {
|
switch($table) {
|
||||||
case 'item':
|
case 'item':
|
||||||
$i = q("select id from item where mid = '%s' and author_xchan = '%s' ",
|
$i = q("select id from item where mid = '%s' and ( author_xchan = '%s' or ( owner_xchan = '%s' and item_wall = 1 )) ",
|
||||||
dbesc($mid),
|
dbesc($mid),
|
||||||
|
dbesc($channel['channel_hash']),
|
||||||
dbesc($channel['channel_hash'])
|
dbesc($channel['channel_hash'])
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ class Editblock extends \Zotlabs\Web\Controller {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$itm = q("SELECT * FROM `item` WHERE `id` = %d and uid = %s LIMIT 1",
|
$itm = q("SELECT * FROM item WHERE id = %d and uid = %s LIMIT 1",
|
||||||
intval($post_id),
|
intval($post_id),
|
||||||
intval($owner)
|
intval($owner)
|
||||||
);
|
);
|
||||||
@@ -98,6 +98,11 @@ class Editblock extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$mimetype = $itm[0]['mimetype'];
|
$mimetype = $itm[0]['mimetype'];
|
||||||
|
|
||||||
|
$content = $itm[0]['body'];
|
||||||
|
if($itm[0]['mimetype'] === 'text/markdown')
|
||||||
|
$content = \Zotlabs\Lib\MarkdownSoap::unescape($itm[0]['body']);
|
||||||
|
|
||||||
|
|
||||||
$rp = 'blocks/' . $channel['channel_address'];
|
$rp = 'blocks/' . $channel['channel_address'];
|
||||||
|
|
||||||
$x = array(
|
$x = array(
|
||||||
@@ -117,7 +122,7 @@ class Editblock extends \Zotlabs\Web\Controller {
|
|||||||
'ptyp' => $itm[0]['type'],
|
'ptyp' => $itm[0]['type'],
|
||||||
'mimeselect' => true,
|
'mimeselect' => true,
|
||||||
'mimetype' => $itm[0]['mimetype'],
|
'mimetype' => $itm[0]['mimetype'],
|
||||||
'body' => undo_post_tagging($itm[0]['body']),
|
'body' => undo_post_tagging($content),
|
||||||
'post_id' => $post_id,
|
'post_id' => $post_id,
|
||||||
'visitor' => true,
|
'visitor' => true,
|
||||||
'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'),
|
'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'),
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ class Editlayout extends \Zotlabs\Web\Controller {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$itm = q("SELECT * FROM `item` WHERE `id` = %d and uid = %s LIMIT 1",
|
$itm = q("SELECT * FROM item WHERE id = %d and uid = %s LIMIT 1",
|
||||||
intval($post_id),
|
intval($post_id),
|
||||||
intval($owner)
|
intval($owner)
|
||||||
);
|
);
|
||||||
@@ -119,6 +119,7 @@ class Editlayout extends \Zotlabs\Web\Controller {
|
|||||||
'hide_weblink' => true,
|
'hide_weblink' => true,
|
||||||
'hide_attach' => true,
|
'hide_attach' => true,
|
||||||
'hide_preview' => true,
|
'hide_preview' => true,
|
||||||
|
'disable_comments' => true,
|
||||||
'ptyp' => $itm[0]['obj_type'],
|
'ptyp' => $itm[0]['obj_type'],
|
||||||
'body' => undo_post_tagging($itm[0]['body']),
|
'body' => undo_post_tagging($itm[0]['body']),
|
||||||
'post_id' => $post_id,
|
'post_id' => $post_id,
|
||||||
|
|||||||
@@ -25,13 +25,21 @@ class Editpost extends \Zotlabs\Web\Controller {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$itm = q("SELECT * FROM `item` WHERE `id` = %d AND ( owner_xchan = '%s' OR author_xchan = '%s' ) LIMIT 1",
|
$itm = q("SELECT * FROM item WHERE id = %d AND ( owner_xchan = '%s' OR author_xchan = '%s' ) LIMIT 1",
|
||||||
intval($post_id),
|
intval($post_id),
|
||||||
dbesc(get_observer_hash()),
|
dbesc(get_observer_hash()),
|
||||||
dbesc(get_observer_hash())
|
dbesc(get_observer_hash())
|
||||||
);
|
);
|
||||||
|
|
||||||
if(! count($itm)) {
|
// don't allow web editing of potentially binary content (item_obscured = 1)
|
||||||
|
// @FIXME how do we do it instead?
|
||||||
|
|
||||||
|
if((! $itm) || intval($itm[0]['item_obscured'])) {
|
||||||
|
notice( t('Item is not editable') . EOL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($itm[0]['resource_type'] === 'photo' && $itm[0]['resource_id']) {
|
||||||
notice( t('Item is not editable') . EOL);
|
notice( t('Item is not editable') . EOL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -44,14 +52,6 @@ class Editpost extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$channel = \App::get_channel();
|
$channel = \App::get_channel();
|
||||||
|
|
||||||
if(intval($itm[0]['item_obscured'])) {
|
|
||||||
$key = get_config('system','prvkey');
|
|
||||||
if($itm[0]['title'])
|
|
||||||
$itm[0]['title'] = crypto_unencapsulate(json_decode($itm[0]['title'],true),$key);
|
|
||||||
if($itm[0]['body'])
|
|
||||||
$itm[0]['body'] = crypto_unencapsulate(json_decode($itm[0]['body'],true),$key);
|
|
||||||
}
|
|
||||||
|
|
||||||
$category = '';
|
$category = '';
|
||||||
$catsenabled = ((feature_enabled($owner_uid,'categories')) ? 'categories' : '');
|
$catsenabled = ((feature_enabled($owner_uid,'categories')) ? 'categories' : '');
|
||||||
|
|
||||||
@@ -78,6 +78,7 @@ class Editpost extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$x = array(
|
$x = array(
|
||||||
'nickname' => $channel['channel_address'],
|
'nickname' => $channel['channel_address'],
|
||||||
|
'item' => $itm[0],
|
||||||
'editor_autocomplete'=> true,
|
'editor_autocomplete'=> true,
|
||||||
'bbco_autocomplete'=> 'bbcode',
|
'bbco_autocomplete'=> 'bbcode',
|
||||||
'return_path' => $_SESSION['return_url'],
|
'return_path' => $_SESSION['return_url'],
|
||||||
@@ -85,6 +86,7 @@ class Editpost extends \Zotlabs\Web\Controller {
|
|||||||
'hide_voting' => true,
|
'hide_voting' => true,
|
||||||
'hide_future' => true,
|
'hide_future' => true,
|
||||||
'hide_location' => true,
|
'hide_location' => true,
|
||||||
|
'parent' => (($itm[0]['mid'] === $itm[0]['parent_mid']) ? 0 : $itm[0]['parent']),
|
||||||
'mimetype' => $itm[0]['mimetype'],
|
'mimetype' => $itm[0]['mimetype'],
|
||||||
'ptyp' => $itm[0]['obj_type'],
|
'ptyp' => $itm[0]['obj_type'],
|
||||||
'body' => htmlspecialchars_decode(undo_post_tagging($itm[0]['body']),ENT_COMPAT),
|
'body' => htmlspecialchars_decode(undo_post_tagging($itm[0]['body']),ENT_COMPAT),
|
||||||
|
|||||||
@@ -95,29 +95,24 @@ class Editwebpage extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$sql_extra = item_permissions_sql($owner);
|
$sql_extra = item_permissions_sql($owner);
|
||||||
|
|
||||||
$itm = q("SELECT * FROM `item` WHERE `id` = %d and uid = %s $sql_extra LIMIT 1",
|
$itm = q("SELECT * FROM item WHERE id = %d and uid = %s $sql_extra LIMIT 1",
|
||||||
intval($post_id),
|
intval($post_id),
|
||||||
intval($owner)
|
intval($owner)
|
||||||
);
|
);
|
||||||
|
|
||||||
if(! $itm) {
|
// don't allow web editing of potentially binary content (item_obscured = 1)
|
||||||
|
// @FIXME how do we do it instead?
|
||||||
|
|
||||||
|
if((! $itm) || intval($itm[0]['item_obscured'])) {
|
||||||
notice( t('Permission denied.') . EOL);
|
notice( t('Permission denied.') . EOL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(intval($itm[0]['item_obscured'])) {
|
|
||||||
$key = get_config('system','prvkey');
|
|
||||||
if($itm[0]['title'])
|
|
||||||
$itm[0]['title'] = crypto_unencapsulate(json_decode($itm[0]['title'],true),$key);
|
|
||||||
if($itm[0]['body'])
|
|
||||||
$itm[0]['body'] = crypto_unencapsulate(json_decode($itm[0]['body'],true),$key);
|
|
||||||
}
|
|
||||||
|
|
||||||
$item_id = q("select * from iconfig where cat = 'system' and k = 'WEBPAGE' and iid = %d limit 1",
|
$item_id = q("select * from iconfig where cat = 'system' and k = 'WEBPAGE' and iid = %d limit 1",
|
||||||
intval($itm[0]['id'])
|
intval($itm[0]['id'])
|
||||||
);
|
);
|
||||||
if($item_id)
|
if($item_id)
|
||||||
$page_title = $item_id[0]['v'];
|
$page_title = urldecode($item_id[0]['v']);
|
||||||
|
|
||||||
$mimetype = $itm[0]['mimetype'];
|
$mimetype = $itm[0]['mimetype'];
|
||||||
|
|
||||||
@@ -130,7 +125,9 @@ class Editwebpage extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$layout = $itm[0]['layout_mid'];
|
$layout = $itm[0]['layout_mid'];
|
||||||
|
|
||||||
$tpl = get_markup_template("jot.tpl");
|
$content = $itm[0]['body'];
|
||||||
|
if($itm[0]['mimetype'] === 'text/markdown')
|
||||||
|
$content = \Zotlabs\Lib\MarkdownSoap::unescape($itm[0]['body']);
|
||||||
|
|
||||||
$rp = 'webpages/' . $which;
|
$rp = 'webpages/' . $which;
|
||||||
|
|
||||||
@@ -147,7 +144,7 @@ class Editwebpage extends \Zotlabs\Web\Controller {
|
|||||||
'hide_location' => true,
|
'hide_location' => true,
|
||||||
'hide_voting' => true,
|
'hide_voting' => true,
|
||||||
'ptyp' => $itm[0]['type'],
|
'ptyp' => $itm[0]['type'],
|
||||||
'body' => undo_post_tagging($itm[0]['body']),
|
'body' => undo_post_tagging($content),
|
||||||
'post_id' => $post_id,
|
'post_id' => $post_id,
|
||||||
'visitor' => ($is_owner) ? true : false,
|
'visitor' => ($is_owner) ? true : false,
|
||||||
'acl' => populate_acl($itm[0],false,\Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')),
|
'acl' => populate_acl($itm[0],false,\Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')),
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user