Compare commits

..

298 Commits
5.2.2 ... 5.4

Author SHA1 Message Date
Mario
951e9c8c4f Merge branch '5.4RC' 2021-03-08 09:31:23 +00:00
Mario
89415e1731 release 5.4 2021-03-08 09:26:50 +00:00
Mario
f9ab020d1d Merge branch '5.4RC' of https://framagit.org/hubzilla/core into 5.4RC 2021-03-08 09:23:11 +00:00
Mario
1828ef6b68 changelog 2021-03-08 09:21:22 +00:00
Mario
4903d7b1e9 update sbom
(cherry picked from commit c67fdd9480)
2021-03-06 18:56:53 +01:00
Mario
c67fdd9480 update sbom 2021-03-06 17:55:24 +00:00
Mario
9b5979c83a fix varable name and more changelog
(cherry picked from commit 7460b1eecb)
2021-03-06 09:51:45 +01:00
Mario
7460b1eecb fix varable name and more changelog 2021-03-06 08:50:36 +00:00
Mario
7d03ff2043 sse_bs: if Enotify::format() returns an empty array do not add it to notifications (the item has probably been blocked)
(cherry picked from commit 1da494a2a5)
2021-03-05 09:26:30 +01:00
Mario
1da494a2a5 sse_bs: if Enotify::format() returns an empty array do not add it to notifications (the item has probably been blocked) 2021-03-05 08:15:41 +00:00
Mario
00ccafc90d more changelog
(cherry picked from commit e0c619519f)
2021-03-04 12:21:27 +01:00
Mario
b767e7ddec even more changelog
(cherry picked from commit 31da1362de)
2021-03-04 12:20:56 +01:00
Mario
31da1362de even more changelog 2021-03-04 11:19:23 +00:00
Mario
e0c619519f more changelog 2021-03-04 10:13:48 +00:00
Mario
f1f1e56f87 revert revert isset()
(cherry picked from commit 33e4b6db72)
2021-03-04 10:53:29 +01:00
Mario
33e4b6db72 revert revert isset() 2021-03-04 09:52:54 +00:00
Mario
1eae7b92d1 revert isset() 2021-03-04 09:50:03 +00:00
Mario
5b7a10401f version 5.4RC2 2021-03-04 09:48:19 +00:00
Mario
1b8c5b9727 changelog
(cherry picked from commit 548936c6ca)
2021-03-04 10:46:56 +01:00
Mario
548936c6ca changelog 2021-03-04 09:45:51 +00:00
Max Kostikov
7beb500fb4 Check if custom CSP is set 2021-03-04 08:36:20 +00:00
Mario
9c110e7b9b revert isset 2021-03-04 08:20:16 +00:00
Mario
129f8107d3 merge conflict 2021-03-04 08:17:07 +00:00
Mario
cb01996039 Merge branch 'dev' into 'dev'
Fix frame-src CSP error on video embedding

See merge request hubzilla/core!1918
2021-03-04 08:05:27 +00:00
Max Kostikov
33b738d00b Fix frame-src CSP error on video embedding 2021-03-04 08:05:26 +00:00
Mario
c2dc3e8dec set the default collection acl if indicated so by the role permissions but always set the created friends group as channel_default_group when creating a new channel
(cherry picked from commit 9389abdb75)
2021-03-03 14:12:42 +01:00
Mario
7d1599f9b0 group_add(): return hash if success
(cherry picked from commit f8f15f526f)
2021-03-03 14:11:54 +01:00
Mario
3d264f5a55 php8: fix warnings during install procedure
(cherry picked from commit 48bae9d421)
2021-03-03 14:11:29 +01:00
Mario
9389abdb75 set the default collection acl if indicated so by the role permissions but always set the created friends group as channel_default_group when creating a new channel 2021-03-03 14:09:17 +01:00
Mario
f8f15f526f group_add(): return hash if success 2021-03-03 13:44:38 +01:00
Mario
48bae9d421 php8: fix warnings during install procedure 2021-03-03 13:39:41 +01:00
Mario
55b4eb7b22 version 5.4RC1 2021-02-26 10:15:56 +00:00
Mario
fbb1d6aa41 Merge branch 'dev' into 'dev'
Do not overwrite HTTP schema for Youtube on embedding

See merge request hubzilla/core!1917
2021-02-26 09:03:58 +00:00
Max Kostikov
5440a65607 Do not overwrite HTTP schema for Youtube on embedding 2021-02-25 16:35:19 +00:00
Mario
36c9f9abff Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-02-25 15:43:13 +00:00
Mario
8295ccdda7 a possible fix for #1518 2021-02-25 15:43:01 +00:00
Mario
65892ba555 Merge branch 'dev' into 'dev'
small adjustment

See merge request hubzilla/core!1915
2021-02-25 15:10:41 +00:00
Zot
78938df133 small adjustment 2021-02-25 15:10:41 +00:00
Mario
ac6dec91f1 Merge branch 'dev' into 'dev'
Enable multimedia in podcasts

See merge request hubzilla/core!1916
2021-02-25 15:09:31 +00:00
Mario
373612a046 do not poll feeds if feed_contacts are not allowed 2021-02-25 15:05:49 +00:00
Mario
c1afa306c9 fix logic 2021-02-25 14:15:13 +00:00
Mario
65a20a780d bump version 2021-02-25 12:56:57 +00:00
Mario
b29e121113 replace sticky_kit with a simpler homwgrown solution (still a bit raw) and slightly change the way we load new content so that people with a long aside column do not have to scroll all the way to the bottom for loading the next page 2021-02-25 12:55:19 +00:00
Michal Klodner
f45ebfa223 - Enable enclosures in Atom/RSS (podcasts)
- Remove checking of audio/video URLs for pattern at the end
2021-02-24 21:03:05 +00:00
Mario
a033c439f3 zap compat export fixes 2021-02-24 10:19:15 +00:00
Mario
66e4bc327f Merge branch 'dev' into 'dev'
export compatibility from hubzilla to zap

See merge request hubzilla/core!1910
2021-02-24 08:35:30 +00:00
Zot
df362e4f81 export compatibility from hubzilla to zap 2021-02-24 08:35:29 +00:00
Max Kostikov
82ee980172 Merge branch 'dev' into 'dev'
Update Russian translation

See merge request hubzilla/core!1912
2021-02-23 12:33:17 +00:00
Max Kostikov
463a8d338e Update hmessages.po 2021-02-23 12:29:02 +00:00
Max Kostikov
d074bb65da Update Russian hstrings.php 2021-02-23 12:26:20 +00:00
Max Kostikov
b7c411470b Update Russian hmessages.po 2021-02-23 12:24:59 +00:00
Max Kostikov
e09e6c5524 Missprint 2021-02-23 12:22:19 +00:00
Mario
fa73c8d15e bump dev version to 5.5 2021-02-23 10:57:37 +00:00
Mario
6060ca127b composer dump-autoload 2021-02-23 10:54:27 +00:00
Mario
ca4e0351cf update strings 2021-02-23 10:52:38 +00:00
Mario
f3be2ecc9d version 5.4RC 2021-02-23 10:48:47 +00:00
Mario
135305d975 Merge branch 'dev' into 'dev'
Rename photo storage type system variable

See merge request hubzilla/core!1911
2021-02-23 10:02:16 +00:00
Max Kostikov
34aa8ba3cc Rename photo storage type system variable 2021-02-23 10:02:15 +00:00
Mario
28fe91dfa7 Merge branch 'dev' of https://codeberg.org/hubzilla/hubzilla into dev 2021-02-23 09:53:12 +00:00
mjfriaza
883b519714 Update Spanish version 2021-02-23 09:52:24 +00:00
hubzilla
9dae590c64 Merge pull request 'Update Spanish version' (#4) from mjfriaza/hubzilla:dev into dev
Reviewed-on: https://codeberg.org/hubzilla/hubzilla/pulls/4
2021-02-23 10:49:21 +01:00
Mario
d4159e8333 streamline iconf names and make sure to save the correct data 2021-02-22 10:32:05 +00:00
Max Kostikov
90d04082a1 Fix missprint 2021-02-21 14:13:46 +01:00
Max Kostikov
a84c7271f2 Formatting 2021-02-20 14:49:31 +01:00
Max Kostikov
f46ddf2273 Bump DB version 2021-02-20 14:47:50 +01:00
Max Kostikov
b401869d30 Rename photo storage type system variable 2021-02-20 14:47:14 +01:00
Max Kostikov
cc55716879 Merge branch 'dev' into 'dev'
Dev sync

See merge request kostikov/core!1
2021-02-20 13:39:54 +00:00
Mario
ddad4f604b provide raw base64 encoded crypto 2021-02-19 17:37:53 +00:00
Mario
dc553ab309 summary edit actions 2021-02-19 10:24:20 +00:00
Mario
a2d170385b deprecate summary tag in favour of a separate input field 2021-02-19 10:11:24 +00:00
Mario
a275726988 update site once a day 2021-02-19 09:26:39 +00:00
Mario
863d4d83a1 fix recursive shares 2021-02-19 07:41:29 +00:00
Mario
d50381c9c6 fix summary regex after recent bbcode chane 2021-02-18 20:36:56 +00:00
Mario
c9bbe1a735 adjust error reporting for php8 to not report warnings - they are too many 2021-02-18 20:04:34 +00:00
Mario
18b9d1efd8 this setting is probably not required anymoreà 2021-02-18 20:00:20 +00:00
Mario
85f1845d15 fix usage of null coalescing operator 2021-02-18 19:46:26 +00:00
Mario
c34fc416a2 php8 warnings 2021-02-18 19:32:45 +00:00
Mario
7794ee5a88 php8 warnings 2021-02-18 13:32:02 +00:00
Mario
65068479b9 php8 warnings 2021-02-18 13:29:15 +00:00
mjfriaza
655ae9d1cd Merge branch 'dev' into dev 2021-02-18 13:28:05 +01:00
mjfriaza
76163fc37b Update Spanish version 2021-02-18 13:22:57 +01:00
Mario
92f3c5ae21 backward compatibility with recent crypto changes 2021-02-18 09:36:22 +00:00
Mario
c3ec5d4d6a do not try to fetch legacy zot zotfeed - they will not return anything useful 2021-02-17 20:16:20 +00:00
Mario
0aeb4d6fb5 php8: fix mod mail if there are no messages 2021-02-17 19:41:27 +00:00
Mario
edd4ac791f remove logging 2021-02-17 18:15:09 +00:00
Mario
27577824de fix php8 issue in include/oembed and unencapsulate for zot_refresh() 2021-02-17 18:14:29 +00:00
Mario Vavti
281b2261af reduce loglevel until the most glaring php8 issues will be resolved 2021-02-16 14:35:01 +01:00
Mario
3eaf0b7f23 php8 another fix 2021-02-16 12:56:34 +00:00
Mario
76ad2c0fa4 php8 fix 2021-02-16 12:41:27 +00:00
Mario
efaadf54d3 make sure we do not try to update columns which do not exist 2021-02-16 09:21:55 +00:00
Mario
6f71c6d950 fix detection of multiline codeblocks after recent change to bbcode() 2021-02-15 19:18:49 +00:00
Mario
ad0b0364b8 missing files 2021-02-15 18:42:21 +00:00
Mario
e8c2e17bc9 compser update twbs/bootstrap 2021-02-15 18:41:44 +00:00
Mario
6fae291cc8 missing file 2021-02-15 18:40:00 +00:00
Mario
1e48be7ab7 compser update symfony/polyfill-ctype 2021-02-15 18:39:11 +00:00
Mario
0cd4c34101 compser update sabre/dav /vobject 2021-02-15 18:35:40 +00:00
Mario
02401ea9fd composer update ramsey/collection 2021-02-15 18:29:24 +00:00
Mario
18c8f1b903 composer update brick/math 2021-02-15 18:27:20 +00:00
Mario
4171a0136a revert debug code 2021-02-15 18:25:04 +00:00
Mario
ba29a6ce4d composer update smarty 2021-02-15 18:23:26 +00:00
Mario
d72a096fa5 fix preview generating duplicate IDs 2021-02-15 10:15:57 +00:00
Mario
ed99392001 move substitution of new lines with <br> to the end of bbcode(). This will fix issue #1512. 2021-02-15 08:20:42 +00:00
Mario
50e9a12ca5 Merge branch 'fix-public-permissions-in-display' into 'dev'
FIX: Display urls won't show to permitted remote observers

See merge request hubzilla/core!1909
2021-02-14 16:16:26 +00:00
M. Dent
d6b259bb27 FIX: Display urls won't show to permitted remote observers 2021-02-14 17:16:25 +01:00
Mario
5e8e6dc458 changelog 2021-02-13 20:20:46 +00:00
Mario
22e0175ab7 fix ping_site() issue 2021-02-13 19:30:15 +00:00
Mario
0ffb09aa40 onepoll: add date_begin argument to poll url 2021-02-11 21:05:45 +00:00
Mario
8054d7ad66 remove logging 2021-02-11 21:01:16 +00:00
Mario
d3e70acacd make encode_item_collection() deal with extra query args 2021-02-11 21:00:10 +00:00
Mario
6f520cadb7 actor will be stored in the next step decode_note() 2021-02-11 11:13:06 +00:00
Mario
becdd64257 update 1242 2021-02-10 20:59:30 +00:00
Mario
464a0634d6 use (un)obscurify 2021-02-10 20:40:28 +00:00
Mario
391db61629 revert z_(un)obscure() until (un)obscurify() will be implemented and a update will take care of the data in db 2021-02-10 19:27:00 +00:00
Mario
e6450acc03 version 2021-02-09 19:13:32 +00:00
Mario
e75ae17662 whitespace 2021-02-09 14:09:26 +00:00
Mario
3b3c93f9b3 undo accidental revert in last commit 2021-02-09 14:05:00 +00:00
Mario
b4693870ba port Lib/Crypto from zap 2021-02-09 13:50:03 +00:00
Mario
5aee2f172e restructure keyutiÃls tests 2021-02-08 20:05:05 +00:00
Mario
6b8b42fb21 fix line separators 2021-02-08 16:16:56 +00:00
Mario
320e95aaae composer 2021-02-08 16:08:31 +00:00
Mario
1bcf84f275 fix test 2021-02-08 16:04:56 +00:00
Mario
a8e0bd1f12 keyutils tests 2021-02-08 13:37:48 +00:00
Mario
eb05e5a205 revert include/crypto to its previous state for reference - we are now using Lib/Keyutils for key conversion 2021-02-08 10:55:35 +00:00
Mario
d316d9436b mixed up variables 2021-02-08 10:17:05 +00:00
Max Kostikov
b2e4a4b2b1 Merge branch 'dev' into 'dev'
Use datetime interval in public tag cloud query to support queueworker deduplication

See merge request hubzilla/core!1908
2021-02-06 10:41:33 +00:00
Max Kostikov
e1d622c49f Use datetime interval in public tag cloud query to support queueworker deduplication 2021-02-06 11:36:22 +01:00
Max Kostikov
8bb77bcfd6 Fix new Imagemagick object 2021-02-05 15:32:09 +01:00
Mario Vavti
a9070382e7 bump version 2021-02-04 22:26:29 +01:00
Mario Vavti
9e22641425 add Lib/Keyutils 2021-02-04 22:20:55 +01:00
Mario Vavti
19007dd8eb move key conversion to separate lib 2021-02-04 22:16:48 +01:00
Mario Vavti
03e1f5f8a4 remove unused function 2021-02-04 21:49:25 +01:00
Mario Vavti
6bb73e14b6 key conversion functions cleanup 2021-02-04 21:31:37 +01:00
Mario Vavti
41f84dabcc use phpseclib for key transformations 2021-02-04 21:21:22 +01:00
Mario Vavti
cd79d12e5b phpseclib missing files 2021-02-04 21:05:17 +01:00
Mario Vavti
a6162d3134 downgrade phpseclib to version 2 2021-02-04 21:01:25 +01:00
Mario Vavti
34b28cd8d3 fix wrong operand 2021-02-03 10:22:34 +01:00
Mario Vavti
9a170791e4 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-02-03 10:12:02 +01:00
Mario
44b559fb1d Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-02-02 12:58:01 +00:00
Mario
2167d12b3f composer add phpseclib 2021-02-02 12:57:46 +00:00
Mario Vavti
e312c381d8 import_xchan() $arr photo structure has changed 2021-02-02 11:47:38 +01:00
Mario Vavti
af6f7f244e Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-02-02 10:58:28 +01:00
Mario Vavti
f3f49cf80f fix php8 issues 2021-02-02 10:58:10 +01:00
Mario
08c9152abd fix getting mimetype via getimagesize() and do not default to image/jpeg yet if it could not be found 2021-02-01 22:58:55 +00:00
Mario
70fa7ad8d0 too many arguments 2021-02-01 20:52:35 +00:00
Mario
cd081ac077 remove unused/commented out code 2021-02-01 14:32:28 +00:00
Mario
197338a727 remove logging 2021-02-01 09:30:22 +00:00
Mario
61e7791d31 Merge branch 'dev' into 'dev'
Better profile photo fetch processing

See merge request hubzilla/core!1906
2021-02-01 08:53:10 +00:00
Max Kostikov
de91d2c804 Better profile photo fetch processing 2021-02-01 09:53:09 +01:00
Mario
11f5550512 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-01-31 20:37:29 +00:00
Mario
d99611e7dd add fetch_provider hook 2021-01-31 20:37:16 +00:00
Max Kostikov
c0933c90e8 Fix copypaste 2021-01-31 15:26:55 +01:00
Max Kostikov
21b3ba38e7 Fix polish plurals function 2021-01-31 12:05:02 +01:00
Max Kostikov
bac87a8aec Fix polish plurals function 2021-01-31 12:04:26 +01:00
Max Kostikov
a235917d48 Merge branch 'translation-pl' into 'dev'
New fixes & translations

See merge request hubzilla/core!1907
2021-01-30 18:40:37 +00:00
Andrzej Budziński
d2eb10d7ff Fixes (!1905):
- view/pl/hmessages.po
- view/pl/hstrings.php
2021-01-30 18:42:47 +01:00
Andrzej Budziński
89bf71b227 New fixes & translatosns:
- doc/pl/tutorials/*: 100%
- doc/pl/checking_account_guota_usage.bb: 100%
- doc/pl/member/member_guide.bb: fixes
- doc/pl/admin/hub_snapshots.md: fixes
- view/pl/hmessage.po: fixes
- view/pl/hstrings.po: fixes to generated code
2021-01-30 14:03:39 +01:00
Mario
7686b48723 code format only 2021-01-29 07:36:56 +00:00
Mario
840dbbe8ba code format only 2021-01-28 15:50:34 +00:00
Mario
ab4863a2e0 AS discovery for mod profile 2021-01-28 15:44:57 +00:00
Mario
8c2442eca5 AS channel discovery with custom access header 2021-01-28 14:57:37 +00:00
Mario Vavti
8b78e18fb8 keep file permissions in util folder at 755 2021-01-27 11:56:58 +01:00
Mario
66640a206e fix issue in view/pl/hstrings.php 2021-01-27 10:35:17 +00:00
Mario
15c90371e0 Merge branch 'customjotheaders' into 'dev'
Custom "headers" in item creation form.

See merge request hubzilla/core!1901
2021-01-27 10:25:26 +00:00
M. Dent
00fe7bb1bb Custom "headers" in item creation form. 2021-01-27 11:25:26 +01:00
Mario
a2728167bc Merge branch 'dev' into 'dev'
Rebuild public tags cloud not often than once per 5 mins.

See merge request hubzilla/core!1900
2021-01-27 10:23:59 +00:00
Max Kostikov
6326605c99 Revert "Fix directory permissions on create"
This reverts commit 85c5e1178a57865ad977c260725da2839ebb4d98
2021-01-27 11:23:59 +01:00
Mario
7cd4f60922 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-01-27 10:15:37 +00:00
Mario
af719fea40 fix file permissions. 755 for dirs, 644 for files 2021-01-27 10:15:26 +00:00
Max Kostikov
0af458768f Fix wrong redbasic theme permissions 2021-01-27 12:14:30 +02:00
Mario
3ba46873ba Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-01-27 09:59:40 +00:00
Mario
f4cc91f0f5 Merge branch 'translation-pl' into 'dev'
Translation pl

Polish translations (used on hub.hubzilla.pl)
- view/pl: 100%
- doc/pl: ~40%
- doc/context/pl: 100%
- doc/macros/pl: 100%

See merge request hubzilla/core!1902
2021-01-27 09:57:30 +00:00
Andrzej S. Budziński
f813671b67 Merge branch 'translation-pl' into 'dev'
Translation pl

Polish translations (used on hub.hubzilla.pl)
- view/pl: 100%
- doc/pl: ~40%
- doc/context/pl: 100%
- doc/macros/pl: 100%

See merge request hubzilla/core!1902
2021-01-27 10:57:30 +01:00
Mario
74f8f2d956 thread listener improvements 2021-01-26 12:11:01 +00:00
Mario
f0ee4c3cef port fix from zap: catch a complex edge case where some public stream comments were not being delivered and should have been 2021-01-26 10:35:24 +00:00
Mario
6878445319 use mail envelope instead of lock icon for direct messages 2021-01-26 10:29:03 +00:00
Mario
de34dac6cc port youtube embed fix from zap 2021-01-26 09:56:28 +00:00
Mario
1c8d298f3f Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-01-26 09:21:21 +00:00
Mario
777af6e7ad Libzot::fetch_conversation() fixes 2021-01-26 09:21:16 +00:00
Mario Vavti
82dbdf7c70 fix issues in Activity::encode_item_collection() after recent changes 2021-01-26 10:07:41 +01:00
Mario Vavti
4cf05891d7 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-01-25 21:52:29 +01:00
Mario Vavti
d4198223bc invoke channel discovery by hash instead of address and add thread listeners only if we also send them the post 2021-01-25 21:52:17 +01:00
Mario
1b4bbcc891 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-01-25 20:28:03 +00:00
Mario
0e9d99c603 expose manual public item import from searchbar, set commen_policy in Activity::store() to what we get if we get something otherwise default to authenticated, comments by the owner have the relay flag set and therefor $perm will be not be set to post_comments - always check if we own the parent in lib/libzot (not only if $perm = send_stream) if otherwise not allowed 2021-01-25 20:27:50 +00:00
Charlie Root
3ed444b4b4 Run storageconv from web server user 2021-01-25 18:35:28 +02:00
Mario
77793e17c0 Merge branch 'dev' into 'dev'
Add support filesystem storage for xchan profile photos

See merge request hubzilla/core!1898
2021-01-24 20:03:35 +00:00
Max Kostikov
552796286e Add support filesystem storage for xchan profile photos 2021-01-24 21:03:34 +01:00
Mario
e486442eb1 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-01-24 19:55:50 +00:00
Mario
2035828042 revert externals/zotfeed functionality due to scaling issues. Save zotfeed consumers that are not our contacts in thread listeners 2021-01-24 19:55:29 +00:00
Mario
4fbedb6750 extra check for item_private in fetch_and_store_parents() 2021-01-24 15:00:01 +00:00
Max Kostikov
6b0c61ac6b Merge branch 'dev' into 'dev'
Variable typo

See merge request hubzilla/core!1897
2021-01-23 20:57:47 +00:00
Max Kostikov
0a13c794ab Variable typo 2021-01-23 21:55:50 +01:00
Max Kostikov
a53f286467 Merge branch 'dev' into 'dev'
Don't fetch profile photos from own hub

See merge request hubzilla/core!1896
2021-01-23 20:47:06 +00:00
Max Kostikov
e4ed5ed264 Do not store multiple profile images thumbnails 2021-01-23 21:45:20 +01:00
Max Kostikov
74441f2f00 Don't fetch profile photos from own hub 2021-01-23 21:38:03 +01:00
Max Kostikov
007de17702 Merge branch 'dev' into 'dev'
Bump DB update version

See merge request hubzilla/core!1895
2021-01-23 15:24:44 +00:00
Max Kostikov
ecf2e4e0ee Bump DB update version 2021-01-23 16:22:29 +01:00
Max Kostikov
03910453a9 Merge branch 'dev' into 'dev'
Dev sync

See merge request kostikov/core!3
2021-01-23 13:07:09 +00:00
Max Kostikov
30962dadbf Merge branch 'dev' into 'dev'
# Conflicts:
#   Zotlabs/Daemon/Cache_query.php
#   include/contact_widgets.php
#   include/taxonomy.php
2021-01-23 14:04:42 +01:00
Max Kostikov
33951dc1e4 Remove duplicated profile photos 2021-01-23 14:00:38 +01:00
Max Kostikov
893847c649 Fix duplicate profile photos creation for clones 2021-01-23 13:58:05 +01:00
Mario
fbbc53838c fix ramsey/uuid exception 2021-01-23 12:35:02 +00:00
Max Kostikov
7bc0340106 Encode SQL query array 2021-01-22 15:39:48 +01:00
Max Kostikov
bfb9f10234 Encode SQL query array 2021-01-22 15:38:40 +01:00
Max Kostikov
3f34c73f09 Decode SQL query array 2021-01-22 15:37:49 +01:00
Mario
92f420f77c cleanup 2021-01-22 10:42:58 +00:00
Mario Vavti
78716c42d6 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-01-22 11:16:43 +01:00
Mario Vavti
e6aed4fb8e implement externals via zot6 and zotfeed - part 2 2021-01-22 11:12:39 +01:00
Mario
064effe5fd fix encode_item_collection() 2021-01-22 10:11:27 +00:00
Mario
93ac3c985f implement externals via zot6 and zotfeed - part 1 2021-01-22 10:06:50 +00:00
Mario
fe97b63e0b Merge branch 'dev' into 'dev'
Implement SQL query background caching

See merge request hubzilla/core!1894
2021-01-21 09:08:53 +01:00
Max Kostikov
3836e75c89 Implement SQL query background caching 2021-01-21 09:08:53 +01:00
Max Kostikov
28ae78c579 Higher log level 2021-01-21 08:16:15 +01:00
Mario
bdd6d878f1 cleanup lib/libsync 2021-01-21 07:09:19 +00:00
Max Kostikov
8134e9cae0 Process channel categories list in background 2021-01-20 22:28:38 +01:00
Max Kostikov
70ee41f252 Process public tags cloud in background 2021-01-20 22:24:00 +01:00
Max Kostikov
491dffd9b7 Implement SQL query background caching 2021-01-20 22:18:27 +01:00
Max Kostikov
ad42890a0b Swap key and cat for running pid tracking 2021-01-20 22:15:01 +01:00
Mario
5a971a3731 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-01-20 21:14:29 +00:00
Max Kostikov
ab4455c54c Merge branch 'dev' into 'dev'
Dev sync

See merge request kostikov/core!2
2021-01-20 22:12:15 +01:00
Max Kostikov
6cca06f641 Merge branch 'dev' into 'dev'
Use Zot6 on pinned content sync between clones

See merge request hubzilla/core!1893
2021-01-20 22:09:21 +01:00
Mario
c5d37a0831 remove logging 2021-01-20 20:43:51 +00:00
Mario
57645386b2 looks like we get arrays or json strings here for some reason 2021-01-20 20:42:59 +00:00
Mario
b242347fa1 onepoll via zot6 to /zotfeed which implements an outbox 2021-01-20 20:17:50 +00:00
Max Kostikov
15b2aa660b Update Pin.php 2021-01-20 13:53:09 +01:00
Max Kostikov
4da4f2367f Use Zot6 on pinned content sync between clones 2021-01-20 13:18:48 +01:00
Max Kostikov
9612a69a64 Merge branch 'dev' into 'dev'
Dev sync

See merge request kostikov/core!1
2021-01-20 13:15:40 +01:00
Mario
4e9d8e1a83 fix abandon days setting for onepoll 2021-01-18 21:10:59 +00:00
Mario
6083bfea2f lib/activity cleanup and remove unused code - requires addon update 2021-01-18 20:39:23 +00:00
Mario
08264f8d11 more cleanup daemon/thumbnail 2021-01-18 14:35:40 +00:00
Mario
8b93136773 more cleanup daemon/queue 2021-01-18 14:35:00 +00:00
Mario
c7a82a6a84 more cleanup daemon/poller 2021-01-18 14:33:19 +00:00
Mario
ef67e18161 more cleanup daemon/onepoll 2021-01-18 14:29:01 +00:00
Mario
08d2fb4ed4 more cleanup daemon/onedirsync 2021-01-18 14:24:44 +00:00
Mario
836637621d more cleanup daemon/notifier 2021-01-18 14:23:23 +00:00
Mario
6e7a2d0d96 more cleanup daemon/master 2021-01-18 14:13:58 +00:00
Mario
101005f3d2 more cleanup daemon/importfile 2021-01-18 14:11:29 +00:00
Mario
8f88543478 more cleanup daemon/importdoc 2021-01-18 14:10:38 +00:00
Mario
f1ac5bb667 more cleanup daemon/gprobe 2021-01-18 14:09:48 +00:00
Mario
8e5df2dd22 more cleanup daemon/externals 2021-01-18 14:08:31 +00:00
Mario
441525750f more cleanup daemon/expire 2021-01-18 14:02:37 +00:00
Mario
9acfc44ac9 cleanup daemon/expire 2021-01-18 14:00:21 +00:00
Mario
d5bd09b983 cleanup daemon/deliver_hooks, daemon/directory 2021-01-18 13:49:58 +00:00
Mario
45350179b4 cleanup daemon/deliver 2021-01-18 13:41:34 +00:00
Mario
d0f3d2b2a5 cleanup daemon/curlauth 2021-01-18 13:40:01 +00:00
Mario
3742fe80fc only var can be passed by reference, cleanup 2021-01-18 13:37:54 +00:00
Mario
e191966e69 only var can be passed by reference, cleanup 2021-01-18 13:36:47 +00:00
Mario
2c8e122008 cleanup daemon/checksites 2021-01-18 13:29:48 +00:00
Mario
2729f466d5 cleanup 2021-01-18 13:23:29 +00:00
Mario
f4b71fbec1 cleanup 2021-01-18 13:21:13 +00:00
Mario
6695225492 cleanup 2021-01-18 13:08:13 +00:00
Mario
4f74d1d877 cleanup 2021-01-18 13:00:39 +00:00
Mario
bee84e9b00 whitespace 2021-01-18 12:56:07 +00:00
Mario
faaa2d4472 $match should be array 2021-01-18 11:21:37 +00:00
Mario
917c6caa14 force arg is not used anymore in drop_item_lolevel() 2021-01-18 08:46:37 +00:00
Mario
cd59c67c67 fix undefined variable 2021-01-18 08:43:08 +00:00
Mario
37f1b774b7 missing import 2021-01-17 15:19:00 +00:00
Mario
828636847e get_item_elements() check against zot6 2021-01-17 14:13:31 +00:00
Mario
06b5f71075 port util/connect to Lib/Connect 2021-01-17 14:06:35 +00:00
Mario
8d37a4239a mark_orphan_hubsxchans() check against zot6 2021-01-17 13:56:23 +00:00
Mario
a925b08e80 get_bookmark_link() check against zot6 2021-01-17 13:52:55 +00:00
Mario
46aefd8883 fix fetch vcard menu entry for zot6 connections 2021-01-17 13:41:27 +00:00
Mario
38a48de826 app_render() check against zot6 2021-01-17 13:35:13 +00:00
Mario
485a232ae6 changelog 2021-01-16 09:31:51 +00:00
Mario
0d544e2294 wrong logic 2021-01-16 09:17:45 +00:00
Mario
395b427787 cleanup mod like 2021-01-16 09:09:54 +00:00
Mario
4d63c37c38 HTTPSig::get_zotfinger_key() only takes the id arg 2021-01-15 21:23:14 +00:00
Mario
a2776ade81 exec is marked deprecated 2021-01-15 21:19:07 +00:00
Mario
5f5b3f3d4c remove unused global var 2021-01-15 21:02:13 +00:00
Mario
60b76c53fc fix undefined var 2021-01-15 20:58:31 +00:00
Mario
e55ea8b126 undefined variable $filename 2021-01-15 20:52:18 +00:00
Mario
889581e35b wrong variable name 2021-01-15 20:36:48 +00:00
Mario
f7222d43c9 only vars can be passed by reference 2021-01-15 20:26:22 +00:00
Mario
1e474c9689 unused variable and missing break statement 2021-01-15 20:14:48 +00:00
Mario
50fb658776 fix undefined variable 2021-01-15 20:10:44 +00:00
Mario
dde0f3a403 formatting 2021-01-15 20:03:49 +00:00
Mario
597d7bd532 formatting 2021-01-15 20:02:03 +00:00
Mario
aa27f93a9c cleanup unused/undefined variables 2021-01-15 20:00:47 +00:00
Mario
ae4b5231bb fix undefined vars in mod cal 2021-01-15 19:37:47 +00:00
Mario
28ef42a424 make functions public static 2021-01-15 19:31:50 +00:00
Mario
70233ea903 remove redundant import and add ext-zip to composer 2021-01-15 19:28:15 +00:00
Mario
63c15c2c8d remove redundant import 2021-01-15 19:11:14 +00:00
Mario
3e1f387b2b Receiver::run() does not take an argument 2021-01-15 19:09:27 +00:00
Mario
77c777512c fix issue in unused function 2021-01-15 19:04:20 +00:00
Mario
02059fb663 bump composer php version 2021-01-15 19:00:04 +00:00
Mario
3205429d24 more wiki issues 2021-01-15 18:57:56 +00:00
Mario
aa8eb9522f wiki issues 2021-01-15 18:55:07 +00:00
Mario
5030157246 argument must be of type boolean 2021-01-15 18:39:07 +00:00
Mario
a3bc9251bf $msg must be array 2021-01-15 18:37:08 +00:00
Mario
5a325cfa7b remove unused variables 2021-01-15 17:21:33 +00:00
Mario
583d3b5580 whitespace 2021-01-15 15:49:22 +00:00
Mario
43e3663721 fix wrong/undefined variables and add sleep interval to notifier calls 2021-01-15 15:48:17 +00:00
Mario
9f8a512eb5 only var can be passed by reference 2021-01-15 15:07:54 +00:00
Mario
3bcb322156 also check for zot6 2021-01-15 15:06:07 +00:00
Mario
1e645cabd4 style fixes 2021-01-15 15:00:53 +00:00
Mario
ee82763d45 add ext-json to composer 2021-01-15 14:47:26 +00:00
Mario
42812078c5 make attach_upgrade() catch entries where only display_path is missing 2021-01-15 10:00:13 +00:00
Mario
83f0c3d1dd some work to fix r_preview in list mode 2021-01-14 14:28:35 +00:00
Mario
e5a70744c0 update changelog
(cherry picked from commit 299c4bda1b)
2021-01-13 11:35:06 +01:00
1204 changed files with 125921 additions and 71421 deletions

0
.gitignore vendored Executable file → Normal file
View File

0
.homeinstall/zotserver-setup.sh Executable file → Normal file
View File

0
.openshift/action_hooks/deploy Executable file → Normal file
View File

0
.openshift/cron/weekly/chronograph Executable file → Normal file
View File

View File

@@ -1,11 +1,82 @@
Hubzilla 5.4 (2021-03-08)
- Add new connections to privacy group independend from the default privacy group settings
- group_add() return group hash to save a lookup
- Do not poll feeds if feed contacts setting is disabled
- Deprecate sticky_kit library in favor of CSS position sticky solution
- Trigger endless scroll loading at the end of content instead of end of window height
- Implement experimental zap export compatibility
- Deprecate the [summary] tag in favor of a separate input field for the summary
- Adjust error reporting for PHP8
- Rely on php.ini default value for pcre.backtrack_limit
- PHP8 compatibility (experimental)
- Introduce Lib/Crypto (ported from zap)
- Introduce Lib/Keyutils which now implements phpseclib v2
- Improve profile photo fetching
- Introduce fetch_provider hook
- Implement ActivityStreams discovery in mod profile
- Implement ActivityStreams discovery in mod channel
- Streamline OS folder and file permissions
- Add polish translations
- Implement ThreadListener in mod activity_match
- Improve ThreadListener handling
- Use mail envelope instead of lock icon for direct messages
- Implement ASCollection in Libzot::fetch_conversation()
- Invoke channel discovery by hash instead of address in mod channel
- Implement manual public item import for zot6, activitypub and diaspora via search
- Default photo storage to filesystem instead of DB for new installations
- Support filesystem storage for xchan profile photos
- Deprecate Daemon/Externals
- Implement SQL query background caching
- Process channel categories list in background
- Port util/connect to Lib/Connect
Bugfixes
- Fix visible/empty notifications for blocked contacts items
- Fix issue where URL fragment was turned into hashtag if the hashtag existed elsewhere in the post (issue #1518)
- Fix audio and video embeds for media sources without media format extension
- Fix issue where zot package was saved in iconf instead of the decoded activity
- Fix duplicate id in post preview
- Fix display issue of restricted content in mod display
- Fix issue where comments were not delivered to the public stream
- Fix issue where profile photos were stored multiple times and remove duplicates
- Fix pinned items sync between clones
- Fix r_preview for list mode in mod channel and mod network
Addons
- Pubcrawl: deal with mastodons remote replies
- Diaspora: reduce xchan network confusion in several places
- Diaspora: fix mentions if multiple xchan networks exists
- Diaspora: fix comments on comments
- Pubcrawl: do not re-use broken signed messages
- Pubcrawl: fix parsing of images with description (core issue #1519)
- Pubcrawl: use the signed message from the attachment (iconfig) when relaying
- Diaspora: implement browser to browser encrypted messages as base64 encoded string
- Pubcrawl: implement browser to browser encrypted messages as base64 encoded string
- Diaspora: support post summary
- Pubcrawl: fix summary aka content warning
- PHP8 compatibility (experimental)
- Tripleaes: removed
- Reflect core crypto changes
- Photocache: improve mimetype detection
- Diaspora: implement mnanual fetch provider
- Diaspora: implement send participation
- Pubcrawl: deprecate pubcrawl_is_as_request() in favor of the core version in Lib/ActivityStreams
- Diaspora: prefer zot identity for inbound comments if available
- Pubcrawl: return zotfeed results in mod outbox
- Queueworker: improved deduplication by adding a uuid
- Superblock: fix syncing with clones regression
- Queueworker: improve SQL query in GetWorkerCount()
- Queueworker: fix issue in workersleep handling
Hubzilla 5.2.2 (2021-02-13)
- Fix issue with ping_site()
- Fix issue with ping_site()
Hubzilla 5.2.1 (2021-01-16)
- Fix attach_upgrade() to catch all broken entries in attach
- Fix collect_recipients() public policy filter for zot6
- Fix leaking of duplicate tasks in queueworker addon_common
- Fix leaking of duplicate tasks in queueworker
Hubzilla 5.2 (2021-01-13)

16
SBOM.md
View File

@@ -3,7 +3,7 @@
|Name|Version|License|Source|
|----|-------|-------|------|
|blueimp/jquery-file-upload|10.31.0.0|MIT|https://github.com/vkhramtsov/jQuery-File-Upload.git|
|brick/math|0.9.1.0|MIT|https://github.com/brick/math.git|
|brick/math|0.9.2.0|MIT|https://github.com/brick/math.git|
|bshaffer/oauth2-server-php|1.11.1.0|MIT|https://github.com/bshaffer/oauth2-server-php.git|
|commerceguys/intl|1.0.7.0|MIT|https://github.com/commerceguys/intl.git|
|desandro/imagesloaded|4.1.4.0|MIT|https://github.com/desandro/imagesloaded.git|
@@ -12,22 +12,22 @@
|lukasreschke/id3parser|0.0.3.0|GPL|https://github.com/LukasReschke/ID3Parser.git|
|michelf/php-markdown|1.9.0.0|BSD-3-Clause|https://github.com/michelf/php-markdown.git|
|pear/text_languagedetect|1.0.1.0|BSD-2-Clause|https://github.com/pear/Text_LanguageDetect.git|
|phpseclib/phpseclib|2.0.30.0|MIT|https://github.com/phpseclib/phpseclib.git|
|psr/log|1.1.3.0|MIT|https://github.com/php-fig/log.git|
|ramsey/collection|1.1.1.0|MIT|https://github.com/ramsey/collection.git|
|ramsey/collection|1.1.3.0|MIT|https://github.com/ramsey/collection.git|
|ramsey/uuid|4.1.1.0|MIT|https://github.com/ramsey/uuid.git|
|sabre/dav|4.1.3.0|BSD-3-Clause|https://github.com/sabre-io/dav.git|
|sabre/dav|4.1.5.0|BSD-3-Clause|https://github.com/sabre-io/dav.git|
|sabre/event|5.1.2.0|BSD-3-Clause|https://github.com/sabre-io/event.git|
|sabre/http|5.1.1.0|BSD-3-Clause|https://github.com/sabre-io/http.git|
|sabre/uri|2.2.1.0|BSD-3-Clause|https://github.com/sabre-io/uri.git|
|sabre/vobject|4.3.3.0|BSD-3-Clause|https://github.com/sabre-io/vobject.git|
|sabre/vobject|4.3.5.0|BSD-3-Clause|https://github.com/sabre-io/vobject.git|
|sabre/xml|2.2.3.0|BSD-3-Clause|https://github.com/sabre-io/xml.git|
|simplepie/simplepie|1.5.6.0|BSD-3-Clause|https://github.com/simplepie/simplepie.git|
|smarty/smarty|3.1.36.0|LGPL-3.0|https://github.com/smarty-php/smarty.git|
|symfony/polyfill-ctype|1.20.0.0|MIT|https://github.com/symfony/polyfill-ctype.git|
|twbs/bootstrap|4.5.3.0|MIT|https://github.com/twbs/bootstrap.git|
|smarty/smarty|3.1.38.0|LGPL-3.0|https://github.com/smarty-php/smarty.git|
|symfony/polyfill-ctype|1.22.0.0|MIT|https://github.com/symfony/polyfill-ctype.git|
|twbs/bootstrap|4.6.0.0|MIT|https://github.com/twbs/bootstrap.git|
|fullcalendar/fullcalendar|4.4.2.0|MIT|https://github.com/fullcalendar/fullcalendar.git|
|miromannino/Justified-Gallery|3.8.1.0|MIT|https://github.com/miromannino/Justified-Gallery.git|
|fengyuanchen/cropperjs|1.5.7.0|MIT|https://github.com/fengyuanchen/cropperjs.git|
|ForkAwesome/Fork-Awesome|1.1.7.0|MIT,SIL OFL,CC BY 3.0|https://github.com/ForkAwesome/Fork-Awesome.git|
|leafo/sticky-kit|1.1.2.0|MIT|https://github.com/leafo/sticky-kit.git|
|jquery/jquery|3.5.1.0|MIT|https://github.com/jquery/jquery.git|

View File

@@ -54,7 +54,7 @@ class AccessList {
* * \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_gid = $channel['channel_allow_gid'];
$this->deny_cid = $channel['channel_deny_cid'];
@@ -99,7 +99,6 @@ class AccessList {
$this->allow_gid = $arr['allow_gid'];
$this->deny_cid = $arr['deny_cid'];
$this->deny_gid = $arr['deny_gid'];
$this->explicit = $explicit;
}

View File

@@ -2,6 +2,7 @@
namespace Zotlabs\Access;
use App;
use Zotlabs\Lib\PConfig;
/**
@@ -39,10 +40,10 @@ class PermissionLimits {
*/
static public function Std_Limits() {
$limits = [];
$perms = Permissions::Perms();
$perms = Permissions::Perms();
foreach($perms as $k => $v) {
if(strstr($k, 'view'))
foreach ($perms as $k => $v) {
if (strstr($k, 'view'))
$limits[$k] = PERMS_PUBLIC;
else
$limits[$k] = PERMS_SPECIFIC;
@@ -77,14 +78,14 @@ class PermissionLimits {
* * \b array with all permission limits, if $perm is not set
*/
static public function Get($channel_id, $perm = '') {
if($perm) {
if ($perm) {
return intval(PConfig::Get($channel_id, 'perm_limits', $perm));
}
PConfig::Load($channel_id);
if(array_key_exists($channel_id, \App::$config)
&& array_key_exists('perm_limits', \App::$config[$channel_id]))
return \App::$config[$channel_id]['perm_limits'];
if (array_key_exists($channel_id, App::$config)
&& array_key_exists('perm_limits', App::$config[$channel_id]))
return App::$config[$channel_id]['perm_limits'];
return false;
}

View File

@@ -218,13 +218,13 @@ class PermissionRoles {
// set permissionlimits for this permission here, for example:
// if($perm === 'mynewperm')
// \Zotlabs\Access\PermissionLimits::Set($uid,$perm,1);
// PermissionLimits::Set($uid,$perm,1);
if($perm === 'view_wiki')
\Zotlabs\Access\PermissionLimits::Set($uid, $perm, PERMS_PUBLIC);
PermissionLimits::Set($uid, $perm, PERMS_PUBLIC);
if($perm === 'write_wiki')
\Zotlabs\Access\PermissionLimits::Set($uid, $perm, PERMS_SPECIFIC);
PermissionLimits::Set($uid, $perm, PERMS_SPECIFIC);
// set autoperms here if applicable
@@ -262,11 +262,11 @@ class PermissionRoles {
case 'view_wiki':
set_abconfig($uid,$ab['abook_xchan'],'my_perms',$perm,
intval(get_abconfig($uid,$ab['abook_xchan'],'my_perms','view_pages')));
break;
case 'write_wiki':
set_abconfig($uid,$ab['abook_xchan'],'my_perms',$perm,
intval(get_abconfig($uid,$ab['abook_xchan'],'my_perms','write_pages')));
break;
default:
break;
}
@@ -317,4 +317,4 @@ class PermissionRoles {
return $roles;
}
}
}

View File

@@ -75,7 +75,7 @@ class Permissions {
$x = [
'permissions' => $perms,
'filter' => $filter
'filter' => $filter
];
/**
* @hooks permissions_list
@@ -84,7 +84,7 @@ class Permissions {
*/
call_hooks('permissions_list', $x);
return($x['permissions']);
return ($x['permissions']);
}
/**
@@ -96,10 +96,10 @@ class Permissions {
*/
static public function BlockedAnonPerms() {
$res = [];
$res = [];
$perms = PermissionLimits::Std_limits();
foreach($perms as $perm => $limit) {
if($limit != PERMS_PUBLIC) {
foreach ($perms as $perm => $limit) {
if ($limit != PERMS_PUBLIC) {
$res[] = $perm;
}
}
@@ -111,7 +111,7 @@ class Permissions {
*/
call_hooks('write_perms', $x);
return($x['permissions']);
return ($x['permissions']);
}
/**
@@ -120,20 +120,20 @@ class Permissions {
* 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) {
if(is_null($arr)) {
if (is_null($arr)) {
btlogger('FilledPerms: null');
$arr = [];
}
$everything = self::Perms();
$ret = [];
foreach($everything as $k => $v) {
if(in_array($k, $arr))
$ret = [];
foreach ($everything as $k => $v) {
if (in_array($k, $arr))
$ret[$k] = 1;
else
$ret[$k] = 0;
@@ -155,9 +155,9 @@ class Permissions {
*/
static public function OPerms($arr) {
$ret = [];
if($arr) {
foreach($arr as $k => $v) {
$ret[] = [ 'name' => $k, 'value' => $v ];
if ($arr) {
foreach ($arr as $k => $v) {
$ret[] = ['name' => $k, 'value' => $v];
}
}
return $ret;
@@ -170,15 +170,16 @@ class Permissions {
* @return boolean|array
*/
static public function FilledAutoperms($channel_id) {
if(! intval(get_pconfig($channel_id,'system','autoperms')))
if (!intval(get_pconfig($channel_id, 'system', 'autoperms')))
return false;
$arr = [];
$r = q("select * from pconfig where uid = %d and cat = 'autoperms'",
intval($channel_id)
);
if($r) {
foreach($r as $rr) {
if ($r) {
foreach ($r as $rr) {
$arr[$rr['k']] = intval($rr['v']);
}
}
@@ -193,11 +194,11 @@ class Permissions {
* @return boolean true if all perms from $p1 exist also in $p2
*/
static public function PermsCompare($p1, $p2) {
foreach($p1 as $k => $v) {
if(! array_key_exists($k, $p2))
foreach ($p1 as $k => $v) {
if (!array_key_exists($k, $p2))
return false;
if($p1[$k] != $p2[$k])
if ($p1[$k] != $p2[$k])
return false;
}
@@ -214,18 +215,18 @@ class Permissions {
*/
static public function connect_perms($channel_id) {
$my_perms = [];
$permcat = null;
$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);
$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) {
if ($permcat && $permcat['perms']) {
foreach ($permcat['perms'] as $p) {
$my_perms[$p['name']] = $p['value'];
}
}
@@ -235,15 +236,15 @@ class Permissions {
// 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) {
$role = get_pconfig($channel_id, 'system', 'permissions_role');
if ($role) {
$xx = PermissionRoles::role_perms($role);
if($xx['perms_auto'])
if ($xx['perms_auto'])
$automatic = 1;
if((! $my_perms) && ($xx['perms_connect'])) {
if ((!$my_perms) && ($xx['perms_connect'])) {
$default_perms = $xx['perms_connect'];
$my_perms = Permissions::FilledPerms($default_perms);
$my_perms = Permissions::FilledPerms($default_perms);
}
}
@@ -251,11 +252,11 @@ class Permissions {
// it is likely a custom permissions role. First see if there are any
// automatic permissions.
if(! $my_perms) {
if (!$my_perms) {
$m = Permissions::FilledAutoperms($channel_id);
if($m) {
if ($m) {
$automatic = 1;
$my_perms = $m;
$my_perms = $m;
}
}
@@ -263,35 +264,35 @@ class Permissions {
// 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) {
if (!$my_perms) {
$r = q("select channel_hash from channel where channel_id = %d",
intval($channel_id)
);
if($r) {
if ($r) {
$x = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'my_perms'",
intval($channel_id),
dbesc($r[0]['channel_hash'])
);
if($x) {
foreach($x as $xv) {
if ($x) {
foreach ($x as $xv) {
$my_perms[$xv['k']] = intval($xv['v']);
}
}
}
}
return ( [ 'perms' => $my_perms, 'automatic' => $automatic ] );
return (['perms' => $my_perms, 'automatic' => $automatic]);
}
static public function serialise($p) {
$n = [];
if($p) {
foreach($p as $k => $v) {
if(intval($v)) {
if ($p) {
foreach ($p as $k => $v) {
if (intval($v)) {
$n[] = $k;
}
}
}
return implode(',',$n);
return implode(',', $n);
}
}

View File

@@ -2,13 +2,12 @@
namespace Zotlabs\Daemon;
require_once('include/zot.php');
class Addon {
static public function run($argc,$argv) {
static public function run($argc, $argv) {
call_hooks('daemon_addon',$argv);
call_hooks('daemon_addon', $argv);
}
}

View File

@@ -2,7 +2,6 @@
namespace Zotlabs\Daemon;
class Cache_embeds {
static public function run($argc,$argv) {

View File

@@ -0,0 +1,36 @@
<?php
namespace Zotlabs\Daemon;
use Zotlabs\Lib\Cache;
class Cache_query {
static public function run($argc, $argv) {
if(! $argc == 3)
return;
$key = $argv[1];
$pid = get_config('procid', $key, false);
if ($pid && (function_exists('posix_kill') ? posix_kill($pid, 0) : true)) {
logger($key . ': procedure already run with pid ' . $pid, LOGGER_DEBUG);
return;
}
$pid = getmypid();
set_config('procid', $key, $pid);
array_shift($argv);
array_shift($argv);
$arr = json_decode(base64_decode($argv[0]), true);
$r = call_user_func_array('q', $arr);
if($r)
Cache::set($key, serialize($r));
del_config('procid', $key);
}
}

View File

@@ -6,34 +6,35 @@ require_once('include/hubloc.php');
class Checksites {
static public function run($argc,$argv) {
static public function run($argc, $argv) {
logger('checksites: start');
if(($argc > 1) && ($argv[1]))
if (($argc > 1) && ($argv[1]))
$site_id = $argv[1];
if($site_id)
if ($site_id)
$sql_options = " and site_url = '" . dbesc($argv[1]) . "' ";
$days = intval(get_config('system','sitecheckdays'));
if($days < 1)
$days = intval(get_config('system', 'sitecheckdays'));
if ($days < 1)
$days = 30;
$r = q("select * from site where site_dead = 0 and site_update < %s - INTERVAL %s and site_type = %d $sql_options ",
db_utcnow(), db_quoteinterval($days . ' DAY'),
db_utcnow(),
db_quoteinterval($days . ' DAY'),
intval(SITE_TYPE_ZOT)
);
if(! $r)
if (!$r)
return;
foreach($r as $rr) {
if(! strcasecmp($rr['site_url'],z_root()))
foreach ($r as $rr) {
if (!strcasecmp($rr['site_url'], z_root()))
continue;
$x = ping_site($rr['site_url']);
if($x['success']) {
if ($x['success']) {
logger('checksites: ' . $rr['site_url']);
q("update site set site_update = '%s' where site_url = '%s' ",
dbesc(datetime_convert()),

58
Zotlabs/Daemon/Convo.php Normal file
View File

@@ -0,0 +1,58 @@
<?php
namespace Zotlabs\Daemon;
use Zotlabs\Lib\Activity;
use Zotlabs\Lib\ActivityStreams;
use Zotlabs\Lib\ASCollection;
class Convo {
static public function run($argc, $argv) {
logger('convo invoked: ' . print_r($argv, true));
if ($argc != 4) {
return;
}
$id = $argv[1];
$channel_id = intval($argv[2]);
$contact_hash = $argv[3];
$channel = channelx_by_n($channel_id);
if (!$channel) {
return;
}
$r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_channel = %d and abook_xchan = '%s' LIMIT 1",
intval($channel_id),
dbesc($contact_hash)
);
if (!$r) {
return;
}
$contact = array_shift($r);
$obj = new ASCollection($id, $channel);
$messages = $obj->get();
if ($messages) {
foreach ($messages as $message) {
if (is_string($message)) {
$message = Activity::fetch($message, $channel);
}
// set client flag because comments will probably just be objects and not full blown activities
// and that lets us use implied_create
$AS = new ActivityStreams($message);
if ($AS->is_valid() && is_array($AS->obj)) {
$item = Activity::decode_note($AS);
Activity::store($channel, $contact['abook_xchan'], $AS, $item);
}
}
}
}
}

View File

@@ -6,14 +6,14 @@ use Zotlabs\Lib\Libsync;
class Cron {
static public function run($argc,$argv) {
static public function run($argc, $argv) {
$maxsysload = intval(get_config('system','maxloadavg'));
if($maxsysload < 1)
$maxsysload = intval(get_config('system', 'maxloadavg'));
if ($maxsysload < 1)
$maxsysload = 50;
if(function_exists('sys_getloadavg')) {
if (function_exists('sys_getloadavg')) {
$load = sys_getloadavg();
if(intval($load[0]) > $maxsysload) {
if (intval($load[0]) > $maxsysload) {
logger('system: load ' . $load . ' too high. Cron deferred to next scheduled run.');
return;
}
@@ -21,17 +21,18 @@ class Cron {
// Check for a lockfile. If it exists, but is over an hour old, it's stale. Ignore it.
$lockfile = 'store/[data]/cron';
if((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 3600))
&& (! get_config('system','override_cron_lockfile'))) {
if ((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 3600))
&& (!get_config('system', 'override_cron_lockfile'))) {
logger("cron: Already running");
return;
}
// Create a lockfile. Needs two vars, but $x doesn't need to contain anything.
$x = '';
file_put_contents($lockfile, $x);
logger('cron: start');
// run queue delivery process in the background
Master::Summon(array('Queue'));
@@ -46,7 +47,7 @@ class Cron {
db_utcnow(),
db_quoteinterval('3 MINUTE')
);
// expire any expired mail
q("delete from mail where expires > '%s' and expires < %s ",
@@ -54,19 +55,23 @@ class Cron {
db_utcnow()
);
$interval = get_config('system', 'delivery_interval', 3);
// expire any expired items
$r = q("select id,item_wall from item where expires > '2001-01-01 00:00:00' and expires < %s
and item_deleted = 0 ",
db_utcnow()
);
if($r) {
if ($r) {
require_once('include/items.php');
foreach($r as $rr) {
drop_item($rr['id'],false,(($rr['item_wall']) ? DROPITEM_PHASE1 : DROPITEM_NORMAL));
if($rr['item_wall']) {
foreach ($r as $rr) {
drop_item($rr['id'], false, (($rr['item_wall']) ? DROPITEM_PHASE1 : DROPITEM_NORMAL));
if ($rr['item_wall']) {
// The notifier isn't normally invoked unless item_drop is interactive.
Master::Summon( [ 'Notifier', 'drop', $rr['id'] ] );
Master::Summon(['Notifier', 'drop', $rr['id']]);
if ($interval)
@time_sleep_until(microtime(true) + (float)$interval);
}
}
}
@@ -78,9 +83,9 @@ class Cron {
dbesc(NULL_DATE),
db_utcnow()
);
if($r) {
if ($r) {
require_once('include/security.php');
foreach($r as $rr) {
foreach ($r as $rr) {
atoken_delete($rr['atoken_id']);
}
}
@@ -90,33 +95,33 @@ class Cron {
// or dead entries.
$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')
);
if($r) {
foreach($r as $rr) {
Master::Summon(array('Directory',$rr['channel_id'],'force'));
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
if ($r) {
foreach ($r as $rr) {
Master::Summon(array('Directory', $rr['channel_id'], 'force'));
if ($interval)
@time_sleep_until(microtime(true) + (float)$interval);
}
}
// Clean expired photos from cache
$r = q("SELECT DISTINCT xchan, content FROM photo WHERE photo_usage = %d AND expires < %s - INTERVAL %s",
intval(PHOTO_CACHE),
db_utcnow(),
db_quoteinterval(get_config('system','active_expire_days', '30') . ' DAY')
db_quoteinterval(get_config('system', 'active_expire_days', '30') . ' DAY')
);
if($r) {
if ($r) {
q("DELETE FROM photo WHERE photo_usage = %d AND expires < %s - INTERVAL %s",
intval(PHOTO_CACHE),
db_utcnow(),
db_quoteinterval(get_config('system','active_expire_days', '30') . ' DAY')
db_quoteinterval(get_config('system', 'active_expire_days', '30') . ' DAY')
);
foreach($r as $rr) {
foreach ($r as $rr) {
$file = dbunescbin($rr['content']);
if(is_file($file)) {
if (is_file($file)) {
@unlink($file);
@rmdir(dirname($file));
logger('info: deleted cached photo file ' . $file, LOGGER_DEBUG);
@@ -130,27 +135,29 @@ class Cron {
$r = q("select id from item where item_delayed = 1 and created <= %s and created > '%s' ",
db_utcnow(),
dbesc(datetime_convert('UTC','UTC','now - 2 days'))
dbesc(datetime_convert('UTC', 'UTC', 'now - 2 days'))
);
if($r) {
foreach($r as $rr) {
if ($r) {
foreach ($r as $rr) {
$x = q("update item set item_delayed = 0 where id = %d",
intval($rr['id'])
);
if($x) {
if ($x) {
$z = q("select * from item where id = %d",
intval($message_id)
intval($rr['id'])
);
if($z) {
if ($z) {
xchan_query($z);
$sync_item = fetch_post_tags($z);
Libsync::build_sync_packet($sync_item[0]['uid'],
[
'item' => [ encode_item($sync_item[0],true) ]
[
'item' => [encode_item($sync_item[0], true)]
]
);
}
Master::Summon(array('Notifier','wall-new',$rr['id']));
Master::Summon(array('Notifier', 'wall-new', $rr['id']));
if ($interval)
@time_sleep_until(microtime(true) + (float)$interval);
}
}
}
@@ -163,27 +170,22 @@ class Cron {
require_once('include/attach.php');
attach_upgrade();
$abandon_days = intval(get_config('system','account_abandon_days'));
if($abandon_days < 1)
$abandon_days = 0;
// once daily run birthday_updates and then expire in background
// FIXME: add birthday updates, both locally and for xprof for use
// by directory servers
$d1 = intval(get_config('system','last_expire_day'));
$d2 = intval(datetime_convert('UTC','UTC','now','d'));
$d1 = intval(get_config('system', 'last_expire_day'));
$d2 = intval(datetime_convert('UTC', 'UTC', 'now', 'd'));
// Allow somebody to staggger daily activities if they have more than one site on their server,
// or if it happens at an inconvenient (busy) hour.
$h1 = intval(get_config('system','cron_hour'));
$h2 = intval(datetime_convert('UTC','UTC','now','G'));
$h1 = intval(get_config('system', 'cron_hour'));
$h2 = intval(datetime_convert('UTC', 'UTC', 'now', 'G'));
if(($d2 != $d1) && ($h1 == $h2)) {
if (($d2 != $d1) && ($h1 == $h2)) {
Master::Summon(array('Cron_daily'));
}
@@ -192,14 +194,14 @@ class Cron {
$r = q("select xchan_photo_l, xchan_hash from xchan where xchan_photo_l != '' and xchan_photo_m = ''
and xchan_photo_date < %s - INTERVAL %s",
db_utcnow(),
db_utcnow(),
db_quoteinterval('1 DAY')
);
if($r) {
if ($r) {
require_once('include/photo/photo_driver.php');
foreach($r as $rr) {
foreach ($r as $rr) {
$photos = import_xchan_photo($rr['xchan_photo_l'], $rr['xchan_hash'], false, true);
$x = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s'
q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s'
where xchan_hash = '%s'",
dbesc($photos[0]),
dbesc($photos[1]),
@@ -213,31 +215,28 @@ class Cron {
// pull in some public posts
$disable_discover_tab = get_config('system','disable_discover_tab') || get_config('system','disable_discover_tab') === false;
if(! $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'));
*/
$generation = 0;
$restart = false;
$restart = false;
if(($argc > 1) && ($argv[1] == 'restart')) {
$restart = true;
if (($argc > 1) && ($argv[1] == 'restart')) {
$restart = true;
$generation = intval($argv[2]);
if(! $generation)
if (!$generation)
return;
}
reload_plugins();
$d = datetime_convert();
// TODO check to see if there are any cronhooks before wasting a process
if(! $restart)
if (!$restart)
Master::Summon(array('Cronhooks'));
set_config('system','lastcron',datetime_convert());
set_config('system', 'lastcron', datetime_convert());
//All done - clear the lockfile
@unlink($lockfile);

View File

@@ -6,7 +6,7 @@ use Zotlabs\Lib\Libzotdir;
class Cron_daily {
static public function run($argc,$argv) {
static public function run($argc, $argv) {
logger('cron_daily: start');
@@ -15,14 +15,12 @@ class Cron_daily {
*
*/
Libzotdir::check_upstream_directory();
// Fire off the Cron_weekly process if it's the correct day.
$d3 = intval(datetime_convert('UTC','UTC','now','N'));
if($d3 == 7) {
$d3 = intval(datetime_convert('UTC', 'UTC', 'now', 'N'));
if ($d3 == 7) {
Master::Summon(array('Cron_weekly'));
}
@@ -53,8 +51,8 @@ class Cron_daily {
// Clean up emdedded content cache
q("DELETE FROM cache WHERE updated < %s - INTERVAL %s",
db_utcnow(),
db_quoteinterval(get_config('system','active_expire_days', '30') . ' DAY')
db_utcnow(),
db_quoteinterval(get_config('system', 'active_expire_days', '30') . ' DAY')
);
//update statistics in config
@@ -68,8 +66,8 @@ class Cron_daily {
// expire old delivery reports
$keep_reports = intval(get_config('system','expire_delivery_reports'));
if($keep_reports === 0)
$keep_reports = intval(get_config('system', 'expire_delivery_reports'));
if ($keep_reports === 0)
$keep_reports = 10;
q("delete from dreport where dreport_time < %s - INTERVAL %s",
@@ -85,13 +83,12 @@ class Cron_daily {
// Pull remote changes and push local changes.
// potential issue: how do we keep from creating an endless update loop?
$dirmode = get_config('system','directory_mode');
$dirmode = get_config('system', 'directory_mode');
if($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) {
if ($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) {
Libzotdir::sync_directories($dirmode);
}
Master::Summon(array('Expire'));
Master::Summon(array('Cli_suggest'));
@@ -99,9 +96,10 @@ class Cron_daily {
z6_discover();
call_hooks('cron_daily',datetime_convert());
$date = datetime_convert();
call_hooks('cron_daily', $date);
set_config('system','last_expire_day',intval(datetime_convert('UTC','UTC','now','d')));
set_config('system', 'last_expire_day', intval(datetime_convert('UTC', 'UTC', 'now', 'd')));
/**
* End Cron Daily

View File

@@ -4,21 +4,22 @@ namespace Zotlabs\Daemon;
class Cron_weekly {
static public function run($argc,$argv) {
static public function run($argc, $argv) {
/**
* Cron Weekly
*
*
* Actions in the following block are executed once per day only on Sunday (once per week).
*
*/
call_hooks('cron_weekly',datetime_convert());
$date = datetime_convert();
call_hooks('cron_weekly', $date);
z_check_cert();
prune_hub_reinstalls();
mark_orphan_hubsxchans();
// Find channels that were removed in the last three weeks, but
@@ -31,8 +32,8 @@ class Cron_weekly {
db_utcnow(), db_quoteinterval('21 DAY'),
db_utcnow(), db_quoteinterval('10 DAY')
);
if($r) {
foreach($r as $rv) {
if ($r) {
foreach ($r as $rv) {
channel_remove_final($rv['channel_id']);
}
}
@@ -43,14 +44,14 @@ class Cron_weekly {
db_utcnow(), db_quoteinterval('14 DAY')
);
$dirmode = intval(get_config('system','directory_mode'));
if($dirmode === DIRECTORY_MODE_SECONDARY || $dirmode === DIRECTORY_MODE_PRIMARY) {
logger('regdir: ' . print_r(z_fetch_url(get_directory_primary() . '/regdir?f=&url=' . urlencode(z_root()) . '&realm=' . urlencode(get_directory_realm())),true));
$dirmode = intval(get_config('system', 'directory_mode'));
if ($dirmode === DIRECTORY_MODE_SECONDARY || $dirmode === DIRECTORY_MODE_PRIMARY) {
logger('regdir: ' . print_r(z_fetch_url(get_directory_primary() . '/regdir?f=&url=' . urlencode(z_root()) . '&realm=' . urlencode(get_directory_realm())), true));
}
// Check for dead sites
Master::Summon(array('Checksites'));
// update searchable doc indexes
Master::Summon(array('Importdoc'));

View File

@@ -2,6 +2,8 @@
namespace Zotlabs\Daemon;
use App;
// generate a curl compatible cookie file with an authenticated session for the given channel_id.
// If this file is then used with curl and the destination url is sent through zid() or manually
// manipulated to add a zid, it should allow curl to provide zot magic-auth across domains.
@@ -10,15 +12,15 @@ namespace Zotlabs\Daemon;
class CurlAuth {
static public function run($argc,$argv) {
static public function run($argc, $argv) {
if($argc != 2)
if ($argc != 2)
return;
\App::$session->start();
App::$session->start();
$_SESSION['authenticated'] = 1;
$_SESSION['uid'] = $argv[1];
$_SESSION['uid'] = $argv[1];
$x = session_id();
@@ -29,14 +31,14 @@ class CurlAuth {
$output = '';
if($e) {
if ($e) {
$lines = file($f);
if($lines) {
foreach($lines as $line) {
if(strlen($line) > 0 && $line[0] != '#' && substr_count($line, "\t") == 6) {
if ($lines) {
foreach ($lines as $line) {
if (strlen($line) > 0 && $line[0] != '#' && substr_count($line, "\t") == 6) {
$tokens = explode("\t", $line);
$tokens = array_map('trim', $tokens);
if($tokens[4] > time()) {
if ($tokens[4] > time()) {
$output .= $line . "\n";
}
}
@@ -46,9 +48,9 @@ class CurlAuth {
}
}
$t = time() + (24 * 3600);
file_put_contents($f, $output . 'HttpOnly_' . \App::get_hostname() . "\tFALSE\t/\tTRUE\t$t\tPHPSESSID\t" . $x, (($e) ? FILE_APPEND : 0));
file_put_contents($f, $output . 'HttpOnly_' . App::get_hostname() . "\tFALSE\t/\tTRUE\t$t\tPHPSESSID\t" . $x, (($e) ? FILE_APPEND : 0));
file_put_contents($c,$x);
file_put_contents($c, $x);
return;
}

View File

@@ -5,25 +5,25 @@ namespace Zotlabs\Daemon;
require_once('include/queue_fn.php');
class Deliver {
static public function run($argc,$argv) {
if($argc < 2)
static public function run($argc, $argv) {
if ($argc < 2)
return;
logger('deliver: invoked: ' . print_r($argv,true), LOGGER_DATA);
logger('deliver: invoked: ' . print_r($argv, true), LOGGER_DATA);
for($x = 1; $x < $argc; $x ++) {
for ($x = 1; $x < $argc; $x++) {
if(! $argv[$x])
if (!$argv[$x])
continue;
$r = q("select * from outq where outq_hash = '%s'",
dbesc($argv[$x])
);
if($r) {
queue_deliver($r[0],true);
if ($r) {
queue_deliver($r[0], true);
}
}

View File

@@ -2,21 +2,18 @@
namespace Zotlabs\Daemon;
require_once('include/zot.php');
class Deliver_hooks {
static public function run($argc,$argv) {
static public function run($argc, $argv) {
if($argc < 2)
if ($argc < 2)
return;
$r = q("select * from item where id = '%d'",
intval($argv[1])
);
if($r)
call_hooks('notifier_normal',$r[0]);
if ($r)
call_hooks('notifier_normal', $r[0]);
}
}

View File

@@ -8,40 +8,40 @@ use Zotlabs\Lib\Queue;
class Directory {
static public function run($argc,$argv){
static public function run($argc, $argv) {
if($argc < 2)
if ($argc < 2)
return;
$force = false;
$force = false;
$pushall = true;
if($argc > 2) {
if($argv[2] === 'force')
if ($argc > 2) {
if ($argv[2] === 'force')
$force = true;
if($argv[2] === 'nopush')
if ($argv[2] === 'nopush')
$pushall = false;
}
}
logger('directory update', LOGGER_DEBUG);
$dirmode = get_config('system','directory_mode');
if($dirmode === false)
$dirmode = get_config('system', 'directory_mode');
if ($dirmode === false)
$dirmode = DIRECTORY_MODE_NORMAL;
$x = q("select * from channel where channel_id = %d limit 1",
intval($argv[1])
);
if(! $x)
if (!$x)
return;
$channel = $x[0];
if($dirmode != DIRECTORY_MODE_NORMAL) {
if ($dirmode != DIRECTORY_MODE_NORMAL) {
// this is an in-memory update and we don't need to send a network packet.
Libzotdir::local_dir_update($argv[1],$force);
Libzotdir::local_dir_update($argv[1], $force);
q("update channel set channel_dirdate = '%s' where channel_id = %d",
dbesc(datetime_convert()),
@@ -49,8 +49,8 @@ class Directory {
);
// Now update all the connections
if($pushall)
Master::Summon(array('Notifier','refresh_all',$channel['channel_id']));
if ($pushall)
Master::Summon(array('Notifier', 'refresh_all', $channel['channel_id']));
return;
}
@@ -63,14 +63,12 @@ class Directory {
// ensure the upstream directory is updated
$packet = Libzot::build_packet($channel,(($force) ? 'force_refresh' : 'refresh'));
$z = Libzot::zot($url,$packet,$channel);
$packet = Libzot::build_packet($channel, (($force) ? 'force_refresh' : 'refresh'));
$z = Libzot::zot($url, $packet, $channel);
// re-queue if unsuccessful
if(! $z['success']) {
if (!$z['success']) {
/** @FIXME we aren't updating channel_dirdate if we have to queue
* the directory packet. That means we'll try again on the next poll run.
@@ -95,8 +93,8 @@ class Directory {
}
// Now update all the connections
if($pushall)
Master::Summon(array('Notifier','refresh_all',$channel['channel_id']));
if ($pushall)
Master::Summon(array('Notifier', 'refresh_all', $channel['channel_id']));
}
}

View File

@@ -5,23 +5,24 @@ namespace Zotlabs\Daemon;
class Expire {
static public function run($argc,$argv){
static public function run($argc, $argv) {
cli_startup();
$pid = get_config('expire', 'procid', false);
$pid = get_config('procid', 'expire', false);
if ($pid && (function_exists('posix_kill') ? posix_kill($pid, 0) : true)) {
logger('Expire: procedure already run with pid ' . $pid, LOGGER_DEBUG);
return;
logger('procedure already run with pid ' . $pid, LOGGER_DEBUG);
return;
}
$pid = getmypid();
set_config('expire', 'procid', $pid);
set_config('procid', 'expire', $pid);
// perform final cleanup on previously delete items
$r = q("select id from item where item_deleted = 1 and item_pending_remove = 0 and changed < %s - INTERVAL %s",
db_utcnow(), db_quoteinterval('10 DAY')
db_utcnow(),
db_quoteinterval('10 DAY')
);
if ($r) {
foreach ($r as $rr) {
@@ -32,23 +33,22 @@ class Expire {
// physically remove anything that has been deleted for more than two months
/** @FIXME - this is a wretchedly inefficient query */
$r = q("delete from item where item_pending_remove = 1 and changed < %s - INTERVAL %s",
db_utcnow(), db_quoteinterval('36 DAY')
q("delete from item where item_pending_remove = 1 and changed < %s - INTERVAL %s",
db_utcnow(),
db_quoteinterval('36 DAY')
);
/** @FIXME make this optional as it could have a performance impact on large sites */
if (intval(get_config('system', 'optimize_items')))
q("optimize table item");
logger('expire: start with pid ' . $pid, LOGGER_DEBUG);
$site_expire = intval(get_config('system', 'default_expire_days'));
$commented_days = intval(get_config('system','active_expire_days'));
$site_expire = intval(get_config('system', 'default_expire_days'));
$commented_days = intval(get_config('system', 'active_expire_days'));
logger('site_expire: ' . $site_expire);
$r = q("SELECT channel_id, channel_system, channel_address, channel_expire_days from channel where true");
$r = dbq("SELECT channel_id, channel_system, channel_address, channel_expire_days from channel where true");
if ($r) {
foreach ($r as $rr) {
@@ -64,11 +64,12 @@ class Expire {
$channel_expire = $service_class_expire;
else
$channel_expire = $site_expire;
if (intval($channel_expire) && (intval($channel_expire) < intval($rr['channel_expire_days'])) ||
intval($rr['channel_expire_days'] == 0)) {
$expire_days = $channel_expire;
} else {
}
else {
$expire_days = $rr['channel_expire_days'];
}
@@ -93,13 +94,13 @@ class Expire {
}
logger('Expire: sys interval: ' . $expire_days, LOGGER_DEBUG);
if ($expire_days)
item_expire($x['channel_id'], $expire_days, $commented_days);
logger('Expire: sys: done', LOGGER_DEBUG);
}
del_config('expire', 'procid');
del_config('procid', 'expire');
}
}

View File

@@ -2,97 +2,180 @@
namespace Zotlabs\Daemon;
require_once('include/zot.php');
use Zotlabs\Lib\Activity;
use Zotlabs\Lib\ActivityStreams;
use Zotlabs\Lib\ASCollection;
require_once('include/channel.php');
class Externals {
static public function run($argc,$argv){
static public function run($argc, $argv) {
$total = 0;
logger('externals: start');
$importer = get_sys_channel();
$total = 0;
$attempts = 0;
logger('externals: startup', LOGGER_DEBUG);
// pull in some public posts
while ($total == 0 && $attempts < 3) {
$arr = ['url' => ''];
call_hooks('externals_url_select', $arr);
while($total == 0 && $attempts < 3) {
$arr = array('url' => '');
call_hooks('externals_url_select',$arr);
if($arr['url']) {
if ($arr['url']) {
$url = $arr['url'];
}
}
else {
$randfunc = db_getfunc('RAND');
// fixme this query does not deal with directory realms.
// fixme this query does not deal with directory realms.
$r = q("select site_url, site_pull from site where site_url != '%s' and site_flags != %d and site_type = %d and site_dead = 0 order by $randfunc limit 1",
$r = q("select site_url, site_pull from site where site_url != '%s'
and site_flags != %d and site_type = %d
and site_dead = 0 and site_project like '%s' and site_version > '5.3.1' order by $randfunc limit 1",
dbesc(z_root()),
intval(DIRECTORY_MODE_STANDALONE),
intval(SITE_TYPE_ZOT)
intval(SITE_TYPE_ZOT),
dbesc('hubzilla%')
);
if($r)
if ($r)
$url = $r[0]['site_url'];
}
$blacklisted = false;
if(! check_siteallowed($url)) {
if (!check_siteallowed($url)) {
logger('blacklisted site: ' . $url);
$blacklisted = true;
}
$attempts ++;
$attempts++;
// make sure we can eventually break out if somebody blacklists all known sites
if($blacklisted) {
if($attempts > 20)
if ($blacklisted) {
if ($attempts > 20)
break;
$attempts --;
$attempts--;
continue;
}
if($url) {
if($r[0]['site_pull'] > NULL_DATE)
$mindate = urlencode(datetime_convert('','',$r[0]['site_pull'] . ' - 1 day'));
else {
$days = get_config('externals','since_days');
if($days === false)
$days = 15;
$mindate = urlencode(datetime_convert('','','now - ' . intval($days) . ' days'));
}
if ($url) {
$feedurl = $url . '/zotfeed?f=&mindate=' . $mindate;
$max = intval(get_config('system', 'max_imported_posts', 30));
if (intval($max)) {
logger('externals: fetching outbox');
logger('externals: pulling public content from ' . $feedurl, LOGGER_DEBUG);
$feed_url = $url . '/zotfeed';
$obj = new ASCollection($feed_url, $importer, 0, $max);
$messages = $obj->get();
$x = z_fetch_url($feedurl);
if(($x) && ($x['success'])) {
q("update site set site_pull = '%s' where site_url = '%s'",
dbesc(datetime_convert()),
dbesc($url)
);
$j = json_decode($x['body'],true);
if($j['success'] && $j['messages']) {
$sys = get_sys_channel();
foreach($j['messages'] as $message) {
// on these posts, clear any route info.
$message['route'] = '';
$results = process_delivery(array('hash' => 'undefined'), get_item_elements($message),
array(array('hash' => $sys['xchan_hash'])), false, true);
$total ++;
if ($messages) {
foreach ($messages as $message) {
if (is_string($message)) {
$message = Activity::fetch($message, $importer);
}
$AS = new ActivityStreams($message);
if ($AS->is_valid() && is_array($AS->obj)) {
$item = Activity::decode_note($AS);
Activity::store($importer, $importer['xchan_hash'], $AS, $item, true);
$total++;
}
}
logger('externals: import_public_posts: ' . $total . ' messages imported', LOGGER_DEBUG);
}
logger('externals: import_public_posts: ' . $total . ' messages imported', LOGGER_DEBUG);
}
}
}
return;
/* $total = 0;
$attempts = 0;
logger('externals: startup', LOGGER_DEBUG);
// pull in some public posts
while ($total == 0 && $attempts < 3) {
$arr = ['url' => ''];
call_hooks('externals_url_select', $arr);
if ($arr['url']) {
$url = $arr['url'];
}
else {
$randfunc = db_getfunc('RAND');
// fixme this query does not deal with directory realms.
$r = q("select site_url, site_pull from site where site_url != '%s' and site_flags != %d and site_type = %d and site_dead = 0 order by $randfunc limit 1",
dbesc(z_root()),
intval(DIRECTORY_MODE_STANDALONE),
intval(SITE_TYPE_ZOT)
);
if ($r)
$url = $r[0]['site_url'];
}
$blacklisted = false;
if (!check_siteallowed($url)) {
logger('blacklisted site: ' . $url);
$blacklisted = true;
}
$attempts++;
// make sure we can eventually break out if somebody blacklists all known sites
if ($blacklisted) {
if ($attempts > 20)
break;
$attempts--;
continue;
}
if ($url) {
if ($r[0]['site_pull'] > NULL_DATE)
$mindate = urlencode(datetime_convert('', '', $r[0]['site_pull'] . ' - 1 day'));
else {
$days = get_config('externals', 'since_days');
if ($days === false)
$days = 15;
$mindate = urlencode(datetime_convert('', '', 'now - ' . intval($days) . ' days'));
}
$feedurl = $url . '/zotfeed?f=&mindate=' . $mindate;
logger('externals: pulling public content from ' . $feedurl, LOGGER_DEBUG);
$x = z_fetch_url($feedurl);
if (($x) && ($x['success'])) {
q("update site set site_pull = '%s' where site_url = '%s'",
dbesc(datetime_convert()),
dbesc($url)
);
$j = json_decode($x['body'], true);
if ($j['success'] && $j['messages']) {
$sys = get_sys_channel();
foreach ($j['messages'] as $message) {
// on these posts, clear any route info.
$message['route'] = '';
process_delivery(['hash' => 'undefined'], get_item_elements($message),
[['hash' => $sys['xchan_hash']]], false, true);
$total++;
}
logger('externals: import_public_posts: ' . $total . ' messages imported', LOGGER_DEBUG);
}
}
}
}*/
}
}

View File

@@ -9,27 +9,27 @@ use Zotlabs\Lib\Zotfinger;
// performs zot_finger on $argv[1], which is a hex_encoded webbie/reddress
class Gprobe {
static public function run($argc,$argv) {
static public function run($argc, $argv) {
if($argc != 2)
if ($argc != 2)
return;
$url = hex2bin($argv[1]);
if(! strpos($url,'@'))
if (!strpos($url, '@'))
return;
$r = q("select * from hubloc where hubloc_addr = '%s' and hubloc_network = 'zot6' limit 1",
dbesc($url)
);
if(! $r) {
if (!$r) {
$href = Webfinger::zot_url(punify($url));
if($href) {
if ($href) {
$zf = Zotfinger::exec($href, null);
}
if(is_array($zf) && array_path_exists('signature/signer',$zf) && $zf['signature']['signer'] === $href && intval($zf['signature']['header_valid'])) {
$xc = Libzot::import_xchan($zf['data']);
if (is_array($zf) && array_path_exists('signature/signer', $zf) && $zf['signature']['signer'] === $href && intval($zf['signature']['header_valid'])) {
Libzot::import_xchan($zf['data']);
}
}

14
Zotlabs/Daemon/Importdoc.php Executable file → Normal file
View File

@@ -5,7 +5,7 @@ namespace Zotlabs\Daemon;
class Importdoc {
static public function run($argc,$argv) {
static public function run($argc, $argv) {
require_once('include/help.php');
@@ -16,20 +16,20 @@ class Importdoc {
static public function update_docs_dir($s) {
$f = basename($s);
$d = dirname($s);
if($s === 'doc/html')
if ($s === 'doc/html')
return;
$files = glob("$d/$f");
if($files) {
foreach($files as $fi) {
if($fi === 'doc/html') {
if ($files) {
foreach ($files as $fi) {
if ($fi === 'doc/html') {
continue;
}
if(is_dir($fi)) {
if (is_dir($fi)) {
self::update_docs_dir("$fi/*");
}
else {
// don't update media content
if(strpos(z_mime_content_type($fi),'text') === 0) {
if (strpos(z_mime_content_type($fi), 'text') === 0) {
store_doc_file($fi);
}
}

View File

@@ -6,22 +6,21 @@ use Zotlabs\Lib\Libsync;
class Importfile {
static public function run($argc,$argv){
static public function run($argc, $argv) {
logger('Importfile: ' . print_r($argv,true));
logger('Importfile: ' . print_r($argv, true));
if($argc < 3)
if ($argc < 3)
return;
$channel = channelx_by_n($argv[1]);
if(! $channel)
if (!$channel)
return;
$srcfile = $argv[2];
$folder = (($argc > 3) ? $argv[3] : '');
$dstname = (($argc > 4) ? $argv[4] : '');
$hash = random_string();
$hash = random_string();
$arr = [
'src' => $srcfile,
@@ -35,15 +34,15 @@ class Importfile {
'replace' => true
];
if($folder)
if ($folder)
$arr['folder'] = $folder;
attach_store($channel,$channel['channel_hash'],'import',$arr);
attach_store($channel, $channel['channel_hash'], 'import', $arr);
$sync = attach_export_data($channel, $hash);
if ($sync)
Libsync::build_sync_packet($channel['channel_id'], ['file' => [$sync]]);
$sync = attach_export_data($channel,$hash);
if($sync)
Libsync::build_sync_packet($channel['channel_id'],array('file' => array($sync)));
return;
}
}

View File

@@ -2,58 +2,57 @@
namespace Zotlabs\Daemon;
if(array_search( __file__ , get_included_files()) === 0) {
if (array_search(__file__, get_included_files()) === 0) {
require_once('include/cli_startup.php');
array_shift($argv);
$argc = count($argv);
if($argc)
Master::Release($argc,$argv);
if ($argc)
Master::Release($argc, $argv);
return;
}
class Master {
static public function Summon($arr) {
$hookinfo = [
'argv'=>$arr
'argv' => $arr
];
call_hooks ('daemon_master_summon',$hookinfo);
call_hooks('daemon_master_summon', $hookinfo);
$arr = $hookinfo['argv'];
$arr = $hookinfo['argv'];
$argc = count($arr);
if ((!is_array($arr) || (count($arr) < 1))) {
logger("Summon handled by hook.",LOGGER_DEBUG);
if ((!is_array($arr) || ($argc < 1))) {
logger("Summon handled by hook.", LOGGER_DEBUG);
return;
}
$phpbin = get_config('system','phpbin','php');
proc_run($phpbin,'Zotlabs/Daemon/Master.php',$arr);
$phpbin = get_config('system', 'phpbin', 'php');
proc_run($phpbin, 'Zotlabs/Daemon/Master.php', $arr);
}
static public function Release($argc,$argv) {
static public function Release($argc, $argv) {
cli_startup();
$hookinfo = [
'argv'=>$argv
'argv' => $argv
];
call_hooks ('daemon_master_release',$hookinfo);
call_hooks('daemon_master_release', $hookinfo);
$argv = $hookinfo['argv'];
$argc = count($argv);
if ((!is_array($argv) || (count($argv) < 1))) {
logger("Release handled by hook.",LOGGER_DEBUG);
if ((!is_array($argv) || ($argc < 1))) {
logger("Release handled by hook.", LOGGER_DEBUG);
return;
}
logger('Master: release: ' . json_encode($argv), LOGGER_ALL,LOG_DEBUG);
$cls = '\\Zotlabs\\Daemon\\' . $argv[0];
$cls::run($argc,$argv);
logger('Master: release: ' . json_encode($argv), LOGGER_ALL, LOG_DEBUG);
$cls = '\\Zotlabs\\Daemon\\' . $argv[0];
$cls::run($argc, $argv);
}
}

View File

@@ -14,7 +14,6 @@ require_once('include/items.php');
require_once('include/bbcode.php');
/*
* This file was at one time responsible for doing all deliveries, but this caused
* big problems on shared hosting systems, where the process might get killed by the
@@ -81,198 +80,198 @@ require_once('include/bbcode.php');
*/
class Notifier {
static public function run($argc,$argv){
static public function run($argc, $argv) {
if($argc < 3)
if ($argc < 3)
return;
logger('notifier: invoked: ' . print_r($argv,true), LOGGER_DEBUG);
logger('notifier: invoked: ' . print_r($argv, true), LOGGER_DEBUG);
$cmd = $argv[1];
$item_id = $argv[2];
if(! $item_id)
if (!$item_id)
return;
$sys = get_sys_channel();
$deliveries = array();
$deliveries = [];
$request = false;
$mail = false;
$top_level = false;
$location = false;
$recipients = array();
$url_recipients = array();
$normal_mode = true;
$packet_type = 'undefined';
$request = false;
$mail = false;
$location = false;
$recipients = [];
$normal_mode = true;
$packet_type = 'undefined';
if($cmd === 'mail' || $cmd === 'single_mail') {
if ($cmd === 'mail' || $cmd === 'single_mail') {
$normal_mode = false;
$mail = true;
$private = true;
$message = q("SELECT * FROM mail WHERE id = %d LIMIT 1",
intval($item_id)
$mail = true;
$private = true;
$message = q("SELECT * FROM mail WHERE id = %d LIMIT 1",
intval($item_id)
);
if(! $message) {
if (!$message) {
return;
}
xchan_mail_query($message[0]);
$uid = $message[0]['channel_id'];
$uid = $message[0]['channel_id'];
$recipients[] = $message[0]['from_xchan']; // include clones
$recipients[] = $message[0]['to_xchan'];
$item = $message[0];
$item = $message[0];
$encoded_item = encode_mail($item);
$s = q("select * from channel where channel_id = %d limit 1",
intval($item['channel_id'])
intval($uid)
);
if($s)
if ($s)
$channel = $s[0];
}
elseif($cmd === 'request') {
$channel_id = $item_id;
$xchan = $argv[3];
elseif ($cmd === 'request') {
$channel_id = $item_id;
$xchan = $argv[3];
$request_message_id = $argv[4];
$s = q("select * from channel where channel_id = %d limit 1",
intval($channel_id)
);
if($s)
if ($s)
$channel = $s[0];
$private = true;
$private = true;
$recipients[] = $xchan;
$packet_type = 'request';
$normal_mode = false;
$packet_type = 'request';
$normal_mode = false;
}
elseif($cmd === 'keychange') {
elseif ($cmd === 'keychange') {
$channel = channelx_by_n($item_id);
$r = q("select abook_xchan from abook where abook_channel = %d",
$r = q("select abook_xchan from abook where abook_channel = %d",
intval($item_id)
);
if($r) {
foreach($r as $rr) {
if ($r) {
foreach ($r as $rr) {
$recipients[] = $rr['abook_xchan'];
}
}
$private = false;
$private = false;
$packet_type = 'keychange';
$normal_mode = false;
}
elseif(in_array($cmd, [ 'permission_update', 'permission_reject', 'permission_accept', 'permission_create' ])) {
elseif (in_array($cmd, ['permission_update', 'permission_reject', 'permission_accept', 'permission_create'])) {
// Get the (single) recipient
$r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_self = 0",
intval($item_id)
);
if($r) {
if ($r) {
$uid = $r[0]['abook_channel'];
// Get the sender
$channel = channelx_by_n($uid);
if($channel) {
$perm_update = array('sender' => $channel, 'recipient' => $r[0], 'success' => false, 'deliveries' => '');
if ($channel) {
$perm_update = ['sender' => $channel, 'recipient' => $r[0], 'success' => false, 'deliveries' => ''];
if($cmd === 'permission_create')
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);
if ($cmd === 'permission_create')
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
call_hooks('permissions_update',$perm_update);
call_hooks('permissions_update', $perm_update);
if($perm_update['success']) {
if($perm_update['deliveries']) {
if ($perm_update['success']) {
if ($perm_update['deliveries']) {
$deliveries[] = $perm_update['deliveries'];
do_delivery($deliveries);
}
return;
}
else {
$recipients[] = $r[0]['abook_xchan'];
$private = false;
$packet_type = 'refresh';
$packet_recips = array(array('guid' => $r[0]['xchan_guid'],'guid_sig' => $r[0]['xchan_guid_sig'],'hash' => $r[0]['xchan_hash']));
$recipients[] = $r[0]['abook_xchan'];
$private = false;
$packet_type = 'refresh';
$packet_recips = [['guid' => $r[0]['xchan_guid'], 'guid_sig' => $r[0]['xchan_guid_sig'], 'hash' => $r[0]['xchan_hash']]];
}
}
}
}
elseif($cmd === 'refresh_all') {
elseif ($cmd === 'refresh_all') {
logger('notifier: refresh_all: ' . $item_id);
$uid = $item_id;
$uid = $item_id;
$channel = channelx_by_n($item_id);
$r = q("select abook_xchan from abook where abook_channel = %d",
intval($item_id)
$r = q("select abook_xchan from abook where abook_channel = %d",
intval($uid)
);
if($r) {
foreach($r as $rr) {
if ($r) {
foreach ($r as $rr) {
$recipients[] = $rr['abook_xchan'];
}
}
$private = false;
$private = false;
$packet_type = 'refresh';
}
elseif($cmd === 'location') {
elseif ($cmd === 'location') {
logger('notifier: location: ' . $item_id);
$s = q("select * from channel where channel_id = %d limit 1",
intval($item_id)
);
if($s)
if ($s)
$channel = $s[0];
$uid = $item_id;
$recipients = array();
$r = q("select abook_xchan from abook where abook_channel = %d",
intval($item_id)
$uid = $item_id;
$recipients = [];
$r = q("select abook_xchan from abook where abook_channel = %d",
intval($uid)
);
if($r) {
foreach($r as $rr) {
if ($r) {
foreach ($r as $rr) {
$recipients[] = $rr['abook_xchan'];
}
}
$encoded_item = array('locations' => Libzot::encode_locations($channel),'type' => 'location', 'encoding' => 'zot');
$target_item = array('aid' => $channel['channel_account_id'],'uid' => $channel['channel_id']);
$private = false;
$packet_type = 'location';
$location = true;
$encoded_item = ['locations' => Libzot::encode_locations($channel), 'type' => 'location', 'encoding' => 'zot'];
$target_item = ['aid' => $channel['channel_account_id'], 'uid' => $channel['channel_id']];
$private = false;
$packet_type = 'location';
$location = true;
}
elseif($cmd === 'purge') {
elseif ($cmd === 'purge') {
$xchan = $argv[3];
logger('notifier: purge: ' . $item_id . ' => ' . $xchan);
if (! $xchan) {
if (!$xchan) {
return;
}
$channel = channelx_by_n($item_id);
$recipients[] = $xchan;
$private = true;
$packet_type = 'purge';
$channel = channelx_by_n($item_id);
$recipients[] = $xchan;
$private = true;
$packet_type = 'purge';
$packet_recips[] = ['hash' => $xchan];
}
elseif($cmd === 'purge_all') {
elseif ($cmd === 'purge_all') {
logger('notifier: purge_all: ' . $item_id);
$channel = channelx_by_n($item_id);
$recipients = [];
$r = q("select abook_xchan from abook where abook_channel = %d and abook_self = 0",
$r = q("select abook_xchan from abook where abook_channel = %d and abook_self = 0",
intval($item_id)
);
if (! $r) {
if (!$r) {
return;
}
foreach ($r as $rr) {
$recipients[] = $rr['abook_xchan'];
$recipients[] = $rr['abook_xchan'];
$packet_recips[] = ['hash' => $rr['abook_xchan']];
}
$private = false;
$private = false;
$packet_type = 'purge';
@@ -287,7 +286,7 @@ class Notifier {
intval($item_id)
);
if(! $r)
if (!$r)
return;
xchan_query($r);
@@ -296,25 +295,22 @@ class Notifier {
$target_item = $r[0];
if(in_array($target_item['author']['xchan_network'], ['rss', 'anon'])) {
if (in_array($target_item['author']['xchan_network'], ['rss', 'anon'])) {
logger('notifier: target item author is not a fetchable actor', LOGGER_DEBUG);
return;
}
$deleted_item = false;
if(intval($target_item['item_deleted'])) {
if (intval($target_item['item_deleted'])) {
logger('notifier: target item ITEM_DELETED', LOGGER_DEBUG);
$deleted_item = true;
}
if(! in_array(intval($target_item['item_type']), [ ITEM_TYPE_POST ] )) {
$hookinfo=[
'targetitem'=>$target_item,
'deliver'=>false
if (!in_array(intval($target_item['item_type']), [ITEM_TYPE_POST])) {
$hookinfo = [
'targetitem' => $target_item,
'deliver' => false
];
if (intval($target_item['item_type'] == ITEM_TYPE_CUSTOM)) {
call_hooks('customitem_deliver',$hookinfo);
call_hooks('customitem_deliver', $hookinfo);
}
if (!$hookinfo['deliver']) {
@@ -328,14 +324,14 @@ class Notifier {
// 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);
return;
}
if(strpos($target_item['postopts'],'nodeliver') !== false) {
if (strpos($target_item['postopts'], 'nodeliver') !== false) {
logger('notifier: target item is undeliverable', LOGGER_DEBUG);
return;
}
@@ -343,17 +339,16 @@ class Notifier {
$s = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1",
intval($target_item['uid'])
);
if($s)
if ($s)
$channel = $s[0];
if($channel['channel_hash'] !== $target_item['author_xchan'] && $channel['channel_hash'] !== $target_item['owner_xchan']) {
if ($channel['channel_hash'] !== $target_item['author_xchan'] && $channel['channel_hash'] !== $target_item['owner_xchan']) {
logger("notifier: Sending channel {$channel['channel_hash']} is not owner {$target_item['owner_xchan']} or author {$target_item['author_xchan']}", LOGGER_NORMAL, LOG_WARNING);
return;
}
if($target_item['mid'] === $target_item['parent_mid']) {
$parent_item = $target_item;
if ($target_item['mid'] === $target_item['parent_mid']) {
$parent_item = $target_item;
$top_level_post = true;
}
else {
@@ -362,10 +357,10 @@ class Notifier {
intval($target_item['parent'])
);
if(! $r)
if (!$r)
return;
if(strpos($r[0]['postopts'],'nodeliver') !== false) {
if (strpos($r[0]['postopts'], 'nodeliver') !== false) {
logger('notifier: target item is undeliverable', LOGGER_DEBUG, LOG_NOTICE);
return;
}
@@ -373,34 +368,34 @@ class Notifier {
xchan_query($r);
$r = fetch_post_tags($r);
$parent_item = $r[0];
$parent_item = $r[0];
$top_level_post = false;
}
// avoid looping of discover items 12/4/2014
if($sys && $parent_item['uid'] == $sys['channel_id'])
if ($sys && $parent_item['uid'] == $sys['channel_id'])
return;
$encoded_item = encode_item($target_item);
// Re-use existing signature unless the activity type changed to a Tombstone, which won't verify.
$m = ((intval($target_item['item_deleted'])) ? '' : get_iconfig($target_item,'activitystreams','signed_data'));
$m = ((intval($target_item['item_deleted'])) ? '' : get_iconfig($target_item, 'activitypub', 'signed_data'));
if($m) {
$activity = json_decode($m,true);
if ($m) {
$activity = json_decode($m, true);
}
else {
$activity = array_merge(['@context' => [
ACTIVITYSTREAMS_JSONLD_REV,
'https://w3id.org/security/v1',
z_root() . ZOT_APSCHEMA_REV
]], Activity::encode_activity($target_item)
]], Activity::encode_activity($target_item)
);
}
logger('target_item: ' . print_r($target_item,true), LOGGER_DEBUG);
logger('encoded: ' . print_r($activity,true), LOGGER_DEBUG);
logger('target_item: ' . print_r($target_item, true), LOGGER_DEBUG);
logger('encoded: ' . print_r($activity, true), LOGGER_DEBUG);
// Send comments to the owner to re-deliver to everybody in the conversation
// We only do this if the item in question originated on this site. This prevents looping.
@@ -411,9 +406,7 @@ class Notifier {
// flag on comments for an extended period. So we'll also call comment_local_origin() which looks at
// the hostname in the message_id and provides a second (fallback) opinion.
$relay_to_owner = (((! $top_level_post) && (intval($target_item['item_origin'])) && comment_local_origin($target_item)) ? true : false);
$relay_to_owner = (((!$top_level_post) && (intval($target_item['item_origin'])) && comment_local_origin($target_item)) ? true : false);
$uplink = false;
@@ -425,43 +418,42 @@ class Notifier {
// tag_deliver'd post which needs to be sent back to the original author
if(($cmd === 'uplink') && intval($parent_item['item_uplink']) && (! $top_level_post)) {
if (($cmd === 'uplink') && intval($parent_item['item_uplink']) && (!$top_level_post)) {
logger('notifier: uplink');
$uplink = true;
}
if(($relay_to_owner || $uplink) && ($cmd !== 'relay')) {
if (($relay_to_owner || $uplink) && ($cmd !== 'relay')) {
logger('notifier: followup relay', LOGGER_DEBUG);
$recipients = array(($uplink) ? $parent_item['source_xchan'] : $parent_item['owner_xchan']);
$private = true;
if(! $encoded_item['flags'])
$encoded_item['flags'] = array();
$recipients = [($uplink) ? $parent_item['source_xchan'] : $parent_item['owner_xchan']];
$private = true;
if (!$encoded_item['flags'])
$encoded_item['flags'] = [];
$encoded_item['flags'][] = 'relay';
$upstream = true;
$upstream = true;
}
else {
logger('notifier: normal distribution', LOGGER_DEBUG);
if($cmd === 'relay')
if ($cmd === 'relay')
logger('notifier: owner relay');
$upstream = false;
// if our parent is a tag_delivery recipient, uplink to the original author causing
// a delivery fork.
if(($parent_item) && intval($parent_item['item_uplink']) && (! $top_level_post) && ($cmd !== 'uplink')) {
if (($parent_item) && intval($parent_item['item_uplink']) && (!$top_level_post) && ($cmd !== 'uplink')) {
// don't uplink a relayed post to the relay owner
if($parent_item['source_xchan'] !== $parent_item['owner_xchan']) {
if ($parent_item['source_xchan'] !== $parent_item['owner_xchan']) {
logger('notifier: uplinking this item');
Master::Summon(array('Notifier','uplink',$item_id));
Master::Summon(['Notifier', 'uplink', $item_id]);
}
}
$private = false;
$recipients = collect_recipients($parent_item,$private);
$private = false;
$recipients = collect_recipients($parent_item, $private);
if ($top_level_post) {
// remove clones who will receive the post via sync
$recipients = array_diff($recipients, [ $target_item['owner_xchan'] ]);
$recipients = array_diff($recipients, [$target_item['owner_xchan']]);
}
// FIXME add any additional recipients such as mentions, etc.
@@ -474,32 +466,31 @@ class Notifier {
// Generic delivery section, we have an encoded item and recipients
// Now start the delivery process
$x = $encoded_item;
$x = $encoded_item;
$x['title'] = 'private';
$x['body'] = 'private';
logger('notifier: encoded item: ' . print_r($x,true), LOGGER_DATA, LOG_DEBUG);
$x['body'] = 'private';
logger('notifier: encoded item: ' . print_r($x, true), LOGGER_DATA, LOG_DEBUG);
//logger('notifier: encoded activity: ' . print_r($activity,true), LOGGER_DATA, LOG_DEBUG);
stringify_array_elms($recipients);
if(! $recipients) {
if (!$recipients) {
logger('no recipients');
return;
}
// logger('notifier: recipients: ' . print_r($recipients,true), LOGGER_NORMAL, LOG_DEBUG);
$env_recips = (($private) ? array() : null);
$env_recips = (($private) ? [] : null);
$details = q("select xchan_hash, xchan_network, xchan_addr, xchan_guid, xchan_guid_sig from xchan where xchan_hash in (" . protect_sprintf(implode(',',$recipients)) . ")");
$details = q("select xchan_hash, xchan_network, xchan_addr, xchan_guid, xchan_guid_sig from xchan where xchan_hash in (" . protect_sprintf(implode(',', $recipients)) . ")");
$recip_list = array();
if($details) {
foreach($details as $d) {
$recip_list = [];
if ($details) {
foreach ($details as $d) {
$recip_list[] = $d['xchan_addr'] . ' (' . $d['xchan_hash'] . ')';
if($private) {
if ($private) {
$env_recips[] = [
'guid' => $d['xchan_guid'],
'guid_sig' => $d['xchan_guid_sig'],
@@ -535,8 +526,8 @@ class Notifier {
];
call_hooks('notifier_process', $narr);
if($narr['queued']) {
foreach($narr['queued'] as $pq)
if ($narr['queued']) {
foreach ($narr['queued'] as $pq)
$deliveries[] = $pq;
}
@@ -546,26 +537,26 @@ class Notifier {
$env_recips = $narr['env_recips'];
$packet_recips = $narr['packet_recips'];
if(($private) && (! $env_recips)) {
if (($private) && (!$env_recips)) {
// shouldn't happen
logger('notifier: private message with no envelope recipients.' . print_r($argv,true), LOGGER_NORMAL, LOG_NOTICE);
logger('notifier: private message with no envelope recipients.' . print_r($argv, true), LOGGER_NORMAL, LOG_NOTICE);
}
logger('notifier: recipients (may be delivered to more if public): ' . print_r($recip_list,true), LOGGER_DEBUG);
logger('notifier: recipients (may be delivered to more if public): ' . print_r($recip_list, true), LOGGER_DEBUG);
// Now we have collected recipients (except for external mentions, FIXME)
// Let's reduce this to a set of hubs; checking that the site is not dead.
$hubs = q("select hubloc.*, site.site_crypto, site.site_flags, site.site_version, site.site_project, site.site_dead from hubloc left join site on site_url = hubloc_url
where hubloc_hash in (" . protect_sprintf(implode(',',$recipients)) . ")
where hubloc_hash in (" . protect_sprintf(implode(',', $recipients)) . ")
and hubloc_error = 0 and hubloc_deleted = 0"
);
// public posts won't make it to the local public stream unless there's a recipient on this site.
// This code block sees if it's a public post and localhost is missing, and if so adds an entry for the local sys channel to the $hubs list
if (! $private) {
if (!$private) {
$found_localhost = false;
if ($hubs) {
foreach ($hubs as $h) {
@@ -575,7 +566,7 @@ class Notifier {
}
}
}
if (! $found_localhost) {
if (!$found_localhost) {
$localhub = q("select hubloc.*, site.site_crypto, site.site_flags, site.site_version, site.site_project, site.site_dead from hubloc
left join site on site_url = hubloc_url where hubloc_id_url = '%s' and hubloc_error = 0 and hubloc_deleted = 0",
dbesc(z_root() . '/channel/sys')
@@ -586,7 +577,7 @@ class Notifier {
}
}
if(! $hubs) {
if (!$hubs) {
logger('notifier: no hubs', LOGGER_NORMAL, LOG_NOTICE);
return;
}
@@ -605,17 +596,17 @@ class Notifier {
$hub_env = []; // per-hub envelope so we don't broadcast the entire envelope to all
$dead = []; // known dead hubs - report them as undeliverable
foreach($hubs as $hub) {
foreach ($hubs as $hub) {
if (intval($hub['site_dead'])) {
$dead[] = $hub;
continue;
}
if($env_recips) {
foreach($env_recips as $er) {
if($hub['hubloc_hash'] === $er['hash']) {
if(! array_key_exists($hub['hubloc_host'] . $hub['hubloc_sitekey'], $hub_env)) {
if ($env_recips) {
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;
@@ -624,36 +615,36 @@ class Notifier {
}
if($hub['hubloc_network'] == 'zot') {
if(! in_array($hub['hubloc_sitekey'],$keys)) {
if ($hub['hubloc_network'] == 'zot') {
if (!in_array($hub['hubloc_sitekey'], $keys)) {
$hublist[] = $hub['hubloc_host'] . ' ' . $hub['hubloc_network'];
$dhubs[] = $hub;
$keys[] = $hub['hubloc_sitekey'];
}
}
else {
if(! in_array($hub['hubloc_url'],$urls)) {
if($hub['hubloc_url'] === z_root()) {
if (!in_array($hub['hubloc_url'], $urls)) {
if ($hub['hubloc_url'] === z_root()) {
//deliver to local hub first
array_unshift($hublist, $hub['hubloc_host'] . ' ' . $hub['hubloc_network']);
array_unshift($dhubs, $hub);
}
else {
$hublist[] = $hub['hubloc_host'] . ' ' . $hub['hubloc_network'];
$dhubs[] = $hub;
$dhubs[] = $hub;
}
$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) {
logger('notifier_hub: ' . $hub['hubloc_url'],LOGGER_DEBUG);
logger('notifier_hub: ' . $hub['hubloc_url'], LOGGER_DEBUG);
if(! in_array($hub['hubloc_network'], [ 'zot','zot6' ])) {
if (!in_array($hub['hubloc_network'], ['zot', 'zot6'])) {
$narr = [
'channel' => $channel,
'upstream' => $upstream,
@@ -680,9 +671,9 @@ class Notifier {
];
call_hooks('notifier_hub',$narr);
if($narr['queued']) {
foreach($narr['queued'] as $pq)
call_hooks('notifier_hub', $narr);
if ($narr['queued']) {
foreach ($narr['queued'] as $pq)
$deliveries[] = $pq;
}
continue;
@@ -698,11 +689,11 @@ class Notifier {
// will invoke a delivery to those connections which are connected to just that
// hub instance.
if($cmd === 'single_mail' || $cmd === 'single_activity') {
if ($cmd === 'single_mail' || $cmd === 'single_activity') {
continue;
}
if(! in_array($hub['hubloc_network'], [ 'zot','zot6' ])) {
if (!in_array($hub['hubloc_network'], ['zot', 'zot6'])) {
continue;
}
@@ -710,31 +701,31 @@ class Notifier {
// in the loop. The signature verification step can't handle dashes in the
// hashes.
$hash = random_string(48);
$hash = random_string(48);
$packet = null;
$pmsg = '';
if($packet_type === 'refresh' || $packet_type === 'purge') {
if($hub['hubloc_network'] === 'zot6') {
$packet = Libzot::build_packet($channel, $packet_type, ids_to_array($packet_recips,'hash'));
if ($packet_type === 'refresh' || $packet_type === 'purge') {
if ($hub['hubloc_network'] === 'zot6') {
$packet = Libzot::build_packet($channel, $packet_type, ids_to_array($packet_recips, 'hash'));
}
else {
$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' && $hub['hubloc_network'] === 'zot') {
$pmsg = get_pconfig($channel['channel_id'],'system','keychange');
$packet = zot_build_packet($channel,$packet_type,(($packet_recips) ? $packet_recips : null));
if ($packet_type === 'keychange' && $hub['hubloc_network'] === 'zot') {
$pmsg = get_pconfig($channel['channel_id'], 'system', 'keychange');
$packet = zot_build_packet($channel, $packet_type, (($packet_recips) ? $packet_recips : null));
}
elseif($packet_type === 'request' && $hub['hubloc_network'] === 'zot') {
$env = (($hub_env && $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']]) ? $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']] : '');
$packet = zot_build_packet($channel,$packet_type,$env,$hub['hubloc_sitekey'],$hub['site_crypto'],
$hash, array('message_id' => $request_message_id)
elseif ($packet_type === 'request' && $hub['hubloc_network'] === 'zot') {
$env = (($hub_env && $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']]) ? $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']] : '');
$packet = zot_build_packet($channel, $packet_type, $env, $hub['hubloc_sitekey'], $hub['site_crypto'],
$hash, ['message_id' => $request_message_id]
);
}
if($packet) {
if ($packet) {
Queue::insert(
[
'hash' => $hash,
@@ -750,11 +741,10 @@ class Notifier {
else {
$env = (($hub_env && $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']]) ? $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']] : '');
if($hub['hubloc_network'] === 'zot6') {
if ($hub['hubloc_network'] === 'zot6') {
$zenv = [];
if($env) {
foreach($env as $e) {
if ($env) {
foreach ($env as $e) {
$zenv[] = $e['hash'];
}
}
@@ -767,11 +757,11 @@ class Notifier {
// For public reshares, some comments to the reshare on the zot fork will not make it to zot6
// due to these different message models. This cannot be prevented at this time.
if($packet_type === 'activity' && $activity['type'] === 'Announce' && intval($target_item['item_private'])) {
if ($packet_type === 'activity' && $activity['type'] === 'Announce' && intval($target_item['item_private'])) {
continue;
}
$packet = Libzot::build_packet($channel,$packet_type,$zenv,$activity,'activitystreams',(($private) ? $hub['hubloc_sitekey'] : null),$hub['site_crypto']);
$packet = Libzot::build_packet($channel, $packet_type, $zenv, $activity, 'activitystreams', (($private) ? $hub['hubloc_sitekey'] : null), $hub['site_crypto']);
}
else {
// currently zot6 delivery is only performed on normal items and not sync items or mail or anything else
@@ -779,28 +769,28 @@ class Notifier {
// with before switching to zot6 as the primary zot6 handler checks for the existence of a message delivery report
// to trigger dequeue'ing
$z6 = (($encoded_item && $encoded_item['type'] === 'activity' && (! array_key_exists('allow_cid',$encoded_item))) ? true : false);
if($z6) {
$packet = zot6_build_packet($channel,'notify',$env, json_encode($encoded_item), (($private) ? $hub['hubloc_sitekey'] : null), $hub['site_crypto'],$hash);
$z6 = (($encoded_item && $encoded_item['type'] === 'activity' && (!array_key_exists('allow_cid', $encoded_item))) ? true : false);
if ($z6) {
$packet = zot6_build_packet($channel, 'notify', $env, json_encode($encoded_item), (($private) ? $hub['hubloc_sitekey'] : null), $hub['site_crypto'], $hash);
}
else {
$packet = zot_build_packet($channel,'notify',$env, (($private) ? $hub['hubloc_sitekey'] : null), $hub['site_crypto'],$hash);
$packet = zot_build_packet($channel, 'notify', $env, (($private) ? $hub['hubloc_sitekey'] : null), $hub['site_crypto'], $hash);
}
}
// remove this after most hubs have updated to version 5.0
if(stripos($hub['site_project'], 'hubzilla') !== false && version_compare($hub['site_version'], '4.7.3', '<=')) {
if($encoded_item['type'] === 'mail') {
$encoded_item['from']['network'] = 'zot';
if (stripos($hub['site_project'], 'hubzilla') !== false && version_compare($hub['site_version'], '4.7.3', '<=')) {
if ($encoded_item['type'] === 'mail') {
$encoded_item['from']['network'] = 'zot';
$encoded_item['from']['guid_sig'] = str_replace('sha256.', '', $encoded_item['from']['guid_sig']);
}
else {
$encoded_item['owner']['network'] = 'zot';
$encoded_item['owner']['network'] = 'zot';
$encoded_item['owner']['guid_sig'] = str_replace('sha256.', '', $encoded_item['owner']['guid_sig']);
if(strpos($encoded_item['author']['url'], z_root()) === 0) {
$encoded_item['author']['network'] = 'zot';
if (strpos($encoded_item['author']['url'], z_root()) === 0) {
$encoded_item['author']['network'] = 'zot';
$encoded_item['author']['guid_sig'] = str_replace('sha256.', '', $encoded_item['author']['guid_sig']);
}
}
@@ -819,7 +809,7 @@ class Notifier {
);
// 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'))) {
q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan, dreport_queue ) values ( '%s','%s','%s','%s','%s','%s','%s' ) ",
dbesc($target_item['mid']),
dbesc($hub['hubloc_host']),
@@ -835,21 +825,21 @@ class Notifier {
$deliveries[] = $hash;
}
if($normal_mode) {
if ($normal_mode) {
$x = q("select * from hook where hook = 'notifier_normal'");
if($x) {
Master::Summon( [ 'Deliver_hooks', $target_item['id'] ] );
if ($x) {
Master::Summon(['Deliver_hooks', $target_item['id']]);
}
}
if($deliveries)
if ($deliveries)
do_delivery($deliveries);
logger('notifier: basic loop complete.', LOGGER_DEBUG);
if ($dead) {
foreach ($dead as $deceased) {
if (is_array($target_item) && (! $target_item['item_deleted']) && (! get_config('system','disable_dreport'))) {
if (is_array($target_item) && (!$target_item['item_deleted']) && (!get_config('system', 'disable_dreport'))) {
q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_name, dreport_result, dreport_time, dreport_xchan, dreport_queue )
values ( '%s', '%s','%s','%s','%s','%s','%s','%s' ) ",
dbesc($target_item['mid']),
@@ -865,7 +855,7 @@ class Notifier {
}
}
call_hooks('notifier_end',$target_item);
call_hooks('notifier_end', $target_item);
logger('notifer: complete.');
return;

View File

@@ -11,14 +11,14 @@ require_once('include/dir_fns.php');
class Onedirsync {
static public function run($argc,$argv) {
static public function run($argc, $argv) {
logger('onedirsync: start ' . intval($argv[1]));
if(($argc > 1) && (intval($argv[1])))
if (($argc > 1) && (intval($argv[1])))
$update_id = intval($argv[1]);
if(! $update_id) {
if (!$update_id) {
logger('onedirsync: no update');
return;
}
@@ -27,9 +27,9 @@ class Onedirsync {
intval($update_id)
);
if(! $r)
if (!$r)
return;
if(($r[0]['ud_flags'] & UPDATE_FLAGS_UPDATED) || (! $r[0]['ud_addr']))
if (($r[0]['ud_flags'] & UPDATE_FLAGS_UPDATED) || (!$r[0]['ud_addr']))
return;
// Have we probed this channel more recently than the other directory server
@@ -41,8 +41,8 @@ class Onedirsync {
dbesc($r[0]['ud_date']),
intval(UPDATE_FLAGS_UPDATED)
);
if($x) {
$y = q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 and ud_date != '%s'",
if ($x) {
q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 and ud_date != '%s'",
intval(UPDATE_FLAGS_UPDATED),
dbesc($r[0]['ud_addr']),
intval(UPDATE_FLAGS_UPDATED),
@@ -59,8 +59,8 @@ class Onedirsync {
$h = Libzot::zot_record_preferred($h);
if(($h) && ($h['hubloc_status'] & HUBLOC_OFFLINE)) {
$y = q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 ",
if (($h) && ($h['hubloc_status'] & HUBLOC_OFFLINE)) {
q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 ",
intval(UPDATE_FLAGS_UPDATED),
dbesc($r[0]['ud_addr']),
intval(UPDATE_FLAGS_UPDATED)
@@ -72,7 +72,7 @@ class Onedirsync {
// we might have to pull this out some day, but for now update_directory_entry()
// runs zot_finger() and is kind of zot specific
if($h && ! in_array($h['hubloc_network'], ['zot6', 'zot']))
if ($h && !in_array($h['hubloc_network'], ['zot6', 'zot']))
return;
Libzotdir::update_directory_entry($r[0]);

View File

@@ -2,68 +2,70 @@
namespace Zotlabs\Daemon;
use Zotlabs\Lib\Activity;
use Zotlabs\Lib\ActivityStreams;
use Zotlabs\Lib\ASCollection;
use Zotlabs\Lib\Libzot;
require_once('include/zot.php');
require_once('include/socgraph.php');
class Onepoll {
static public function run($argc,$argv) {
static public function run($argc, $argv) {
logger('onepoll: start');
if(($argc > 1) && (intval($argv[1])))
if (($argc > 1) && (intval($argv[1])))
$contact_id = intval($argv[1]);
if(! $contact_id) {
if (!$contact_id) {
logger('onepoll: no contact');
return;
}
$d = datetime_convert();
$sql_extra = '';
$allow_feeds = get_config('system', 'feed_contacts');
if(!$allow_feeds) {
$sql_extra = ' and abook_feed = 0 ';
}
$contacts = q("SELECT abook.*, xchan.*, account.*
FROM abook LEFT JOIN account on abook_account = account_id left join xchan on xchan_hash = abook_xchan
where abook_id = %d
FROM abook LEFT JOIN account on abook_account = account_id left join xchan on xchan_hash = abook_xchan
where abook_id = %d $sql_extra
and abook_pending = 0 and abook_archived = 0 and abook_blocked = 0 and abook_ignored = 0
AND (( account_flags = %d ) OR ( account_flags = %d )) limit 1",
intval($contact_id),
intval(ACCOUNT_OK),
intval(ACCOUNT_UNVERIFIED)
);
);
if(! $contacts) {
if (!$contacts) {
logger('onepoll: abook_id not found: ' . $contact_id);
return;
}
$contact = $contacts[0];
$t = $contact['abook_updated'];
$contact = array_shift($contacts);
$importer_uid = $contact['abook_channel'];
$r = q("SELECT * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1",
intval($importer_uid)
);
if(! $r)
if (!$r)
return;
$importer = $r[0];
logger("onepoll: poll: ({$contact['id']}) IMPORTER: {$importer['xchan_name']}, CONTACT: {$contact['xchan_name']}");
$last_update = ((($contact['abook_updated'] === $contact['abook_created']) || ($contact['abook_updated'] <= NULL_DATE))
? datetime_convert('UTC','UTC','now - 7 days')
: datetime_convert('UTC','UTC',$contact['abook_updated'] . ' - 2 days')
$last_update = ((($contact['abook_updated'] === $contact['abook_created']) || ($contact['abook_updated'] <= NULL_DATE))
? datetime_convert('UTC', 'UTC', 'now - 7 days')
: datetime_convert('UTC', 'UTC', $contact['abook_updated'] . ' - 2 days')
);
if($contact['xchan_network'] === 'rss') {
if ($contact['xchan_network'] === 'rss') {
logger('onepoll: processing feed ' . $contact['xchan_name'], LOGGER_DEBUG);
$alive = handle_feed($importer['channel_id'],$contact_id,$contact['xchan_hash']);
$alive = handle_feed($importer['channel_id'], $contact_id, $contact['xchan_hash']);
if ($alive) {
q("update abook set abook_connected = '%s' where abook_id = %d",
dbesc(datetime_convert()),
@@ -72,22 +74,22 @@ class Onepoll {
}
return;
}
if(! in_array($contact['xchan_network'],['zot','zot6']))
if (!in_array($contact['xchan_network'], ['zot', 'zot6']))
return;
// update permissions
if($contact['xchan_network'] === 'zot6')
$x = Libzot::refresh($contact,$importer);
if ($contact['xchan_network'] === 'zot6')
$x = Libzot::refresh($contact, $importer);
if($contact['xchan_network'] === 'zot')
$x = zot_refresh($contact,$importer);
if ($contact['xchan_network'] === 'zot')
$x = zot_refresh($contact, $importer);
$responded = false;
$updated = datetime_convert();
$connected = datetime_convert();
if(! $x) {
if (!$x) {
// mark for death by not updating abook_connected, this is caught in include/poller.php
q("update abook set abook_updated = '%s' where abook_id = %d",
dbesc($updated),
@@ -103,83 +105,112 @@ class Onepoll {
$responded = true;
}
if(! $responded)
if (!$responded)
return;
if($contact['xchan_connurl']) {
$fetch_feed = true;
$x = null;
$fetch_feed = true;
$x = null;
// They haven't given us permission to see their stream
// They haven't given us permission to see their stream
$can_view_stream = intval(get_abconfig($importer_uid,$contact['abook_xchan'],'their_perms','view_stream'));
$can_view_stream = intval(get_abconfig($importer_uid, $contact['abook_xchan'], 'their_perms', 'view_stream'));
if(! $can_view_stream)
$fetch_feed = false;
if (!$can_view_stream)
$fetch_feed = false;
// we haven't given them permission to send us their stream
// we haven't given them permission to send us their stream
$can_send_stream = intval(get_abconfig($importer_uid,$contact['abook_xchan'],'my_perms','send_stream'));
if(! $can_send_stream)
$fetch_feed = false;
$can_send_stream = intval(get_abconfig($importer_uid, $contact['abook_xchan'], 'my_perms', 'send_stream'));
if($fetch_feed) {
if (!$can_send_stream)
$fetch_feed = false;
if(strpos($contact['xchan_connurl'],z_root()) === 0) {
// 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 ])
])
];
}
if ($fetch_feed && $contact['xchan_network'] !== 'zot') {
$max = intval(get_config('system', 'max_imported_posts', 30));
if (intval($max)) {
$cl = get_xconfig($contact['abook_xchan'], 'activitypub', 'collections');
if (is_array($cl) && $cl) {
$url = ((array_key_exists('outbox', $cl)) ? $cl['outbox'] : '');
}
else {
// remote fetch
$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 ]);
$url = str_replace('/poco/', '/zotfeed/', $contact['xchan_connurl']);
}
logger('feed_update: ' . print_r($x,true), LOGGER_DATA);
}
if(($x) && ($x['success'])) {
$total = 0;
logger('onepoll: feed update ' . $contact['xchan_name'] . ' ' . $feedurl);
$j = json_decode($x['body'],true);
if($j['success'] && $j['messages']) {
foreach($j['messages'] as $message) {
$results = process_delivery(array('hash' => $contact['xchan_hash']), get_item_elements($message),
array(array('hash' => $importer['xchan_hash'])), false);
logger('onepoll: feed_update: process_delivery: ' . print_r($results,true), LOGGER_DATA);
$total ++;
if ($url) {
logger('fetching outbox');
$url = $url . '?date_begin=' . urlencode($last_update);
$obj = new ASCollection($url, $importer, 0, $max);
$messages = $obj->get();
if ($messages) {
foreach ($messages as $message) {
if (is_string($message)) {
$message = Activity::fetch($message, $importer);
}
$AS = new ActivityStreams($message);
if ($AS->is_valid() && is_array($AS->obj)) {
$item = Activity::decode_note($AS);
Activity::store($importer, $contact['abook_xchan'], $AS, $item);
}
}
}
logger("onepoll: $total messages processed");
}
}
}
/* if ($fetch_feed) {
if (strpos($contact['xchan_connurl'], z_root()) === 0) {
// 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
$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);
}
if (($x) && ($x['success'])) {
$total = 0;
logger('onepoll: feed update ' . $contact['xchan_name'] . ' ' . $feedurl);
$j = json_decode($x['body'], true);
if ($j['success'] && $j['messages']) {
foreach ($j['messages'] as $message) {
$results = process_delivery(['hash' => $contact['xchan_hash']], get_item_elements($message),
[['hash' => $importer['xchan_hash']]], false);
logger('onepoll: feed_update: process_delivery: ' . print_r($results, true), LOGGER_DATA);
$total++;
}
logger("onepoll: $total messages processed");
}
}
*/
// update the poco details for this connection
if($contact['xchan_connurl']) {
$r = q("SELECT xlink_id from xlink
where xlink_xchan = '%s' and xlink_updated > %s - INTERVAL %s and xlink_static = 0 limit 1",
intval($contact['xchan_hash']),
db_utcnow(), db_quoteinterval('1 DAY')
);
if(! $r) {
poco_load($contact['xchan_hash'],$contact['xchan_connurl']);
}
$r = q("SELECT xlink_id from xlink where xlink_xchan = '%s' and xlink_updated > %s - INTERVAL %s and xlink_static = 0 limit 1",
intval($contact['xchan_hash']),
db_utcnow(), db_quoteinterval('1 DAY')
);
if (!$r) {
poco_load($contact['xchan_hash'], $contact['xchan_connurl']);
}
return;

View File

@@ -4,53 +4,50 @@ namespace Zotlabs\Daemon;
class Poller {
static public function run($argc,$argv) {
static public function run($argc, $argv) {
$maxsysload = intval(get_config('system','maxloadavg'));
if($maxsysload < 1)
$maxsysload = intval(get_config('system', 'maxloadavg'));
if ($maxsysload < 1)
$maxsysload = 50;
if(function_exists('sys_getloadavg')) {
if (function_exists('sys_getloadavg')) {
$load = sys_getloadavg();
if(intval($load[0]) > $maxsysload) {
if (intval($load[0]) > $maxsysload) {
logger('system: load ' . $load . ' too high. Poller deferred to next scheduled run.');
return;
}
}
$interval = intval(get_config('system','poll_interval'));
if(! $interval)
$interval = ((get_config('system','delivery_interval') === false) ? 3 : intval(get_config('system','delivery_interval')));
$interval = intval(get_config('system', 'poll_interval'));
if (!$interval)
$interval = ((get_config('system', 'delivery_interval') === false) ? 3 : intval(get_config('system', 'delivery_interval')));
// Check for a lockfile. If it exists, but is over an hour old, it's stale. Ignore it.
$lockfile = 'store/[data]/poller';
if((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 3600))
&& (! get_config('system','override_poll_lockfile'))) {
if ((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 3600))
&& (!get_config('system', 'override_poll_lockfile'))) {
logger("poller: Already running");
return;
}
// Create a lockfile. Needs two vars, but $x doesn't need to contain anything.
$x = '';
file_put_contents($lockfile, $x);
logger('poller: start');
$manual_id = 0;
$generation = 0;
$force = false;
$force = false;
$restart = false;
if(($argc > 1) && ($argv[1] == 'force'))
if (($argc > 1) && ($argv[1] == 'force'))
$force = true;
if(($argc > 1) && ($argv[1] == 'restart')) {
$restart = true;
if (($argc > 1) && ($argv[1] == 'restart')) {
$generation = intval($argv[2]);
if(! $generation)
if (!$generation)
return;
}
if(($argc > 1) && intval($argv[1])) {
if (($argc > 1) && intval($argv[1])) {
$manual_id = intval($argv[1]);
$force = true;
}
@@ -59,17 +56,15 @@ class Poller {
reload_plugins();
$d = datetime_convert();
// Only poll from those with suitable relationships
$abandon_sql = (($abandon_days)
? sprintf(" AND account_lastlog > %s - INTERVAL %s ", db_utcnow(), db_quoteinterval(intval($abandon_days).' DAY'))
: ''
$abandon_days = intval(get_config('system', 'account_abandon_days', 0));
$abandon_sql = (($abandon_days)
? sprintf(" AND account_lastlog > %s - INTERVAL %s ", db_utcnow(), db_quoteinterval(intval($abandon_days) . ' DAY'))
: ''
);
$randfunc = db_getfunc('RAND');
$contacts = q("SELECT abook.abook_updated, abook.abook_connected, abook.abook_feed,
abook.abook_channel, abook.abook_id, abook.abook_archived, abook.abook_pending,
abook.abook_ignored, abook.abook_blocked,
@@ -84,119 +79,117 @@ class Poller {
intval(ACCOUNT_UNVERIFIED) // FIXME
);
if($contacts) {
foreach($contacts as $contact) {
if ($contacts) {
foreach ($contacts as $contact) {
$update = false;
$update = false;
$t = $contact['abook_updated'];
$c = $contact['abook_connected'];
if(intval($contact['abook_feed'])) {
$min = service_class_fetch($contact['abook_channel'],'minimum_feedcheck_minutes');
if(! $min)
$min = intval(get_config('system','minimum_feedcheck_minutes'));
if(! $min)
if (intval($contact['abook_feed'])) {
$min = service_class_fetch($contact['abook_channel'], 'minimum_feedcheck_minutes');
if (!$min)
$min = intval(get_config('system', 'minimum_feedcheck_minutes'));
if (!$min)
$min = 60;
$x = datetime_convert('UTC','UTC',"now - $min minutes");
if($c < $x) {
Master::Summon(array('Onepoll',$contact['abook_id']));
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
$x = datetime_convert('UTC', 'UTC', "now - $min minutes");
if ($c < $x) {
Master::Summon(['Onepoll', $contact['abook_id']]);
if ($interval)
@time_sleep_until(microtime(true) + (float)$interval);
}
continue;
}
if(! in_array($contact['xchan_network'],['zot','zot6']))
if (!in_array($contact['xchan_network'], ['zot', 'zot6']))
continue;
if($c == $t) {
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day"))
if ($c == $t) {
if (datetime_convert('UTC', 'UTC', 'now') > datetime_convert('UTC', 'UTC', $t . " + 1 day"))
$update = true;
}
else {
// if we've never connected with them, start the mark for death countdown from now
if($c <= NULL_DATE) {
$r = q("update abook set abook_connected = '%s' where abook_id = %d",
if ($c <= NULL_DATE) {
q("update abook set abook_connected = '%s' where abook_id = %d",
dbesc(datetime_convert()),
intval($contact['abook_id'])
);
$c = datetime_convert();
$c = datetime_convert();
$update = true;
}
// He's dead, Jim
if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 30 day")) > 0) {
$r = q("update abook set abook_archived = 1 where abook_id = %d",
if (strcmp(datetime_convert('UTC', 'UTC', 'now'), datetime_convert('UTC', 'UTC', $c . " + 30 day")) > 0) {
q("update abook set abook_archived = 1 where abook_id = %d",
intval($contact['abook_id'])
);
$update = false;
continue;
}
if(intval($contact['abook_archived'])) {
$update = false;
if (intval($contact['abook_archived'])) {
continue;
}
// might be dead, so maybe don't poll quite so often
// recently deceased, so keep up the regular schedule for 3 days
if((strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 3 day")) > 0)
&& (strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 1 day")) > 0))
if ((strcmp(datetime_convert('UTC', 'UTC', 'now'), datetime_convert('UTC', 'UTC', $c . " + 3 day")) > 0)
&& (strcmp(datetime_convert('UTC', 'UTC', 'now'), datetime_convert('UTC', 'UTC', $t . " + 1 day")) > 0))
$update = true;
// After that back off and put them on a morphine drip
if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 2 day")) > 0) {
if (strcmp(datetime_convert('UTC', 'UTC', 'now'), datetime_convert('UTC', 'UTC', $t . " + 2 day")) > 0) {
$update = true;
}
}
if(intval($contact['abook_pending']) || intval($contact['abook_archived']) || intval($contact['abook_ignored']) || intval($contact['abook_blocked']))
if (intval($contact['abook_pending']) || intval($contact['abook_archived']) || intval($contact['abook_ignored']) || intval($contact['abook_blocked']))
continue;
if((! $update) && (! $force))
continue;
if ((!$update) && (!$force))
continue;
Master::Summon(array('Onepoll',$contact['abook_id']));
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
Master::Summon(['Onepoll', $contact['abook_id']]);
if ($interval)
@time_sleep_until(microtime(true) + (float)$interval);
}
}
$dirmode = intval(get_config('system', 'directory_mode'));
if($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) {
if ($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) {
$r = q("SELECT u.ud_addr, u.ud_id, u.ud_last FROM updates AS u INNER JOIN (SELECT ud_addr, max(ud_id) AS ud_id FROM updates WHERE ( ud_flags & %d ) = 0 AND ud_addr != '' AND ( ud_last <= '%s' OR ud_last > %s - INTERVAL %s ) GROUP BY ud_addr) AS s ON s.ud_id = u.ud_id ",
intval(UPDATE_FLAGS_UPDATED),
dbesc(NULL_DATE),
db_utcnow(), db_quoteinterval('7 DAY')
);
if($r) {
foreach($r as $rr) {
if ($r) {
foreach ($r as $rr) {
// If they didn't respond when we attempted before, back off to once a day
// After 7 days we won't bother anymore
if($rr['ud_last'] > NULL_DATE)
if($rr['ud_last'] > datetime_convert('UTC','UTC', 'now - 1 day'))
if ($rr['ud_last'] > NULL_DATE)
if ($rr['ud_last'] > datetime_convert('UTC', 'UTC', 'now - 1 day'))
continue;
Master::Summon(array('Onedirsync',$rr['ud_id']));
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
Master::Summon(['Onedirsync', $rr['ud_id']]);
if ($interval)
@time_sleep_until(microtime(true) + (float)$interval);
}
}
}
}
set_config('system','lastpoll',datetime_convert());
set_config('system', 'lastpoll', datetime_convert());
//All done - clear the lockfile

View File

@@ -7,12 +7,12 @@ require_once('include/zot.php');
class Queue {
static public function run($argc,$argv) {
static public function run($argc, $argv) {
require_once('include/items.php');
require_once('include/bbcode.php');
if($argc > 1)
if ($argc > 1)
$queue_id = $argv[1];
else
$queue_id = EMPTY_STR;
@@ -25,10 +25,9 @@ class Queue {
$r = q("select outq_posturl from outq where outq_created < %s - INTERVAL %s",
db_utcnow(), db_quoteinterval('3 DAY')
);
if($r) {
foreach($r as $rr) {
$site_url = '';
$h = parse_url($rr['outq_posturl']);
if ($r) {
foreach ($r as $rr) {
$h = parse_url($rr['outq_posturl']);
$desturl = $h['scheme'] . '://' . $h['host'] . (($h['port']) ? ':' . $h['port'] : '');
q("update site set site_dead = 1 where site_dead = 0 and site_url = '%s' and site_update < %s - INTERVAL %s",
dbesc($desturl),
@@ -37,11 +36,11 @@ class Queue {
}
}
$r = q("DELETE FROM outq WHERE outq_created < %s - INTERVAL %s",
q("DELETE FROM outq WHERE outq_created < %s - INTERVAL %s",
db_utcnow(), db_quoteinterval('3 DAY')
);
if($queue_id) {
if ($queue_id) {
$r = q("SELECT * FROM outq WHERE outq_hash = '%s' LIMIT 1",
dbesc($queue_id)
);
@@ -54,7 +53,7 @@ class Queue {
// so that we don't start off a thousand deliveries for a couple of dead hubs.
// The zot driver will deliver everything destined for a single hub once contact is made (*if* contact is made).
// Other drivers will have to do something different here and may need their own query.
// Note: this requires some tweaking as new posts to long dead hubs once a day will keep them in the
// "every 15 minutes" category. We probably need to prioritise them when inserted into the queue
// or just prior to this query based on recent and long-term delivery history. If we have good reason to believe
@@ -67,7 +66,7 @@ class Queue {
db_utcnow()
);
while ($r) {
foreach($r as $rv) {
foreach ($r as $rv) {
queue_deliver($rv);
}
$r = q("SELECT *,$sqlrandfunc as rn FROM outq WHERE outq_delivered = 0 and outq_scheduled < %s order by rn limit 1",
@@ -75,10 +74,10 @@ class Queue {
);
}
}
if(! $r)
if (!$r)
return;
foreach($r as $rv) {
foreach ($r as $rv) {
queue_deliver($rv);
}
}

View File

@@ -5,30 +5,30 @@ namespace Zotlabs\Daemon;
class Thumbnail {
static public function run($argc,$argv) {
static public function run($argc, $argv) {
if(! $argc == 2)
if (!$argc == 2)
return;
$c = q("select * from attach where hash = '%s' ",
dbesc($argv[1])
);
if(! $c)
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));
$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
'thumbnail' => null
];
/**
@@ -40,39 +40,39 @@ class Thumbnail {
* * \e string \b thumbnail
*/
call_hooks('thumbnail',$p);
if($p['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)) {
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')) {
if (method_exists($x, 'Match')) {
$matched = $x->Match($attach['filetype']);
if($matched) {
$x->Thumb($attach,$preview_style,$preview_width,$preview_height);
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) {
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'))
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);
$default_controller->Thumb($attach, $preview_style, $preview_width, $preview_height);
}
}
}

View File

@@ -0,0 +1,150 @@
<?php
namespace Zotlabs\Lib;
/**
* Class for dealing with fetching ActivityStreams collections (ordered or unordered, normal or paged).
* Construct with either an existing object or url and an optional channel to sign requests.
* $direction is 0 (default) to fetch from the beginning, and 1 to fetch from the end and reverse order the resultant array.
* An optional limit to the number of records returned may also be specified.
* Use $class->get() to return an array of collection members.
*/
class ASCollection {
private $channel = null;
private $nextpage = null;
private $limit = 0;
private $direction = 0; // 0 = forward, 1 = reverse
private $data = [];
private $history = [];
function __construct($obj, $channel = null, $direction = 0, $limit = 0) {
$this->channel = $channel;
$this->direction = $direction;
$this->limit = $limit;
if (is_array($obj)) {
$data = $obj;
}
if (is_string($obj)) {
$data = Activity::fetch($obj, $channel);
$this->history[] = $obj;
}
if (!is_array($data)) {
return;
}
if (!in_array($data['type'], ['Collection', 'OrderedCollection', 'OrderedCollectionPage'])) {
return false;
}
if ($this->direction) {
if (array_key_exists('last', $data) && $data['last']) {
$this->nextpage = $data['last'];
}
}
else {
if (array_key_exists('first', $data) && $data['first']) {
$this->nextpage = $data['first'];
}
}
if (isset($data['items']) && is_array($data['items'])) {
$this->data = (($this->direction) ? array_reverse($data['items']) : $data['items']);
}
elseif (isset($data['orderedItems']) && is_array($data['orderedItems'])) {
$this->data = (($this->direction) ? array_reverse($data['orderedItems']) : $data['orderedItems']);
}
if ($this->limit) {
if (count($this->data) > $limit) {
$this->data = array_slice($this->data, 0, $limit);
return;
}
}
do {
$x = $this->next();
} while ($x);
}
function get() {
return $this->data;
}
function next() {
if (!$this->nextpage) {
return false;
}
if (is_array($this->nextpage)) {
$data = $this->nextpage;
}
if (is_string($this->nextpage)) {
if (in_array($this->nextpage, $this->history)) {
// recursion detected
return false;
}
$data = Activity::fetch($this->nextpage, $this->channel);
$this->history[] = $this->nextpage;
}
if (!is_array($data)) {
return false;
}
if (!in_array($data['type'], ['CollectionPage', 'OrderedCollectionPage'])) {
return false;
}
$this->setnext($data);
if (isset($data['items']) && is_array($data['items'])) {
$this->data = array_merge($this->data, (($this->direction) ? array_reverse($data['items']) : $data['items']));
}
elseif (isset($data['orderedItems']) && is_array($data['orderedItems'])) {
$this->data = array_merge($this->data, (($this->direction) ? array_reverse($data['orderedItems']) : $data['orderedItems']));
}
if ($this->limit) {
if (count($this->data) > $this->limit) {
$this->data = array_slice($this->data, 0, $this->limit);
$this->nextpage = false;
return true;
}
}
return true;
}
function setnext($data) {
if ($this->direction) {
if (array_key_exists('prev', $data) && $data['prev']) {
$this->nextpage = $data['prev'];
}
elseif (array_key_exists('first', $data) && $data['first']) {
$this->nextpage = $data['first'];
}
else {
$this->nextpage = false;
}
}
else {
if (array_key_exists('next', $data) && $data['next']) {
$this->nextpage = $data['next'];
}
elseif (array_key_exists('last', $data) && $data['last']) {
$this->nextpage = $data['last'];
}
else {
$this->nextpage = false;
}
}
logger('nextpage: ' . $this->nextpage, LOGGER_DEBUG);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -7,25 +7,24 @@ namespace Zotlabs\Lib;
*
* Parses an ActivityStream JSON string.
*/
class ActivityStreams {
public $raw = null;
public $data = null;
public $valid = false;
public $deleted = false;
public $id = '';
public $parent_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 = null;
public $data = null;
public $valid = false;
public $deleted = false;
public $id = '';
public $parent_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;
/**
@@ -37,29 +36,29 @@ class ActivityStreams {
*/
function __construct($string) {
$this->raw = $string;
$this->raw = $string;
if(is_array($string)) {
if (is_array($string)) {
$this->data = $string;
}
else {
$this->data = json_decode($string, true);
}
if($this->data) {
if ($this->data) {
// verify and unpack JSalmon signature if present
if(is_array($this->data) && array_key_exists('signed',$this->data)) {
if (is_array($this->data) && array_key_exists('signed', $this->data)) {
$ret = JSalmon::verify($this->data);
$tmp = JSalmon::unpack($this->data['data']);
if($ret && $ret['success']) {
if($ret['signer']) {
$saved = json_encode($this->data,JSON_UNESCAPED_SLASHES);
$this->data = $tmp;
$this->data['signer'] = $ret['signer'];
if ($ret && $ret['success']) {
if ($ret['signer']) {
$saved = json_encode($this->data, JSON_UNESCAPED_SLASHES);
$this->data = $tmp;
$this->data['signer'] = $ret['signer'];
$this->data['signed_data'] = $saved;
if($ret['hubloc']) {
if ($ret['hubloc']) {
$this->data['hubloc'] = $ret['hubloc'];
}
}
@@ -68,57 +67,57 @@ class ActivityStreams {
$this->valid = true;
if(array_key_exists('type',$this->data) && array_key_exists('actor',$this->data) && array_key_exists('object',$this->data)) {
if($this->data['type'] === 'Delete' && $this->data['actor'] === $this->data['object']) {
if (array_key_exists('type', $this->data) && array_key_exists('actor', $this->data) && array_key_exists('object', $this->data)) {
if ($this->data['type'] === 'Delete' && $this->data['actor'] === $this->data['object']) {
$this->deleted = $this->data['actor'];
$this->valid = false;
$this->valid = false;
}
}
}
if($this->is_valid()) {
if ($this->is_valid()) {
$this->id = $this->get_property_obj('id');
$this->type = $this->get_primary_type();
$this->actor = $this->get_actor('actor','','');
$this->actor = $this->get_actor('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 && is_array($this->signer) && array_key_exists('publicKey',$this->signer) && is_array($this->signer['publicKey']) && $this->signer['publicKey']['publicKeyPem']) {
$this->sigok = LDSignatures::verify($this->data,$this->signer['publicKey']['publicKeyPem']);
if ($this->ldsig) {
$this->signer = $this->get_compound_property('creator', $this->ldsig);
if ($this->signer && is_array($this->signer) && array_key_exists('publicKey', $this->signer) && is_array($this->signer['publicKey']) && $this->signer['publicKey']['publicKeyPem']) {
$this->sigok = LDSignatures::verify($this->data, $this->signer['publicKey']['publicKeyPem']);
}
}
if(! $this->obj) {
$this->obj = $this->data;
if (!$this->obj) {
$this->obj = $this->data;
$this->type = 'Create';
if(! $this->actor) {
$this->actor = $this->get_actor('attributedTo',$this->obj);
if (!$this->actor) {
$this->actor = $this->get_actor('attributedTo', $this->obj);
}
}
// fetch recursive or embedded activities
if ($this->obj && is_array($this->obj) && array_key_exists('object',$this->obj)) {
if ($this->obj && is_array($this->obj) && array_key_exists('object', $this->obj)) {
$this->obj['object'] = $this->get_compound_property($this->obj['object']);
}
if($this->obj && is_array($this->obj) && $this->obj['actor'])
$this->obj['actor'] = $this->get_actor('actor',$this->obj);
if($this->tgt && is_array($this->tgt) && $this->tgt['actor'])
$this->tgt['actor'] = $this->get_actor('actor',$this->tgt);
if ($this->obj && is_array($this->obj) && $this->obj['actor'])
$this->obj['actor'] = $this->get_actor('actor', $this->obj);
if ($this->tgt && is_array($this->tgt) && $this->tgt['actor'])
$this->tgt['actor'] = $this->get_actor('actor', $this->tgt);
$this->parent_id = $this->get_property_obj('inReplyTo');
if((! $this->parent_id) && is_array($this->obj)) {
if ((!$this->parent_id) && is_array($this->obj)) {
$this->parent_id = $this->obj['inReplyTo'];
}
if((! $this->parent_id) && is_array($this->obj)) {
if ((!$this->parent_id) && is_array($this->obj)) {
$this->parent_id = $this->obj['id'];
}
}
@@ -147,19 +146,19 @@ class ActivityStreams {
function collect_recips($base = '', $namespace = '') {
$x = [];
$fields = [ 'to', 'cc', 'bto', 'bcc', 'audience'];
foreach($fields as $f) {
$fields = ['to', 'cc', 'bto', 'bcc', 'audience'];
foreach ($fields as $f) {
$y = $this->get_compound_property($f, $base, $namespace);
if($y) {
if (! is_array($this->raw_recips)) {
if ($y) {
if (!is_array($this->raw_recips)) {
$this->raw_recips = [];
}
if (! is_array($y)) {
$y = [ $y ];
if (!is_array($y)) {
$y = [$y];
}
$this->raw_recips[$f] = $y;
$x = array_merge($x, $y);
$x = array_merge($x, $y);
}
}
// not yet ready for prime time
@@ -167,21 +166,21 @@ class ActivityStreams {
return $x;
}
function expand($arr,$base = '',$namespace = '') {
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)) {
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);
$x = $this->get_compound_property($a, $base, $namespace);
if ($x) {
$ret = array_merge($ret, $x);
}
}
}
@@ -202,33 +201,33 @@ class ActivityStreams {
*/
function get_namespace($base, $namespace) {
if(! $namespace)
if (!$namespace)
return '';
$key = null;
foreach( [ $this->data, $base ] as $b ) {
if(! $b)
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)
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) {
if ($namespace === $ns) {
$key = '';
}
}
}
}
else {
if($namespace === $b['@context']) {
if ($namespace === $b['@context']) {
$key = '';
}
}
@@ -248,14 +247,14 @@ class ActivityStreams {
*/
function get_property_obj($property, $base = '', $namespace = '') {
$prefix = $this->get_namespace($base, $namespace);
if($prefix === null)
if ($prefix === null)
return null;
$base = (($base) ? $base : $this->data);
$base = (($base) ? $base : $this->data);
$propname = (($prefix) ? $prefix . ':' : '') . $property;
if(! is_array($base)) {
btlogger('not an array: ' . print_r($base,true));
if (!is_array($base)) {
btlogger('not an array: ' . print_r($base, true));
return null;
}
@@ -279,14 +278,14 @@ class ActivityStreams {
}
static function is_an_actor($s) {
return (in_array($s, [ 'Application','Group','Organization','Person','Service' ]));
return (in_array($s, ['Application', 'Group', 'Organization', 'Person', 'Service']));
}
static function is_response_activity($s) {
if (! $s) {
if (!$s) {
return false;
}
return (in_array($s, [ 'Like', 'Dislike', 'Flag', 'Block', 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject', 'emojiReaction', 'EmojiReaction', 'EmojiReact' ]));
return (in_array($s, ['Like', 'Dislike', 'Flag', 'Block', 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject', 'emojiReaction', 'EmojiReaction', 'EmojiReact']));
}
/**
@@ -298,9 +297,9 @@ class ActivityStreams {
* @return NULL|mixed
*/
function get_actor($property,$base='',$namespace = '') {
function get_actor($property, $base = '', $namespace = '') {
$x = $this->get_property_obj($property, $base, $namespace);
if($this->is_url($x)) {
if ($this->is_url($x)) {
// SECURITY: If we have already stored the actor profile, re-generate it
// from cached data - don't refetch it from the network
@@ -308,15 +307,15 @@ class ActivityStreams {
$r = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_id_url = '%s' limit 1",
dbesc($x)
);
if($r) {
$y = Activity::encode_person($r[0]);
if ($r) {
$y = Activity::encode_person($r[0]);
$y['cached'] = true;
return $y;
}
}
$actor = $this->get_compound_property($property,$base,$namespace,true);
if(is_array($actor) && self::is_an_actor($actor['type'])) {
if(array_key_exists('id',$actor) && (! array_key_exists('inbox',$actor))) {
$actor = $this->get_compound_property($property, $base, $namespace, true);
if (is_array($actor) && self::is_an_actor($actor['type'])) {
if (array_key_exists('id', $actor) && (!array_key_exists('inbox', $actor))) {
$actor = $this->fetch_property($actor['id']);
}
return $actor;
@@ -336,7 +335,7 @@ class ActivityStreams {
*/
function get_compound_property($property, $base = '', $namespace = '', $first = false) {
$x = $this->get_property_obj($property, $base, $namespace);
if($this->is_url($x)) {
if ($this->is_url($x)) {
$y = $this->fetch_property($x);
if (is_array($y)) {
$x = $y;
@@ -345,22 +344,22 @@ class ActivityStreams {
// verify and unpack JSalmon signature if present
if(is_array($x) && array_key_exists('signed',$x)) {
if (is_array($x) && array_key_exists('signed', $x)) {
$ret = JSalmon::verify($x);
$tmp = JSalmon::unpack($x['data']);
if($ret && $ret['success']) {
if($ret['signer']) {
$saved = json_encode($x,JSON_UNESCAPED_SLASHES);
$x = $tmp;
$x['signer'] = $ret['signer'];
if ($ret && $ret['success']) {
if ($ret['signer']) {
$saved = json_encode($x, JSON_UNESCAPED_SLASHES);
$x = $tmp;
$x['signer'] = $ret['signer'];
$x['signed_data'] = $saved;
if($ret['hubloc']) {
if ($ret['hubloc']) {
$x['hubloc'] = $ret['hubloc'];
}
}
}
}
if($first && is_array($x) && array_key_exists(0,$x)) {
if ($first && is_array($x) && array_key_exists(0, $x)) {
return $x[0];
}
@@ -374,7 +373,7 @@ class ActivityStreams {
* @return boolean
*/
function is_url($url) {
if(($url) && (! is_array($url)) && (strpos($url, 'http') === 0)) {
if (($url) && (!is_array($url)) && (strpos($url, 'http') === 0)) {
return true;
}
@@ -389,13 +388,13 @@ class ActivityStreams {
* @return NULL|mixed
*/
function get_primary_type($base = '', $namespace = '') {
if(! $base)
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) {
if (is_array($x)) {
foreach ($x as $y) {
if (strpos($y, ':') === false) {
return $y;
}
}
@@ -409,15 +408,32 @@ class ActivityStreams {
return $x;
}
static function is_as_request() {
static function is_as_request($channel = null) {
$x = getBestSupportedMimeType([
'application/ld+json;profile="https://www.w3.org/ns/activitystreams"',
'application/activity+json',
'application/ld+json;profile="http://www.w3.org/ns/activitystreams"'
]);
$hookdata = [];
if ($channel)
$hookdata['channel'] = $channel;
return(($x) ? true : false);
$hookdata['data'] = ['application/x-zot-activity+json'];
call_hooks('is_as_request', $hookdata);
$x = getBestSupportedMimeType($hookdata['data']);
return (($x) ? true : false);
}
static function get_accept_header_string($channel = null) {
$hookdata = [];
if ($channel)
$hookdata['channel'] = $channel;
$hookdata['data'] = 'application/x-zot-activity+json';
call_hooks('get_accept_header_string', $hookdata);
return $hookdata['data'];
}

View File

@@ -307,7 +307,7 @@ class Apps {
}
}
}
if($ret) {
if(isset($ret)) {
if($translate)
self::translate_system_apps($ret);
@@ -524,7 +524,7 @@ class Apps {
}
elseif(remote_channel()) {
$observer = \App::get_observer();
if($observer && $observer['xchan_network'] === 'zot') {
if($observer && in_array($observer['xchan_network'], ['zot6', 'zot'])) {
// some folks might have xchan_url redirected offsite, use the connurl
$x = parse_url($observer['xchan_connurl']);
if($x) {

206
Zotlabs/Lib/Crypto.php Normal file
View File

@@ -0,0 +1,206 @@
<?php
namespace Zotlabs\Lib;
use Exception;
class Crypto {
public static $openssl_algorithms = [
// zot6 nickname, opensslname, keylength, ivlength
['aes256ctr', 'aes-256-ctr', 32, 16],
['camellia256cfb', 'camellia-256-cfb', 32, 16],
['cast5cfb', 'cast5-cfb', 16, 8],
['aes256cbc', 'aes-256-cbc', 32, 16] // remove after legacy zot has been sunset
];
public static function methods() {
$ret = [];
foreach (self::$openssl_algorithms as $ossl) {
$ret[] = $ossl[0] . '.oaep';
}
call_hooks('crypto_methods', $ret);
return $ret;
}
public static function signing_methods() {
$ret = ['sha256'];
call_hooks('signing_methods', $ret);
return $ret;
}
public static function new_keypair($bits) {
$openssl_options = [
'digest_alg' => 'sha1',
'private_key_bits' => $bits,
'encrypt_key' => false
];
$conf = get_config('system', 'openssl_conf_file');
if ($conf) {
$openssl_options['config'] = $conf;
}
$result = openssl_pkey_new($openssl_options);
if (empty($result)) {
return false;
}
// Get private key
$response = ['prvkey' => '', 'pubkey' => ''];
openssl_pkey_export($result, $response['prvkey']);
// Get public key
$pkey = openssl_pkey_get_details($result);
$response['pubkey'] = $pkey["key"];
return $response;
}
public static function sign($data, $key, $alg = 'sha256') {
if (!$key) {
return false;
}
$sig = '';
openssl_sign($data, $sig, $key, $alg);
return $sig;
}
public static function verify($data, $sig, $key, $alg = 'sha256') {
if (!$key) {
return false;
}
try {
$verify = openssl_verify($data, $sig, $key, $alg);
} catch (Exception $e) {
$verify = (-1);
}
if ($verify === (-1)) {
while ($msg = openssl_error_string()) {
logger('openssl_verify: ' . $msg, LOGGER_NORMAL, LOG_ERR);
}
btlogger('openssl_verify: key: ' . $key, LOGGER_DEBUG, LOG_ERR);
}
return (($verify > 0) ? true : false);
}
public static function encapsulate($data, $pubkey, $alg) {
if (!($alg && $pubkey)) {
return $data;
}
$alg_base = $alg;
$padding = OPENSSL_PKCS1_PADDING;
$exts = explode('.', $alg);
if (count($exts) > 1) {
switch ($exts[1]) {
case 'oaep':
$padding = OPENSSL_PKCS1_OAEP_PADDING;
break;
default:
break;
}
$alg_base = $exts[0];
}
$method = null;
foreach (self::$openssl_algorithms as $ossl) {
if ($ossl[0] === $alg_base) {
$method = $ossl;
break;
}
}
if ($method) {
$result = ['encrypted' => true];
$key = openssl_random_pseudo_bytes(256);
$iv = openssl_random_pseudo_bytes(256);
$key1 = substr($key, 0, $method[2]);
$iv1 = substr($iv, 0, $method[3]);
$result['data'] = base64url_encode(openssl_encrypt($data, $method[1], $key1, OPENSSL_RAW_DATA, $iv1), true);
openssl_public_encrypt($key, $k, $pubkey, $padding);
openssl_public_encrypt($iv, $i, $pubkey, $padding);
$result['alg'] = $alg;
$result['key'] = base64url_encode($k, true);
$result['iv'] = base64url_encode($i, true);
return $result;
}
else {
$x = ['data' => $data, 'pubkey' => $pubkey, 'alg' => $alg, 'result' => $data];
call_hooks('crypto_encapsulate', $x);
return $x['result'];
}
}
public static function unencapsulate($data, $prvkey) {
if (!(is_array($data) && array_key_exists('encrypted', $data) && array_key_exists('alg', $data) && $data['alg'])) {
logger('not encrypted');
return $data;
}
$alg_base = $data['alg'];
$padding = OPENSSL_PKCS1_PADDING;
$exts = explode('.', $data['alg']);
if (count($exts) > 1) {
switch ($exts[1]) {
case 'oaep':
$padding = OPENSSL_PKCS1_OAEP_PADDING;
break;
default:
break;
}
$alg_base = $exts[0];
}
$method = null;
foreach (self::$openssl_algorithms as $ossl) {
if ($ossl[0] === $alg_base) {
$method = $ossl;
break;
}
}
if ($method) {
openssl_private_decrypt(base64url_decode($data['key']), $k, $prvkey, $padding);
openssl_private_decrypt(base64url_decode($data['iv']), $i, $prvkey, $padding);
return openssl_decrypt(base64url_decode($data['data']), $method[1], substr($k, 0, $method[2]), OPENSSL_RAW_DATA, substr($i, 0, $method[3]));
}
else {
$x = ['data' => $data, 'prvkey' => $prvkey, 'alg' => $data['alg'], 'result' => $data];
call_hooks('crypto_unencapsulate', $x);
return $x['result'];
}
}
}

View File

@@ -43,7 +43,7 @@ class Enotify {
dbesc($params['to_xchan'])
);
}
if ($x & $y) {
if ($x && $y) {
$sender = $x[0];
$recip = $y[0];
} else {

55
Zotlabs/Lib/Hashpath.php Normal file
View File

@@ -0,0 +1,55 @@
<?php
namespace Zotlabs\Lib;
/*
* Zotlabs\Lib\Hashpath
*
* Creates hashed directory structures for fast access and resistance to overloading any single directory with files.
*
* Takes a $hash which could be any string
* a $prefix which is where to place the hash directory in the filesystem, default is current directory
* use an empty string for $prefix to place hash directories directly off the root directory
* an optional $depth and $slice (default is 2) to indicate the hash level
* $depth = 1, 256 directories, suitable for < 384K records/files
* $depth = 2, 65536 directories, suitable for < 98M records/files
* $depth = 3, 16777216 directories, suitable for < 2.5B records/files
* ...
* The total number of records anticipated divided by the number of hash directories should generally be kept to
* less than 1500 entries for optimum performance though this varies by operating system and filesystem type.
* ext4 uses 32 bit inode numbers (~4B record limit) so use caution or alternative filesystem types with $depth above 3.
* an optional $mkdir (boolean) to recursively create the directory (ignoring errors) before returning
*
* examples: for a $hash of 'abcdefg' and prefix of 'path' the following paths are returned for $depth = 1 and $depth = 3
* path/7d/7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a
* path/7d/1a/54/7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a
*
* see also: boot.php:os_mkdir() - here we provide the equivalent of mkdir -p with permissions of 770.
*
*/
class Hashpath {
static function path($hash, $prefix = '.', $depth = 1, $slice = 2, $mkdir = true, $alg = false) {
if ($alg)
$hash = hash($alg, $hash);
$start = 0;
if ($depth < 1)
$depth = 1;
$sluglen = $depth * $slice;
do {
$slug = substr($hash, $start, $slice);
$prefix .= '/' . $slug;
$start += $slice;
$sluglen -= $slice;
}
while ($sluglen);
if ($mkdir)
os_mkdir($prefix, STORAGE_DEFAULT_PERMISSIONS, true);
return $prefix . '/' . $hash;
}
}

View File

@@ -18,7 +18,7 @@ class JSalmon {
$precomputed = '.' . base64url_encode($data_type,true) . '.YmFzZTY0dXJs.UlNBLVNIQTI1Ng';
$signature = base64url_encode(rsa_sign($data . $precomputed, $key), true);
$signature = base64url_encode(Crypto::sign($data . $precomputed, $key), true);
return ([
'signed' => true,
@@ -54,7 +54,7 @@ class JSalmon {
$key = HTTPSig::get_key(EMPTY_STR,'zot6',base64url_decode($x['sigs']['key_id']));
logger('key: ' . print_r($key,true));
if($key['portable_id'] && $key['public_key']) {
if(rsa_verify($signed_data,base64url_decode($x['sigs']['value']),$key['public_key'])) {
if(Crypto::verify($signed_data,base64url_decode($x['sigs']['value']),$key['public_key'])) {
logger('verified');
$ret = [ 'success' => true, 'signer' => $key['portable_id'], 'hubloc' => $key['hubloc'] ];
}

99
Zotlabs/Lib/Keyutils.php Normal file
View File

@@ -0,0 +1,99 @@
<?php
namespace Zotlabs\Lib;
use phpseclib\Crypt\RSA;
use phpseclib\Math\BigInteger;
/**
* Keyutils
* Convert RSA keys between various formats
*/
class Keyutils {
/**
* @param string $m modulo
* @param string $e exponent
* @return string
*/
public static function meToPem($m, $e) {
$rsa = new RSA();
$rsa->loadKey([
'e' => new BigInteger($e, 256),
'n' => new BigInteger($m, 256)
]);
return $rsa->getPublicKey();
}
/**
* @param string key
* @return string
*/
public static function rsaToPem($key) {
$rsa = new RSA();
$rsa->setPublicKey($key);
return $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS8);
}
/**
* @param string key
* @return string
*/
public static function pemToRsa($key) {
$rsa = new RSA();
$rsa->setPublicKey($key);
return $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1);
}
/**
* @param string $key key
* @param string $m reference modulo
* @param string $e reference exponent
*/
public static function pemToMe($key, &$m, &$e) {
$rsa = new RSA();
$rsa->loadKey($key);
$rsa->setPublicKey();
$m = $rsa->modulus->toBytes();
$e = $rsa->exponent->toBytes();
}
/**
* @param string $pubkey
* @return string
*/
public static function salmonKey($pubkey) {
self::pemToMe($pubkey, $m, $e);
return 'RSA' . '.' . base64url_encode($m, true) . '.' . base64url_encode($e, true);
}
/**
* @param string $key
* @return string
*/
public static function convertSalmonKey($key) {
if (strstr($key, ','))
$rawkey = substr($key, strpos($key, ',') + 1);
else
$rawkey = substr($key, 5);
$key_info = explode('.', $rawkey);
$m = base64url_decode($key_info[1]);
$e = base64url_decode($key_info[2]);
return self::meToPem($m, $e);
}
}

View File

@@ -12,7 +12,7 @@ class LDSignatures {
$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);
$x = Crypto::verify($ohash . $dhash,base64_decode($data['signature']['signatureValue']), $pubkey);
logger('LD-verify: ' . intval($x));
return $x;
@@ -35,11 +35,11 @@ class LDSignatures {
$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']));
$options['signatureValue'] = base64_encode(Crypto::sign($ohash . $dhash,$channel['channel_prvkey']));
$signed = array_merge([
'@context' => [
ACTIVITYSTREAMS_JSONLD_REV,
'@context' => [
ACTIVITYSTREAMS_JSONLD_REV,
'https://w3id.org/security/v1' ],
],$options);
@@ -88,7 +88,7 @@ class LDSignatures {
return '';
jsonld_set_document_loader('jsonld_document_loader');
try {
$d = jsonld_normalize($data,[ 'algorithm' => 'URDNA2015', 'format' => 'application/nquads' ]);
}
@@ -117,7 +117,7 @@ class LDSignatures {
$precomputed = '.' . base64url_encode($data_type,false) . '.YmFzZTY0dXJs.UlNBLVNIQTI1Ng==';
$signature = base64url_encode(rsa_sign($data . $precomputed,$channel['channel_prvkey']));
$signature = base64url_encode(Crypto::sign($data . $precomputed,$channel['channel_prvkey']));
return ([
'id' => $arr['id'],

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -311,12 +311,13 @@ class Libzotdir {
if ($ud['ud_addr'] && (! ($ud['ud_flags'] & UPDATE_FLAGS_DELETED))) {
$success = false;
$zf = [];
$href = Webfinger::zot_url(punify($ud['ud_addr']));
if($href) {
$zf = Zotfinger::exec($href);
}
if(is_array($zf) && array_path_exists('signature/signer',$zf) && $zf['signature']['signer'] === $href && intval($zf['signature']['header_valid'])) {
if(array_path_exists('signature/signer',$zf) && $zf['signature']['signer'] === $href && intval($zf['signature']['header_valid'])) {
$xc = Libzot::import_xchan($zf['data'], 0, $ud);
}
else {

View File

@@ -163,7 +163,7 @@ class NativeWikiPage {
return [ 'success' => true, 'page' => $page ];
}
return [ 'success' => false, 'item_id' => $c['item_id'], 'message' => t('Page not found') ];
return [ 'success' => false, 'message' => t('Page not found') ];
}
@@ -339,7 +339,6 @@ class NativeWikiPage {
}
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'] : '');
@@ -385,7 +384,7 @@ class NativeWikiPage {
$ret = item_store($item, false, false);
if($ret['item_id'])
return array('message' => '', 'item_id' => $ret['item_id'], 'filename' => $filename, 'success' => true);
return array('message' => '', 'item_id' => $ret['item_id'], 'filename' => $pageUrlName, 'success' => true);
else
return array('message' => t('Page update failed.'), 'success' => false);
}
@@ -432,12 +431,12 @@ class NativeWikiPage {
$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);
return array('message' => 'No commit was provided', 'success' => false);
}
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (!$w['wiki']) {
return array('content' => $content, 'message' => 'Error reading wiki', 'success' => false);
return array('message' => 'Error reading wiki', 'success' => false);
}
$x = $arr;
@@ -451,7 +450,7 @@ class NativeWikiPage {
$content = $loaded['body'];
return [ 'content' => $content, 'success' => true ];
}
return [ 'content' => $content, 'success' => false ];
return [ 'success' => false ];
}
}

View File

@@ -132,6 +132,7 @@ class PConfig {
// manage array value
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
$new = false;
$now = datetime_convert();
if (! $updated) {

View File

@@ -2,9 +2,6 @@
namespace Zotlabs\Lib;
use Zotlabs\Lib\Libzot;
class Queue {
static function update($id, $add_priority = 0) {
@@ -39,7 +36,7 @@ class Queue {
// queue item is less than 12 hours old, we'll schedule for fifteen
// minutes.
$r = q("UPDATE outq SET outq_scheduled = '%s' WHERE outq_posturl = '%s'",
q("UPDATE outq SET outq_scheduled = '%s' WHERE outq_posturl = '%s'",
dbesc(datetime_convert('UTC','UTC','now + 5 days')),
dbesc($x[0]['outq_posturl'])
);
@@ -88,7 +85,7 @@ class Queue {
static function set_delivered($id,$channel = 0) {
logger('queue: set delivered ' . $id,LOGGER_DEBUG);
$sql_extra = (($channel_id) ? " and outq_channel = " . intval($channel_id) . " " : '');
$sql_extra = (($channel['channel_id']) ? " and outq_channel = " . intval($channel['channel_id']) . " " : '');
// Set the next scheduled run date so far in the future that it will be expired
// long before it ever makes it back into the delivery chain.
@@ -230,11 +227,10 @@ class Queue {
logger('deliver: dest: ' . $outq['outq_posturl'], LOGGER_DEBUG);
if($outq['outq_posturl'] === z_root() . '/zot') {
// local delivery
$zot = new \Zotlabs\Zot6\Receiver(new \Zotlabs\Zot6\Zot6Handler(),$outq['outq_notify']);
$result = $zot->run(true);
$result = $zot->run();
logger('returned_json: ' . json_encode($result,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES), LOGGER_DATA);
logger('deliver: local zot delivery succeeded to ' . $outq['outq_posturl']);
Libzot::process_response($outq['outq_posturl'],[ 'success' => true, 'body' => json_encode($result) ], $outq);

View File

@@ -2,8 +2,6 @@
namespace Zotlabs\Lib;
use Zotlabs\Lib\Activity;
class Share {
private $item = null;

View File

@@ -35,7 +35,7 @@ class ThreadItem {
public function __construct($data) {
$this->data = $data;
$this->toplevel = ($this->get_id() == $this->get_data_value('parent'));
$this->threaded = get_config('system','thread_allow');
@@ -98,10 +98,11 @@ class ThreadItem {
$conv = $this->get_conversation();
$observer = $conv->get_observer();
$lock = (((intval($item['item_private'])) || (($item['uid'] == local_channel()) && (strlen($item['allow_cid']) || strlen($item['allow_gid'])
$lock = (((intval($item['item_private'])) || (($item['uid'] == local_channel()) && (strlen($item['allow_cid']) || strlen($item['allow_gid'])
|| strlen($item['deny_cid']) || strlen($item['deny_gid']))))
? t('Private Message')
: false);
$locktype = $item['item_private'];
$shareable = ((($conv->get_profile_owner() == local_channel() && local_channel()) && ($item['item_private'] != 1)) ? true : false);
@@ -151,9 +152,9 @@ class ThreadItem {
if($observer && $observer['xchan_hash']
&& ($observer['xchan_hash'] == $this->get_data_value('author_xchan')
|| $observer['xchan_hash'] == $this->get_data_value('owner_xchan')
|| $observer['xchan_hash'] == $this->get_data_value('source_xchan')
&& ($observer['xchan_hash'] == $this->get_data_value('author_xchan')
|| $observer['xchan_hash'] == $this->get_data_value('owner_xchan')
|| $observer['xchan_hash'] == $this->get_data_value('source_xchan')
|| $this->get_data_value('uid') == local_channel()))
$dropping = true;
@@ -169,15 +170,15 @@ class ThreadItem {
'dropping' => $dropping,
'delete' => t('Delete'),
);
}
}
elseif(is_site_admin()) {
$drop = [ 'dropping' => true, 'delete' => t('Admin Delete') ];
}
// FIXME
if($observer_is_pageowner) {
if($observer_is_pageowner) {
$multidrop = array(
'select' => t('Select'),
'select' => t('Select'),
);
}
@@ -223,7 +224,7 @@ class ThreadItem {
if(! feature_enabled($conv->get_profile_owner(),'dislike'))
unset($conv_responses['dislike']);
$responses = get_responses($conv_responses,$response_verbs,$this,$item);
$my_responses = [];
@@ -254,7 +255,7 @@ class ThreadItem {
}
$showlike = ((x($conv_responses['like'],$item['mid'])) ? format_like($conv_responses['like'][$item['mid']],$conv_responses['like'][$item['mid'] . '-l'],'like',$item['mid']) : '');
$showdislike = ((x($conv_responses['dislike'],$item['mid']) && feature_enabled($conv->get_profile_owner(),'dislike'))
$showdislike = ((x($conv_responses['dislike'],$item['mid']) && feature_enabled($conv->get_profile_owner(),'dislike'))
? format_like($conv_responses['dislike'][$item['mid']],$conv_responses['dislike'][$item['mid'] . '-l'],'dislike',$item['mid']) : '');
/*
@@ -264,7 +265,7 @@ class ThreadItem {
*/
$this->check_wall_to_wall();
if($this->is_toplevel()) {
// FIXME check this permission
if(($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) {
@@ -275,7 +276,7 @@ class ThreadItem {
);
}
}
}
else {
$is_comment = true;
}
@@ -349,7 +350,7 @@ class ThreadItem {
// $viewthread (below) is only valid in list mode. If this is a channel page, build the thread viewing link
// since we can't depend on llink or plink pointing to the right local location.
$owner_address = substr($item['owner']['xchan_addr'],0,strpos($item['owner']['xchan_addr'],'@'));
$viewthread = $item['llink'];
if($conv->get_mode() === 'channel')
@@ -357,7 +358,7 @@ class ThreadItem {
$comment_count_txt = sprintf( tt('%d comment','%d comments',$total_children),$total_children );
$list_unseen_txt = (($unseen_comments) ? sprintf( t('%d unseen'),$unseen_comments) : '');
$children = $this->get_children();
$has_tags = (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false);
@@ -386,7 +387,7 @@ class ThreadItem {
$tmp_item = array(
'template' => $this->get_template(),
'mode' => $mode,
'item_type' => intval($item['item_type']),
'item_type' => intval($item['item_type']),
//'type' => implode("",array_slice(explode("/",$item['verb']),-1)),
'body' => $body['html'],
'tags' => $body['tags'],
@@ -432,6 +433,7 @@ class ThreadItem {
'editedtime' => (($item['edited'] != $item['created']) ? sprintf( t('last edited: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['edited'], 'r')) : ''),
'expiretime' => (($item['expires'] > NULL_DATE) ? sprintf( t('Expires: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['expires'], 'r')):''),
'lock' => $lock,
'locktype' => $locktype,
'delayed' => $item['item_delayed'],
'privacy_warning' => $privacy_warning,
'verified' => $verified,
@@ -518,8 +520,8 @@ class ThreadItem {
// needed for scroll to comment from notification but needs more work
// as we do not want to open all comments unless there is actually an #item_xx anchor
// and the url fragment is not sent to the server.
// if(in_array(\App::$module,['display','update_display']))
// and the url fragment is not sent to the server.
// if(in_array(\App::$module,['display','update_display']))
// $visible_comments = 99999;
if(($this->get_display_mode() === 'normal') && ($nb_children > 0)) {
@@ -539,7 +541,7 @@ class ThreadItem {
}
}
}
$result['private'] = $item['item_private'];
$result['toplevel'] = ($this->is_toplevel() ? 'toplevel_item' : '');
@@ -554,7 +556,7 @@ class ThreadItem {
return $result;
}
public function get_id() {
return $this->get_data_value('id');
}
@@ -609,7 +611,7 @@ class ThreadItem {
if(activity_match($item->get_data_value('verb'),ACTIVITY_LIKE) || activity_match($item->get_data_value('verb'),ACTIVITY_DISLIKE)) {
return false;
}
$item->set_parent($this);
$this->children[] = $item;
return end($this->children);
@@ -683,7 +685,7 @@ class ThreadItem {
*/
public function set_conversation($conv) {
$previous_mode = ($this->conversation ? $this->conversation->get_mode() : '');
$this->conversation = $conv;
// Set it on our children too
@@ -792,7 +794,7 @@ class ThreadItem {
if(!$this->is_toplevel() && !get_config('system','thread_allow')) {
return '';
}
$comment_box = '';
$conv = $this->get_conversation();
@@ -808,7 +810,7 @@ class ThreadItem {
$arr = array('comment_buttons' => '','id' => $this->get_id());
call_hooks('comment_buttons',$arr);
$comment_buttons = $arr['comment_buttons'];
$comment_box = replace_macros($template,array(
'$return_path' => '',
'$threaded' => $this->is_threaded(),
@@ -865,7 +867,7 @@ class ThreadItem {
if($conv->get_mode() === 'channel')
return;
if($this->is_toplevel() && ($this->get_data_value('author_xchan') != $this->get_data_value('owner_xchan'))) {
$this->owner_url = chanlink_hash($this->data['owner']['xchan_hash']);
$this->owner_photo = $this->data['owner']['xchan_photo_m'];

View File

@@ -5,7 +5,7 @@ namespace Zotlabs\Lib;
class Verify {
function create($type,$channel_id,$token,$meta) {
public static function create($type,$channel_id,$token,$meta) {
return q("insert into verify ( vtype, channel, token, meta, created ) values ( '%s', %d, '%s', '%s', '%s' )",
dbesc($type),
intval($channel_id),
@@ -15,7 +15,7 @@ class Verify {
);
}
function match($type,$channel_id,$token,$meta) {
public static function match($type,$channel_id,$token,$meta) {
$r = q("select id from verify where vtype = '%s' and channel = %d and token = '%s' and meta = '%s' limit 1",
dbesc($type),
intval($channel_id),
@@ -31,7 +31,7 @@ class Verify {
return false;
}
function get_meta($type,$channel_id,$token) {
public static function get_meta($type,$channel_id,$token) {
$r = q("select id, meta from verify where vtype = '%s' and channel = %d and token = '%s' limit 1",
dbesc($type),
intval($channel_id),
@@ -52,7 +52,7 @@ class Verify {
* @param string $type Verify type
* @param string $interval SQL compatible time interval
*/
function purge($type, $interval) {
public static function purge($type, $interval) {
q("delete from verify where vtype = '%s' and created < %s - INTERVAL %s",
dbesc($type),
db_utcnow(),

View File

@@ -21,9 +21,8 @@ class ZotURL {
}
$portable_url = substr($url,6);
$u = explode('/',$portable_url);
$u = explode('/',$portable_url);
$portable_id = $u[0];
$hosts = self::lookup($portable_id);
if(! $hosts) {
@@ -39,8 +38,8 @@ class ZotURL {
if($channel && $m) {
$headers = [
'Accept' => 'application/x-zot+json',
$headers = [
'Accept' => 'application/x-zot+json',
'Content-Type' => 'application/x-zot+json',
'X-Zot-Token' => random_string(),
'Digest' => HTTPSig::generate_digest_header($data),
@@ -50,9 +49,9 @@ class ZotURL {
$h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),false);
}
else {
$h = [ 'Accept: application/x-zot+json' ];
$h = [ 'Accept: application/x-zot+json' ];
}
$result = [];
$redirects = 0;

View File

@@ -18,8 +18,8 @@ class Zotfinger {
if($channel && $m) {
$headers = [
'Accept' => 'application/x-zot+json',
$headers = [
'Accept' => 'application/x-zot+json',
'Content-Type' => 'application/x-zot+json',
'X-Zot-Token' => random_string(),
'Digest' => HTTPSig::generate_digest_header($data),
@@ -29,11 +29,10 @@ class Zotfinger {
$h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),false);
}
else {
$h = [ 'Accept: application/x-zot+json' ];
$h = [ 'Accept: application/x-zot+json' ];
}
$result = [];
$result = [];
$redirects = 0;
$x = z_post_url($resource,$data,$redirects, [ 'headers' => $h ] );
@@ -44,11 +43,11 @@ class Zotfinger {
if ($verify) {
$result['signature'] = HTTPSig::verify($x, EMPTY_STR, 'zot6');
}
$result['data'] = json_decode($x['body'],true);
if($result['data'] && is_array($result['data']) && array_key_exists('encrypted',$result['data']) && $result['data']['encrypted']) {
$result['data'] = json_decode(crypto_unencapsulate($result['data'],get_config('system','prvkey')),true);
$result['data'] = json_decode(Crypto::unencapsulate($result['data'],get_config('system','prvkey')),true);
}
logger('decrypted: ' . print_r($result,true));

View File

@@ -143,8 +143,8 @@ class Activity extends Controller {
http_status_exit(403, 'Forbidden');
$i = ZlibActivity::encode_item_collection($nitems,'conversation/' . $item_id,'OrderedCollection');
if($portable_id) {
ThreadListener::store(z_root() . '/activity/' . $item_id,$portable_id);
if($portable_id && (! intval($items[0]['item_private']))) {
ThreadListener::store(z_root() . '/activity/' . $item_id, $portable_id);
}
if(! $i)
@@ -239,6 +239,16 @@ class Activity extends Controller {
xchan_query($r,true);
$items = fetch_post_tags($r,false);
if ($portable_id && (! intval($items[0]['item_private']))) {
$c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'",
intval($items[0]['uid']),
dbesc($portable_id)
);
if (! $c) {
ThreadListener::store(z_root() . '/activity/' . $item_id, $portable_id);
}
}
$channel = channelx_by_n($items[0]['uid']);
$x = array_merge( ['@context' => [

View File

@@ -63,9 +63,9 @@ class Article_edit extends \Zotlabs\Web\Controller {
if ($catsenabled){
$itm = fetch_post_tags($itm);
$cats = get_terms_oftype($itm[0]['term'], TERM_CATEGORY);
foreach ($cats as $cat) {
if (strlen($category))
$category .= ', ';
@@ -113,6 +113,7 @@ class Article_edit extends \Zotlabs\Web\Controller {
'post_id' => $post_id,
'visitor' => true,
'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'),
'summary' => htmlspecialchars($itm[0]['summary'],ENT_COMPAT,'UTF-8'),
'placeholdertitle' => t('Title (optional)'),
'pagetitle' => $card_title,
'profile_uid' => (intval($channel['channel_id'])),

View File

@@ -15,7 +15,7 @@ require_once('include/opengraph.php');
class Articles extends Controller {
function init() {
if(argc() > 1)
$which = argv(1);
@@ -28,13 +28,13 @@ class Articles extends Controller {
return;
}
}
profile_load($which);
}
function get($update = 0, $load = false) {
if(observer_prohibited(true)) {
return login();
}
@@ -56,7 +56,7 @@ class Articles extends Controller {
nav_set_selected('Articles');
head_add_link([
head_add_link([
'rel' => 'alternate',
'type' => 'application/json+oembed',
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . App::$query_string),
@@ -65,7 +65,7 @@ class Articles extends Controller {
$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));
}
@@ -74,24 +74,24 @@ class Articles extends Controller {
$datequery2 = ((x($_GET,'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : '');
$which = argv(1);
$selected_card = ((argc() > 2) ? argv(2) : '');
$_SESSION['return_url'] = App::$query_string;
$uid = local_channel();
$owner = App::$profile_uid;
$observer = App::get_observer();
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
if(! perm_is_allowed($owner,$ob_hash,'view_pages')) {
notice( t('Permission denied.') . EOL);
return;
}
$is_owner = ($uid && $uid == $owner);
$channel = channelx_by_n($owner);
if($channel) {
@@ -105,7 +105,7 @@ class Articles extends Controller {
else {
$channel_acl = [ 'allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '' ];
}
if(perm_is_allowed($owner,$ob_hash,'write_pages')) {
@@ -114,16 +114,15 @@ class Articles extends Controller {
'webpage' => ITEM_TYPE_ARTICLE,
'is_owner' => true,
'content_label' => t('Add Article'),
'button' => t('Create'),
'button' => t('Save'),
'nickname' => $channel['channel_address'],
'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid']
'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,
'acl' => (($is_owner) ? populate_acl($channel_acl, false,
PermissionDescription::fromGlobalPermission('view_pages')) : ''),
'permissions' => $channel_acl,
'showacl' => (($is_owner) ? true : false),
'visitor' => true,
'body' => '[summary][/summary]',
'hide_location' => false,
'hide_voting' => false,
'profile_uid' => intval($owner),
@@ -147,12 +146,12 @@ class Articles extends Controller {
else {
$editor = '';
}
$itemspage = get_pconfig(local_channel(),'system','itemspage');
App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10));
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start']));
$sql_extra = item_permissions_sql($owner);
$sql_item = '';
@@ -176,8 +175,8 @@ class Articles extends Controller {
$sql_extra2 .= " and item.item_thread_top != 0 ";
}
$r = q("select * from item
where item.uid = %d and item_type = %d
$r = q("select * from item
where item.uid = %d and item_type = %d
$sql_extra $sql_extra2 $sql_item order by item.created desc $pager_sql",
intval($owner),
intval(ITEM_TYPE_ARTICLE)
@@ -214,7 +213,7 @@ class Articles extends Controller {
opengraph_add_meta((! empty($items) ? $r[0] : []), $channel);
$mode = 'articles';
if(get_pconfig(local_channel(),'system','articles_list_mode') && (! $selected_card))
$page_mode = 'pager_list';
else

View File

@@ -1,4 +1,5 @@
<?php
namespace Zotlabs\Module;
use ZipArchive;
@@ -12,24 +13,24 @@ class Attach extends Controller {
function post() {
$attach_ids = ((x($_REQUEST, 'attach_ids')) ? $_REQUEST['attach_ids'] : []);
$attach_ids = ((x($_REQUEST, 'attach_ids')) ? $_REQUEST['attach_ids'] : []);
$attach_path = ((x($_REQUEST, 'attach_path')) ? $_REQUEST['attach_path'] : '');
$channel_id = ((x($_REQUEST, 'channel_id')) ? intval($_REQUEST['channel_id']) : 0);
$channel = channelx_by_n($channel_id);
$channel_id = ((x($_REQUEST, 'channel_id')) ? intval($_REQUEST['channel_id']) : 0);
$channel = channelx_by_n($channel_id);
if (! $channel) {
if (!$channel) {
notice(t('Channel not found.') . EOL);
return;
}
$strip_str = '/cloud/' . $channel['channel_address'] . '/';
$count = strlen($strip_str);
$strip_str = '/cloud/' . $channel['channel_address'] . '/';
$count = strlen($strip_str);
$attach_path = substr($attach_path, $count);
if ($attach_ids) {
$zip_dir = 'store/[data]/' . $channel['channel_address'] . '/tmp';
if (! is_dir($zip_dir))
if (!is_dir($zip_dir))
mkdir($zip_dir, STORAGE_DEFAULT_PERMISSIONS, true);
$token = random_string(32);
@@ -47,14 +48,14 @@ class Attach extends Controller {
$meta = [
'zip_filename' => $zip_filename,
'zip_path' => $zip_path
'zip_path' => $zip_path
];
Verify::create('zip_token', 0, $token, json_encode($meta));
json_return_and_die([
'success' => true,
'token' => $token
'token' => $token
]);
}
@@ -63,28 +64,28 @@ class Attach extends Controller {
function get() {
if(argc() < 2) {
notice( t('Item not available.') . EOL);
if (argc() < 2) {
notice(t('Item not available.') . EOL);
return;
}
$token = ((x($_REQUEST, 'token')) ? $_REQUEST['token'] : '');
if(argv(1) === 'download') {
if (argv(1) === 'download') {
$meta = Verify::get_meta('zip_token', 0, $token);
if(! $meta)
if (!$meta)
killme();
$meta = json_decode($meta, true);
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="'. $meta['zip_filename'] . '"');
header('Content-Disposition: attachment; filename="' . $meta['zip_filename'] . '"');
header('Content-Length: ' . filesize($meta['zip_path']));
$istream = fopen($meta['zip_path'], 'rb');
$ostream = fopen('php://output', 'wb');
if($istream && $ostream) {
if ($istream && $ostream) {
pipe_streams($istream, $ostream);
fclose($istream);
fclose($ostream);
@@ -94,10 +95,10 @@ class Attach extends Controller {
killme();
}
$r = attach_by_hash(argv(1),get_observer_hash(),((argc() > 2) ? intval(argv(2)) : 0));
$r = attach_by_hash(argv(1), get_observer_hash(), ((argc() > 2) ? intval(argv(2)) : 0));
if(! $r['success']) {
notice( $r['message'] . EOL);
if (!$r['success']) {
notice($r['message'] . EOL);
return;
}
@@ -105,27 +106,27 @@ class Attach extends Controller {
intval($r['data']['uid'])
);
if(! $c)
if (!$c)
return;
$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) && (! channel_codeallowed($r['data']['uid']))) {
header('Content-Type: text/plain');
if (in_array($r['data']['filetype'], $unsafe_types) && (!channel_codeallowed($r['data']['uid']))) {
header('Content-Type: text/plain');
}
else {
header('Content-Type: ' . $r['data']['filetype']);
}
header('Content-Disposition: attachment; filename="' . $r['data']['filename'] . '"');
if(intval($r['data']['os_storage'])) {
if (intval($r['data']['os_storage'])) {
$fname = $r['data']['content'];
if(strpos($fname,'store') !== false)
$istream = fopen($fname,'rb');
if (strpos($fname, 'store') !== false)
$istream = fopen($fname, 'rb');
else
$istream = fopen('store/' . $c[0]['channel_address'] . '/' . $fname,'rb');
$ostream = fopen('php://output','wb');
if($istream && $ostream) {
$istream = fopen('store/' . $c[0]['channel_address'] . '/' . $fname, 'rb');
$ostream = fopen('php://output', 'wb');
if ($istream && $ostream) {
pipe_streams($istream, $ostream);
fclose($istream);
fclose($ostream);
@@ -140,14 +141,14 @@ class Attach extends Controller {
public function zip_archive_handler($zip, $attach_ids, $attach_path, $pass = 1) {
$observer_hash = get_observer_hash();
$single = ((count($attach_ids) == 1) ? true : false);
$single = ((count($attach_ids) == 1) ? true : false);
$download_name = 'download.zip';
foreach($attach_ids as $attach_id) {
foreach ($attach_ids as $attach_id) {
$r = attach_by_id($attach_id, $observer_hash);
if (! $r['success']) {
if (!$r['success']) {
continue;
}
@@ -158,8 +159,8 @@ class Attach extends Controller {
if ($attach_path) {
$strip_str = $attach_path . '/';
$count = strlen($strip_str);
$zip_path = substr($r['data']['display_path'], $count);
$count = strlen($strip_str);
$zip_path = substr($r['data']['display_path'], $count);
}
if ($r['data']['is_dir']) {

View File

@@ -37,8 +37,6 @@ class Cal extends Controller {
$observer = App::get_observer();
App::$data['observer'] = $observer;
$observer_xchan = (($observer) ? $observer['xchan_hash'] : '');
head_set_icon(App::$data['channel']['xchan_photo_s']);
App::$page['htmlhead'] .= "<script> var profile_uid = " . ((App::$data['channel']) ? App::$data['channel']['channel_id'] : 0) . "; </script>" ;
@@ -159,10 +157,10 @@ class Cal extends Controller {
'timezone' => $tz,
'start'=> $start,
'end' => $end,
'drop' => $drop,
'drop' => false,
'allDay' => (($rr['adjust']) ? 0 : 1),
'title' => html_entity_decode($rr['summary'], ENT_COMPAT, 'UTF-8'),
'editable' => $edit ? true : false,
'editable' => false,
'item' => $rr,
'plink' => [$rr['plink'], t('Link to source')],
'description' => html_entity_decode($rr['description'], ENT_COMPAT, 'UTF-8'),
@@ -205,9 +203,9 @@ class Cal extends Controller {
'$prev' => t('Previous'),
'$next' => t('Next'),
'$today' => t('Today'),
'$title' => $title,
'$dtstart' => $dtstart,
'$dtend' => $dtend,
'$title' => '',
'$dtstart' => '',
'$dtend' => '',
'$nick' => $nick
]);

View File

@@ -63,9 +63,9 @@ class Card_edit extends \Zotlabs\Web\Controller {
if ($catsenabled){
$itm = fetch_post_tags($itm);
$cats = get_terms_oftype($itm[0]['term'], TERM_CATEGORY);
foreach ($cats as $cat) {
if (strlen($category))
$category .= ', ';
@@ -114,6 +114,7 @@ class Card_edit extends \Zotlabs\Web\Controller {
'post_id' => $post_id,
'visitor' => true,
'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'),
'summary' => htmlspecialchars($itm[0]['summary'],ENT_COMPAT,'UTF-8'),
'placeholdertitle' => t('Title (optional)'),
'pagetitle' => $card_title,
'profile_uid' => (intval($channel['channel_id'])),

View File

@@ -110,7 +110,7 @@ class Cards extends Controller {
'webpage' => ITEM_TYPE_CARD,
'is_owner' => true,
'content_label' => t('Add Card'),
'button' => t('Create'),
'button' => t('Save'),
'nickname' => $channel['channel_address'],
'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid']
|| $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),

View File

@@ -284,7 +284,7 @@ class Cdav extends Controller {
$server->addPlugin(new \Sabre\CardDAV\VCFExportPlugin());
// And off we go!
$server->exec();
$server->start();
killme();

View File

@@ -4,10 +4,13 @@ namespace Zotlabs\Module;
use App;
use Zotlabs\Web\Controller;
use Zotlabs\Lib\PermissionDescription;
use Zotlabs\Web\HTTPSig;
use Zotlabs\Lib\Activity;
use Zotlabs\Lib\ActivityStreams;
use Zotlabs\Lib\Crypto;
use Zotlabs\Lib\Libzot;
use Zotlabs\Lib\PermissionDescription;
use Zotlabs\Web\Controller;
use Zotlabs\Web\HTTPSig;
require_once('include/items.php');
require_once('include/security.php');
@@ -20,88 +23,117 @@ require_once('include/opengraph.php');
* @brief Channel Controller
*
*/
class Channel extends Controller {
function init() {
if(in_array(substr($_GET['search'],0,1),[ '@', '!', '?']))
if (in_array(substr($_GET['search'], 0, 1), ['@', '!', '?']) || strpos($_GET['search'], 'https://') === 0)
goaway('search' . '?f=&search=' . $_GET['search']);
$which = null;
if(argc() > 1)
if (argc() > 1)
$which = argv(1);
if(! $which) {
if(local_channel()) {
if (!$which) {
if (local_channel()) {
$channel = App::get_channel();
if($channel && $channel['channel_address'])
$which = $channel['channel_address'];
if ($channel && $channel['channel_address'])
$which = $channel['channel_address'];
}
}
if(! $which) {
notice( t('You must be logged in to see this page.') . EOL );
if (!$which) {
notice(t('You must be logged in to see this page.') . EOL);
return;
}
$profile = 0;
$channel = App::get_channel();
if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
$which = $channel['channel_address'];
if ((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
$which = $channel['channel_address'];
$profile = argv(1);
}
$channel = channelx_by_nick($which);
if(! $channel) {
if (!$channel) {
http_status_exit(404, 'Not found');
}
// handle zot6 channel discovery
// handle zot6 channel discovery
if (Libzot::is_zot_request()) {
if(Libzot::is_zot_request()) {
$sigdata = HTTPSig::verify(file_get_contents('php://input'), EMPTY_STR, 'zot6');
if($sigdata && $sigdata['signer'] && $sigdata['header_valid']) {
$data = json_encode(Libzot::zotinfo([ 'address' => $channel['channel_address'], 'target_url' => $sigdata['signer'] ]));
$s = q("select site_crypto, hubloc_sitekey from site left join hubloc on hubloc_url = site_url where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
if ($sigdata && $sigdata['signer'] && $sigdata['header_valid']) {
$data = json_encode(Libzot::zotinfo(['address' => $channel['channel_address'], 'target_url' => $sigdata['signer']]));
$s = q("select site_crypto, hubloc_sitekey from site left join hubloc on hubloc_url = site_url where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
dbesc($sigdata['signer'])
);
if($s) {
$data = json_encode(crypto_encapsulate($data,$s[0]['hubloc_sitekey'],Libzot::best_algorithm($s[0]['site_crypto'])));
if ($s) {
$data = json_encode(Crypto::encapsulate($data, $s[0]['hubloc_sitekey'], Libzot::best_algorithm($s[0]['site_crypto'])));
}
}
else {
$data = json_encode(Libzot::zotinfo([ 'address' => $channel['channel_address'] ]));
$data = json_encode(Libzot::zotinfo(['guid_hash' => $channel['channel_hash']]));
}
$headers = [
'Content-Type' => 'application/x-zot+json',
$headers = [
'Content-Type' => 'application/x-zot+json',
'Digest' => HTTPSig::generate_digest_header($data),
'(request-target)' => strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI']
];
$h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel));
];
$h = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel));
HTTPSig::set_headers($h);
echo $data;
killme();
}
if (ActivityStreams::is_as_request($channel)) {
if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
$which = $channel['channel_address'];
// Somebody may attempt an ActivityStreams fetch on one of our message permalinks
// Make it do the right thing.
$mid = ((x($_REQUEST, 'mid')) ? $_REQUEST['mid'] : '');
if ($mid && strpos($mid, 'b64.') === 0) {
$decoded = @base64url_decode(substr($mid, 4));
if ($decoded) {
$mid = $decoded;
}
}
if ($mid) {
$obj = null;
if (strpos($mid, z_root() . '/item/') === 0) {
App::$argc = 2;
App::$argv = ['item', basename($mid)];
$obj = new Item();
}
if (strpos($mid, z_root() . '/activity/') === 0) {
App::$argc = 2;
App::$argv = ['activity', basename($mid)];
$obj = new Activity();
}
if ($obj) {
$obj->init();
}
}
as_return_and_die(Activity::encode_person($channel, true), $channel);
}
if ((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
$which = $channel['channel_address'];
$profile = argv(1);
}
head_add_link( [
'rel' => 'alternate',
head_add_link([
'rel' => 'alternate',
'type' => 'application/atom+xml',
'title' => t('Posts and comments'),
'href' => z_root() . '/feed/' . $which
]);
head_add_link( [
'rel' => 'alternate',
head_add_link([
'rel' => 'alternate',
'type' => 'application/atom+xml',
'title' => t('Only posts'),
'href' => z_root() . '/feed/' . $which . '?f=&top=1'
@@ -110,19 +142,19 @@ class Channel extends Controller {
// Run profile_load() here to make sure the theme is set before
// we start loading content
profile_load($which,$profile);
profile_load($which, $profile);
// Add Opengraph markup
$mid = ((x($_REQUEST,'mid')) ? $_REQUEST['mid'] : '');
if(strpos($mid,'b64.') === 0)
$mid = @base64url_decode(substr($mid,4));
if($mid)
$r = q("SELECT * FROM item WHERE mid = '%s' AND uid = %d AND item_private = 0 LIMIT 1",
dbesc($mid),
intval($channel['channel_id'])
);
$mid = ((x($_REQUEST, 'mid')) ? $_REQUEST['mid'] : '');
if (strpos($mid, 'b64.') === 0)
$mid = @base64url_decode(substr($mid, 4));
if ($mid)
$r = q("SELECT * FROM item WHERE mid = '%s' AND uid = %d AND item_private = 0 LIMIT 1",
dbesc($mid),
intval($channel['channel_id'])
);
opengraph_add_meta($r ? $r[0] : [], $channel);
}
@@ -132,99 +164,99 @@ class Channel extends Controller {
$category = $datequery = $datequery2 = '';
$mid = ((x($_REQUEST,'mid')) ? $_REQUEST['mid'] : '');
$mid = ((x($_REQUEST, 'mid')) ? $_REQUEST['mid'] : '');
if(strpos($mid,'b64.') === 0)
$decoded = @base64url_decode(substr($mid,4));
if($decoded)
if (strpos($mid, 'b64.') === 0)
$decoded = @base64url_decode(substr($mid, 4));
if ($decoded)
$mid = $decoded;
$datequery = ((x($_GET,'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : '');
$datequery2 = ((x($_GET,'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : '');
$datequery = ((x($_GET, 'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : '');
$datequery2 = ((x($_GET, 'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : '');
if(observer_prohibited(true)) {
if (observer_prohibited(true)) {
return login();
}
$category = ((x($_REQUEST,'cat')) ? $_REQUEST['cat'] : '');
$hashtags = ((x($_REQUEST,'tag')) ? $_REQUEST['tag'] : '');
$order = ((x($_GET,'order')) ? notags($_GET['order']) : 'post');
$search = ((x($_GET,'search')) ? $_GET['search'] : EMPTY_STR);
$category = ((x($_REQUEST, 'cat')) ? $_REQUEST['cat'] : '');
$hashtags = ((x($_REQUEST, 'tag')) ? $_REQUEST['tag'] : '');
$order = ((x($_GET, 'order')) ? notags($_GET['order']) : 'post');
$search = ((x($_GET, 'search')) ? $_GET['search'] : EMPTY_STR);
$groups = array();
$groups = [];
$o = '';
if($update) {
if ($update) {
// Ensure we've got a profile owner if updating.
App::$profile['profile_uid'] = App::$profile_uid = $update;
}
$is_owner = (((local_channel()) && (App::$profile['profile_uid'] == local_channel())) ? true : false);
$channel = App::get_channel();
$channel = App::get_channel();
$observer = App::get_observer();
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
$perms = get_all_perms(App::$profile['profile_uid'],$ob_hash);
$perms = get_all_perms(App::$profile['profile_uid'], $ob_hash);
if(! $perms['view_stream']) {
if (!$perms['view_stream']) {
// We may want to make the target of this redirect configurable
if($perms['view_profile']) {
notice( t('Insufficient permissions. Request redirected to profile page.') . EOL);
goaway (z_root() . "/profile/" . App::$profile['channel_address']);
if ($perms['view_profile']) {
notice(t('Insufficient permissions. Request redirected to profile page.') . EOL);
goaway(z_root() . "/profile/" . App::$profile['channel_address']);
}
notice( t('Permission denied.') . EOL);
notice(t('Permission denied.') . EOL);
return;
}
if(! $update) {
if (!$update) {
nav_set_selected('Channel Home');
// search terms header
if($search) {
$o .= replace_macros(get_markup_template("section_title.tpl"),array(
'$title' => t('Search Results For:') . ' ' . htmlspecialchars($search, ENT_COMPAT,'UTF-8')
));
if ($search) {
$o .= replace_macros(get_markup_template("section_title.tpl"), [
'$title' => t('Search Results For:') . ' ' . htmlspecialchars($search, ENT_COMPAT, 'UTF-8')
]);
}
if($channel && $is_owner) {
$channel_acl = array(
if ($channel && $is_owner) {
$channel_acl = [
'allow_cid' => $channel['channel_allow_cid'],
'allow_gid' => $channel['channel_allow_gid'],
'deny_cid' => $channel['channel_deny_cid'],
'deny_gid' => $channel['channel_deny_gid']
);
'deny_cid' => $channel['channel_deny_cid'],
'deny_gid' => $channel['channel_deny_gid']
];
}
else {
$channel_acl = [ 'allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '' ];
$channel_acl = ['allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => ''];
}
if($perms['post_wall']) {
if ($perms['post_wall']) {
$x = array(
'is_owner' => $is_owner,
'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig(App::$profile['profile_uid'],'system','use_browser_location')))) ? true : false),
'default_location' => (($is_owner) ? App::$profile['channel_location'] : ''),
'nickname' => App::$profile['channel_address'],
'lockstate' => (((strlen(App::$profile['channel_allow_cid'])) || (strlen(App::$profile['channel_allow_gid'])) || (strlen(App::$profile['channel_deny_cid'])) || (strlen(App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'),
'acl' => (($is_owner) ? populate_acl($channel_acl,true, PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''),
'permissions' => $channel_acl,
'showacl' => (($is_owner) ? 'yes' : ''),
'bang' => '',
'visitor' => (($is_owner || $observer) ? true : false),
'profile_uid' => App::$profile['profile_uid'],
$x = [
'is_owner' => $is_owner,
'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig(App::$profile['profile_uid'], 'system', 'use_browser_location')))) ? true : false),
'default_location' => (($is_owner) ? App::$profile['channel_location'] : ''),
'nickname' => App::$profile['channel_address'],
'lockstate' => (((strlen(App::$profile['channel_allow_cid'])) || (strlen(App::$profile['channel_allow_gid'])) || (strlen(App::$profile['channel_deny_cid'])) || (strlen(App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'),
'acl' => (($is_owner) ? populate_acl($channel_acl, true, PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''),
'permissions' => $channel_acl,
'showacl' => (($is_owner) ? 'yes' : ''),
'bang' => '',
'visitor' => (($is_owner || $observer) ? true : false),
'profile_uid' => App::$profile['profile_uid'],
'editor_autocomplete' => true,
'bbco_autocomplete' => 'bbcode',
'bbcode' => true,
'jotnets' => true,
'reset' => t('Reset form')
);
'bbco_autocomplete' => 'bbcode',
'bbcode' => true,
'jotnets' => true,
'reset' => t('Reset form')
];
$o .= status_editor($a,$x,false,'Channel');
$o .= status_editor($a, $x, false, 'Channel');
}
}
@@ -233,16 +265,16 @@ class Channel extends Controller {
/**
* Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
*/
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_deleted = 0
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_deleted = 0
and item.item_unpublished = 0 and item.item_pending_remove = 0
and item.item_blocked = 0 ";
if (! $is_owner)
$item_normal .= "and item.item_delayed = 0 ";
if (!$is_owner)
$item_normal .= "and item.item_delayed = 0 ";
$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(feature_enabled(App::$profile['profile_uid'], 'channel_list_mode') && (! $mid))
if (feature_enabled(App::$profile['profile_uid'], 'channel_list_mode') && (!$mid))
$page_mode = 'list';
else
$page_mode = 'client';
@@ -250,13 +282,13 @@ class Channel extends Controller {
$abook_uids = " and abook.abook_channel = " . intval(App::$profile['profile_uid']) . " ";
$simple_update = '';
if($update && $_SESSION['loadtime'])
$simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) ";
if ($update && $_SESSION['loadtime'])
$simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC', 'UTC', $_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC', 'UTC', $_SESSION['loadtime']) . "' ) ";
if($search) {
if ($search) {
$search = escape_tags($search);
if(strpos($search,'#') === 0) {
$sql_extra .= term_query('item',substr($search,1),TERM_HASHTAG,TERM_COMMUNITYTAG);
if (strpos($search, '#') === 0) {
$sql_extra .= term_query('item', substr($search, 1), TERM_HASHTAG, TERM_COMMUNITYTAG);
}
else {
$sql_extra .= sprintf(" AND (item.body like '%s' OR item.title like '%s') ",
@@ -266,16 +298,16 @@ class Channel extends Controller {
}
}
head_add_link([
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) && (! $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_update
AND item_wall = 1 $simple_update $sql_extra limit 1",
dbesc($mid . '%'),
@@ -296,61 +328,61 @@ class Channel extends Controller {
}
else {
if(x($category)) {
$sql_extra2 .= protect_sprintf(term_item_parent_query(App::$profile['profile_uid'],'item', $category, TERM_CATEGORY));
if (x($category)) {
$sql_extra2 .= protect_sprintf(term_item_parent_query(App::$profile['profile_uid'], 'item', $category, TERM_CATEGORY));
}
if(x($hashtags)) {
$sql_extra2 .= protect_sprintf(term_item_parent_query(App::$profile['profile_uid'],'item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG));
if (x($hashtags)) {
$sql_extra2 .= protect_sprintf(term_item_parent_query(App::$profile['profile_uid'], 'item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG));
}
if($datequery) {
$sql_extra2 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery))));
$order = 'post';
if ($datequery) {
$sql_extra2 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(), '', $datequery))));
$order = 'post';
}
if($datequery2) {
$sql_extra2 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2))));
if ($datequery2) {
$sql_extra2 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(), '', $datequery2))));
}
if($order === 'post')
if ($order === 'post')
$ordering = "created";
else
$ordering = "commented";
$itemspage = get_pconfig(local_channel(),'system','itemspage');
$itemspage = get_pconfig(local_channel(), 'system', 'itemspage');
App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10));
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start']));
if($noscript_content || $load) {
if($mid) {
if ($noscript_content || $load) {
if ($mid) {
$r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal
AND item_wall = 1 $sql_extra limit 1",
dbesc($mid . '%'),
intval(App::$profile['profile_uid'])
);
if (! $r) {
notice( t('Permission denied.') . EOL);
if (!$r) {
notice(t('Permission denied.') . EOL);
}
}
else {
$r = q("SELECT DISTINCT item.parent AS item_id, $ordering FROM item
$r = q("SELECT DISTINCT item.parent AS item_id, $ordering FROM item
left join abook on ( item.author_xchan = abook.abook_xchan $abook_uids )
WHERE true and item.uid = %d $item_normal
AND (abook.abook_blocked = 0 or abook.abook_flags is null)
AND item.item_wall = 1 AND item.item_thread_top = 1
$sql_extra $sql_extra2
$sql_extra $sql_extra2
ORDER BY $ordering DESC, item_id $pager_sql ",
intval(App::$profile['profile_uid'])
);
}
}
else {
$r = array();
$r = [];
}
}
if($r) {
if ($r) {
$parents_str = ids_to_querystr($r,'item_id');
$parents_str = ids_to_querystr($r, 'item_id');
$r = q("SELECT item.*, item.id AS item_id
FROM item
@@ -363,28 +395,38 @@ class Channel extends Controller {
xchan_query($r);
$items = fetch_post_tags($r, true);
$items = conv_sort($items,$ordering);
$items = conv_sort($items, $ordering);
if($load && $mid && (! count($items))) {
if ($load && $mid && (!count($items))) {
// This will happen if we don't have sufficient permissions
// to view the parent item (or the item itself if it is toplevel)
notice( t('Permission denied.') . EOL);
notice(t('Permission denied.') . EOL);
}
} else {
$items = array();
}
else {
$items = [];
}
if((! $update) && (! $load)) {
// Add pinned content
if (!x($_REQUEST, 'mid') && !$search) {
$pinned = new \Zotlabs\Widget\Pinned;
$r = $pinned->widget(intval(App::$profile['profile_uid']), [ITEM_TYPE_POST]);
$o .= $r['html'];
}
if($decoded)
$mode = (($search) ? 'search' : 'channel');
if ((!$update) && (!$load)) {
if ($decoded)
$mid = 'b64.' . base64url_encode($mid);
// This is ugly, but we can't pass the profile_uid through the session to the ajax updater,
// because browser prefetching might change it on us. We have to deliver it with the page.
$maxheight = get_pconfig(App::$profile['profile_uid'],'system','channel_divmore_height');
if(! $maxheight)
$maxheight = get_pconfig(App::$profile['profile_uid'], 'system', 'channel_divmore_height');
if (!$maxheight)
$maxheight = 400;
$o .= '<div id="live-channel"></div>' . "\r\n";
@@ -392,57 +434,48 @@ class Channel extends Controller {
. "; var netargs = '?f='; var profile_page = " . App::$pager['page']
. "; divmore_height = " . intval($maxheight) . ";</script>\r\n";
App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array(
'$baseurl' => z_root(),
'$pgtype' => 'channel',
'$uid' => ((App::$profile['profile_uid']) ? App::$profile['profile_uid'] : '0'),
'$gid' => '0',
'$cid' => '0',
'$cmin' => '(-1)',
'$cmax' => '(-1)',
'$star' => '0',
'$liked' => '0',
'$conv' => '0',
'$spam' => '0',
'$nouveau' => '0',
'$wall' => '1',
'$fh' => '0',
'$dm' => '0',
'$page' => ((App::$pager['page'] != 1) ? App::$pager['page'] : 1),
'$search' => $search,
'$xchan' => '',
'$order' => (($order) ? urlencode($order) : ''),
'$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0),
'$file' => '',
'$cats' => (($category) ? urlencode($category) : ''),
'$tags' => (($hashtags) ? urlencode($hashtags) : ''),
'$mid' => (($mid) ? urlencode($mid) : ''),
'$verb' => '',
'$net' => '',
'$dend' => $datequery,
'$dbegin' => $datequery2,
'$conv_mode' => 'channel'
));
App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"), [
'$baseurl' => z_root(),
'$pgtype' => 'channel',
'$uid' => ((App::$profile['profile_uid']) ? App::$profile['profile_uid'] : '0'),
'$gid' => '0',
'$cid' => '0',
'$cmin' => '(-1)',
'$cmax' => '(-1)',
'$star' => '0',
'$liked' => '0',
'$conv' => '0',
'$spam' => '0',
'$nouveau' => '0',
'$wall' => '1',
'$fh' => '0',
'$dm' => '0',
'$page' => ((App::$pager['page'] != 1) ? App::$pager['page'] : 1),
'$search' => $search,
'$xchan' => '',
'$order' => (($order) ? urlencode($order) : ''),
'$list' => ((x($_REQUEST, 'list')) ? intval($_REQUEST['list']) : 0),
'$file' => '',
'$cats' => (($category) ? urlencode($category) : ''),
'$tags' => (($hashtags) ? urlencode($hashtags) : ''),
'$mid' => (($mid) ? urlencode($mid) : ''),
'$verb' => '',
'$net' => '',
'$dend' => $datequery,
'$dbegin' => $datequery2,
'$conv_mode' => 'channel',
'$page_mode' => $page_mode
]);
}
// Add pinned content
if(! x($_REQUEST,'mid') && ! $search) {
$pinned = new \Zotlabs\Widget\Pinned;
$r = $pinned->widget(intval(App::$profile['profile_uid']), [ITEM_TYPE_POST]);
$o .= $r['html'];
}
$mode = (($search) ? 'search' : 'channel');
if($update) {
$o .= conversation($items,$mode,$update,$page_mode);
if ($update) {
$o .= conversation($items, $mode, $update, $page_mode);
}
else {
$o .= '<noscript>';
if($noscript_content) {
$o .= conversation($items,$mode,$update,'traditional');
if ($noscript_content) {
$o .= conversation($items, $mode, $update, 'traditional');
$o .= alt_pager(count($items));
}
else {
@@ -450,14 +483,14 @@ class Channel extends Controller {
}
$o .= '</noscript>';
$o .= conversation($items,$mode,$update,$page_mode);
$o .= conversation($items, $mode, $update, $page_mode);
if ($mid && $items[0]['title'])
App::$page['title'] = $items[0]['title'] . " - " . App::$page['title'];
}
if($mid)
if ($mid)
$o .= '<div id="content-complete"></div>';
$_SESSION['loadtime'] = datetime_convert();

View File

@@ -1,7 +1,12 @@
<?php
namespace Zotlabs\Module;
use App;
use Zotlabs\Web\Controller;
use Zotlabs\Lib\Libsync;
use Zotlabs\Access\AccessList;
use Zotlabs\Daemon\Master;
require_once('include/conversation.php');
require_once('include/bbcode.php');
@@ -10,37 +15,37 @@ require_once('include/event.php');
require_once('include/items.php');
require_once('include/html2plain.php');
class Channel_calendar extends \Zotlabs\Web\Controller {
class Channel_calendar extends Controller {
function post() {
logger('post: ' . print_r($_REQUEST,true), LOGGER_DATA);
if(! local_channel())
return;
$event_id = ((x($_POST,'event_id')) ? intval($_POST['event_id']) : 0);
$event_hash = ((x($_POST,'event_hash')) ? $_POST['event_hash'] : '');
$xchan = ((x($_POST,'xchan')) ? dbesc($_POST['xchan']) : '');
logger('post: ' . print_r($_REQUEST, true), LOGGER_DATA);
$uid = local_channel();
if (!$uid)
return;
$event_id = ((x($_POST, 'event_id')) ? intval($_POST['event_id']) : 0);
$xchan = ((x($_POST, 'xchan')) ? dbesc($_POST['xchan']) : '');
// only allow editing your own events.
if(($xchan) && ($xchan !== get_observer_hash()))
if (($xchan) && ($xchan !== get_observer_hash()))
return;
$categories = escape_tags(trim($_POST['categories']));
// allday events have adjust = 0, normal events have adjust = 1
$adjust = intval($_POST['adjust']);
$start = datetime_convert((($adjust) ? $tz : 'UTC'), 'UTC', escape_tags($_REQUEST['dtstart']));
$timezone = ((x($_POST, 'timezone_select')) ? escape_tags(trim($_POST['timezone_select'])) : '');
$tz = (($timezone) ? $timezone : date_default_timezone_get());
$start = datetime_convert((($adjust) ? $tz : 'UTC'), 'UTC', escape_tags($_REQUEST['dtstart']));
$finish = datetime_convert((($adjust) ? $tz : 'UTC'), 'UTC', escape_tags($_REQUEST['dtend']));
$timezone = ((x($_POST,'timezone_select')) ? escape_tags(trim($_POST['timezone_select'])) : '');
$tz = (($timezone) ? $timezone : date_default_timezone_get());
if(! $adjust)
if (!$adjust)
$tz = 'UTC';
$summary = escape_tags(trim($_POST['summary']));
@@ -52,88 +57,86 @@ class Channel_calendar extends \Zotlabs\Web\Controller {
// It won't hurt anything, but somebody will file a bug report
// and we'll waste a bunch of time responding to it. Time that
// could've been spent doing something else.
if(strcmp($finish,$start) < 0 && !$nofinish) {
notice( t('Event can not end before it has started.') . EOL);
if(intval($_REQUEST['preview'])) {
echo( t('Unable to generate preview.'));
}
killme();
}
if((! $summary) || (! $start)) {
notice( t('Event title and start time are required.') . EOL);
if(intval($_REQUEST['preview'])) {
echo( t('Unable to generate preview.'));
if (strcmp($finish, $start) < 0) {
notice(t('Event can not end before it has started.') . EOL);
if (intval($_REQUEST['preview'])) {
echo(t('Unable to generate preview.'));
}
killme();
}
$channel = \App::get_channel();
$acl = new \Zotlabs\Access\AccessList(false);
if($event_id) {
if ((!$summary) || (!$start)) {
notice(t('Event title and start time are required.') . EOL);
if (intval($_REQUEST['preview'])) {
echo(t('Unable to generate preview.'));
}
killme();
}
$acl = new AccessList([]);
if ($event_id) {
$x = q("select * from event where id = %d and uid = %d limit 1",
intval($event_id),
intval(local_channel())
intval($uid)
);
if(! $x) {
notice( t('Event not found.') . EOL);
if(intval($_REQUEST['preview'])) {
echo( t('Unable to generate preview.'));
if (!$x) {
notice(t('Event not found.') . EOL);
if (intval($_REQUEST['preview'])) {
echo(t('Unable to generate preview.'));
killme();
}
return;
}
$acl->set($x[0]);
$created = $x[0]['created'];
$edited = datetime_convert();
$edited = datetime_convert();
}
else {
$created = $edited = datetime_convert();
$acl->set_from_array($_POST);
}
$post_tags = array();
$channel = \App::get_channel();
$ac = $acl->get();
$channel = App::get_channel();
$ac = $acl->get();
$str_contact_allow = $ac['allow_cid'];
$str_group_allow = $ac['allow_gid'];
$str_contact_deny = $ac['deny_cid'];
$str_group_deny = $ac['deny_gid'];
$str_contact_deny = $ac['deny_cid'];
$str_group_deny = $ac['deny_gid'];
$private = $acl->is_private();
require_once('include/text.php');
$results = linkify_tags($desc, local_channel());
$results = linkify_tags($desc, $uid);
if($results) {
if ($results) {
// Set permissions based on tag replacements
set_linkified_perms($results, $str_contact_allow, $str_group_allow, local_channel(), false, $private);
set_linkified_perms($results, $str_contact_allow, $str_group_allow, $uid, false, $private);
foreach($results as $result) {
foreach ($results as $result) {
$success = $result['success'];
if($success['replaced']) {
if ($success['replaced']) {
$post_tags[] = array(
'uid' => local_channel(),
'uid' => $uid,
'ttype' => $success['termtype'],
'otype' => TERM_OBJ_POST,
'term' => $success['term'],
'url' => $success['url']
);
);
}
}
}
if(strlen($categories)) {
$cats = explode(',',$categories);
foreach($cats as $cat) {
if (strlen($categories)) {
$cats = explode(',', $categories);
foreach ($cats as $cat) {
$post_tags[] = array(
'uid' => local_channel(),
'uid' => $uid,
'ttype' => TERM_CATEGORY,
'otype' => TERM_OBJ_POST,
'term' => trim($cat),
@@ -141,175 +144,170 @@ class Channel_calendar extends \Zotlabs\Web\Controller {
);
}
}
$datarray = array();
$datarray['dtstart'] = $start;
$datarray['dtend'] = $finish;
$datarray['summary'] = $summary;
$datarray['description'] = $desc;
$datarray['location'] = $location;
$datarray['etype'] = $type;
$datarray['adjust'] = $adjust;
$datarray['nofinish'] = 0;
$datarray['uid'] = local_channel();
$datarray['account'] = get_account_id();
$datarray['event_xchan'] = $channel['channel_hash'];
$datarray['allow_cid'] = $str_contact_allow;
$datarray['allow_gid'] = $str_group_allow;
$datarray['deny_cid'] = $str_contact_deny;
$datarray['deny_gid'] = $str_group_deny;
$datarray['private'] = intval($private);
$datarray['id'] = $event_id;
$datarray['created'] = $created;
$datarray['edited'] = $edited;
$datarray['timezone'] = $tz;
if(intval($_REQUEST['preview'])) {
$datarray = array();
$datarray['dtstart'] = $start;
$datarray['dtend'] = $finish;
$datarray['summary'] = $summary;
$datarray['description'] = $desc;
$datarray['location'] = $location;
$datarray['etype'] = $type;
$datarray['adjust'] = $adjust;
$datarray['nofinish'] = 0;
$datarray['uid'] = $uid;
$datarray['account'] = get_account_id();
$datarray['event_xchan'] = $channel['channel_hash'];
$datarray['allow_cid'] = $str_contact_allow;
$datarray['allow_gid'] = $str_group_allow;
$datarray['deny_cid'] = $str_contact_deny;
$datarray['deny_gid'] = $str_group_deny;
$datarray['private'] = intval($private);
$datarray['id'] = $event_id;
$datarray['created'] = $created;
$datarray['edited'] = $edited;
$datarray['timezone'] = $tz;
if (intval($_REQUEST['preview'])) {
$html = format_event_html($datarray);
echo $html;
killme();
}
$event = event_store_event($datarray);
if($post_tags)
if ($post_tags)
$datarray['term'] = $post_tags;
$item_id = event_store_item($datarray,$event);
if($item_id) {
$item_id = event_store_item($datarray, $event);
if ($item_id) {
$r = q("select * from item where id = %d",
intval($item_id)
);
if($r) {
if ($r) {
xchan_query($r);
$sync_item = fetch_post_tags($r);
$z = q("select * from event where event_hash = '%s' and uid = %d limit 1",
$z = q("select * from event where event_hash = '%s' and uid = %d limit 1",
dbesc($r[0]['resource_id']),
intval($channel['channel_id'])
);
if($z) {
Libsync::build_sync_packet($channel['channel_id'],array('event_item' => array(encode_item($sync_item[0],true)),'event' => $z));
if ($z) {
Libsync::build_sync_packet($channel['channel_id'], array('event_item' => array(encode_item($sync_item[0], true)), 'event' => $z));
}
}
}
\Zotlabs\Daemon\Master::Summon(array('Notifier','event',$item_id));
Master::Summon(array('Notifier', 'event', $item_id));
killme();
}
function get() {
if(argc() > 2 && argv(1) == 'ical') {
if (argc() > 2 && argv(1) == 'ical') {
$event_id = argv(2);
require_once('include/security.php');
$sql_extra = permissions_sql(local_channel());
$r = q("select * from event where event_hash = '%s' $sql_extra limit 1",
dbesc($event_id)
);
if($r) {
if ($r) {
header('Content-type: text/calendar');
header('content-disposition: attachment; filename="' . t('event') . '-' . $event_id . '.ics"' );
header('content-disposition: attachment; filename="' . t('event') . '-' . $event_id . '.ics"');
echo ical_wrapper($r);
killme();
}
else {
notice( t('Event not found.') . EOL );
notice(t('Event not found.') . EOL);
return;
}
}
if(! local_channel()) {
notice( t('Permission denied.') . EOL);
if (!local_channel()) {
notice(t('Permission denied.') . EOL);
return;
}
if((argc() > 2) && (argv(1) === 'ignore') && intval(argv(2))) {
$r = q("update event set dismissed = 1 where id = %d and uid = %d",
intval(argv(2)),
intval(local_channel())
);
}
if((argc() > 2) && (argv(1) === 'unignore') && intval(argv(2))) {
$r = q("update event set dismissed = 0 where id = %d and uid = %d",
if ((argc() > 2) && (argv(1) === 'ignore') && intval(argv(2))) {
q("update event set dismissed = 1 where id = %d and uid = %d",
intval(argv(2)),
intval(local_channel())
);
}
$channel = \App::get_channel();
$mode = 'view';
$export = false;
$ignored = ((x($_REQUEST,'ignored')) ? " and dismissed = " . intval($_REQUEST['ignored']) . " " : '');
if ((argc() > 2) && (argv(1) === 'unignore') && intval(argv(2))) {
q("update event set dismissed = 0 where id = %d and uid = %d",
intval(argv(2)),
intval(local_channel())
);
}
if(argc() > 1) {
if(argc() > 2 && argv(1) === 'add') {
$mode = 'add';
$mode = 'view';
$export = false;
$ignored = ((x($_REQUEST, 'ignored')) ? " and dismissed = " . intval($_REQUEST['ignored']) . " " : '');
if (argc() > 1) {
if (argc() > 2 && argv(1) === 'add') {
$mode = 'add';
$item_id = intval(argv(2));
}
if(argc() > 2 && argv(1) === 'drop') {
$mode = 'drop';
if (argc() > 2 && argv(1) === 'drop') {
$mode = 'drop';
$event_id = argv(2);
}
if(argc() <= 2 && argv(1) === 'export') {
if (argc() <= 2 && argv(1) === 'export') {
$export = true;
}
if(argc() > 2 && intval(argv(1)) && intval(argv(2))) {
if (argc() > 2 && intval(argv(1)) && intval(argv(2))) {
$mode = 'view';
}
if(argc() <= 2) {
$mode = 'view';
if (argc() <= 2) {
$mode = 'view';
$event_id = argv(1);
}
}
if($mode === 'add') {
event_addtocal($item_id,local_channel());
if ($mode === 'add') {
event_addtocal($item_id, local_channel());
killme();
}
if($mode == 'view') {
if ($mode == 'view') {
/* edit/create form */
if($event_id) {
$r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1",
if ($event_id) {
q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1",
dbesc($event_id),
intval(local_channel())
);
if(count($r))
$orig_event = $r[0];
}
$channel = \App::get_channel();
if (argv(1) === 'json'){
if (x($_GET,'start')) $start = $_GET['start'];
if (x($_GET,'end')) $finish = $_GET['end'];
$channel = App::get_channel();
if (argv(1) === 'json') {
if (x($_GET, 'start')) $start = $_GET['start'];
if (x($_GET, 'end')) $finish = $_GET['end'];
}
$start = datetime_convert('UTC','UTC',$start);
$finish = datetime_convert('UTC','UTC',$finish);
$adjust_start = datetime_convert('UTC', date_default_timezone_get(), $start);
$start = datetime_convert('UTC', 'UTC', $start);
$finish = datetime_convert('UTC', 'UTC', $finish);
$adjust_start = datetime_convert('UTC', date_default_timezone_get(), $start);
$adjust_finish = datetime_convert('UTC', date_default_timezone_get(), $finish);
if (x($_GET,'id')){
$r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan, item.id as item_id
if (x($_GET, 'id')) {
$r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan, item.id as item_id
from event left join item on item.resource_id = event.event_hash
where item.resource_type = 'event' and event.uid = %d and event.id = %d limit 1",
intval(local_channel()),
intval($_GET['id'])
);
}
elseif($export) {
elseif ($export) {
$r = q("SELECT event.*, item.id as item_id
from event left join item on item.resource_id = event.event_hash
where event.uid = %d and event.dtstart > '%s' and event.dtend > event.dtstart",
@@ -335,104 +333,105 @@ class Channel_calendar extends \Zotlabs\Web\Controller {
dbesc($adjust_finish)
);
}
if($r && ! $export) {
if ($r && !$export) {
xchan_query($r);
$r = fetch_post_tags($r,true);
$r = fetch_post_tags($r, true);
$r = sort_by_date($r);
}
$events = [];
if($r) {
foreach($r as $rr) {
if ($r) {
foreach ($r as $rr) {
$start = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['dtstart'], 'c') : datetime_convert('UTC', 'UTC', $rr['dtstart'], 'c'));
if ($rr['nofinish']){
if ($rr['nofinish']) {
$end = null;
} else {
}
else {
$end = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['dtend'], 'c') : datetime_convert('UTC', 'UTC', $rr['dtend'], 'c'));
}
$catsenabled = feature_enabled(local_channel(),'categories');
$categories = '';
if($catsenabled){
if($rr['term']) {
$catsenabled = feature_enabled(local_channel(), 'categories');
$categories = '';
if ($catsenabled) {
if ($rr['term']) {
$cats = get_terms_oftype($rr['term'], TERM_CATEGORY);
foreach ($cats as $cat) {
if(strlen($categories))
if (strlen($categories))
$categories .= ', ';
$categories .= $cat['term'];
}
}
}
$edit = ((local_channel() && $rr['author_xchan'] == get_observer_hash()) ? array(z_root().'/events/'.$rr['event_hash'].'?expandform=1',t('Edit event'),'','') : false);
$drop = array(z_root().'/events/drop/'.$rr['event_hash'],t('Delete event'),'','');
$edit = ((local_channel() && $rr['author_xchan'] == get_observer_hash()) ? array(z_root() . '/events/' . $rr['event_hash'] . '?expandform=1', t('Edit event'), '', '') : false);
$drop = array(z_root() . '/events/drop/' . $rr['event_hash'], t('Delete event'), '', '');
$tz = get_iconfig($rr, 'event', 'timezone');
if(! $tz)
if (!$tz)
$tz = 'UTC';
$events[] = array(
'calendar_id' => 'channel_calendar',
'rw' => true,
'id'=>$rr['id'],
'uri' => $rr['event_hash'],
'timezone' => $tz,
'start'=> $start,
'end' => $end,
'drop' => $drop,
'allDay' => (($rr['adjust']) ? 0 : 1),
'title' => html_entity_decode($rr['summary'], ENT_COMPAT, 'UTF-8'),
'editable' => $edit ? true : false,
'item' => $rr,
'plink' => [$rr['plink'], t('Link to source')],
'rw' => true,
'id' => $rr['id'],
'uri' => $rr['event_hash'],
'timezone' => $tz,
'start' => $start,
'end' => $end,
'drop' => $drop,
'allDay' => (($rr['adjust']) ? 0 : 1),
'title' => html_entity_decode($rr['summary'], ENT_COMPAT, 'UTF-8'),
'editable' => $edit ? true : false,
'item' => $rr,
'plink' => [$rr['plink'], t('Link to source')],
'description' => html_entity_decode($rr['description'], ENT_COMPAT, 'UTF-8'),
'location' => html_entity_decode($rr['location'], ENT_COMPAT, 'UTF-8'),
'allow_cid' => expand_acl($rr['allow_cid']),
'allow_gid' => expand_acl($rr['allow_gid']),
'deny_cid' => expand_acl($rr['deny_cid']),
'deny_gid' => expand_acl($rr['deny_gid']),
'categories' => $categories
'location' => html_entity_decode($rr['location'], ENT_COMPAT, 'UTF-8'),
'allow_cid' => expand_acl($rr['allow_cid']),
'allow_gid' => expand_acl($rr['allow_gid']),
'deny_cid' => expand_acl($rr['deny_cid']),
'deny_gid' => expand_acl($rr['deny_gid']),
'categories' => $categories
);
}
}
if($export) {
if ($export) {
header('Content-type: text/calendar');
header('content-disposition: attachment; filename="' . t('calendar') . '-' . $channel['channel_address'] . '.ics"' );
header('content-disposition: attachment; filename="' . t('calendar') . '-' . $channel['channel_address'] . '.ics"');
echo ical_wrapper($r);
killme();
}
if (\App::$argv[1] === 'json'){
if (App::$argv[1] === 'json') {
json_return_and_die($events);
}
}
if($mode === 'drop' && $event_id) {
if ($mode === 'drop' && $event_id) {
$r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1",
dbesc($event_id),
intval(local_channel())
);
$sync_event = $r[0];
if($r) {
if ($r) {
$r = q("delete from event where event_hash = '%s' and uid = %d",
dbesc($event_id),
intval(local_channel())
);
if($r) {
if ($r) {
$sync_event['event_deleted'] = 1;
Libsync::build_sync_packet(0,array('event' => array($sync_event)));
Libsync::build_sync_packet(0, array('event' => array($sync_event)));
$i = q("select * from item where resource_type = 'event' and resource_id = '%s' and uid = %d",
dbesc($event_id),
@@ -441,11 +440,11 @@ class Channel_calendar extends \Zotlabs\Web\Controller {
if ($i) {
$can_delete = false;
$can_delete = false;
$local_delete = true;
$ob_hash = get_observer_hash();
if($ob_hash && ($ob_hash === $i[0]['author_xchan'] || $ob_hash === $i[0]['owner_xchan'] || $ob_hash === $i[0]['source_xchan'])) {
if ($ob_hash && ($ob_hash === $i[0]['author_xchan'] || $ob_hash === $i[0]['owner_xchan'] || $ob_hash === $i[0]['source_xchan'])) {
$can_delete = true;
}
@@ -453,49 +452,49 @@ class Channel_calendar extends \Zotlabs\Web\Controller {
// If the item originated on this site+channel the deletion will propagate downstream.
// Otherwise just the local copy is removed.
if(is_site_admin()) {
if (is_site_admin()) {
$local_delete = true;
if(intval($i[0]['item_origin']))
if (intval($i[0]['item_origin']))
$can_delete = true;
}
if($can_delete || $local_delete) {
if ($can_delete || $local_delete) {
// if this is a different page type or it's just a local delete
// but not by the item author or owner, do a simple deletion
$complex = false;
$complex = false;
if(intval($i[0]['item_type']) || ($local_delete && (! $can_delete))) {
if (intval($i[0]['item_type']) || ($local_delete && (!$can_delete))) {
drop_item($i[0]['id']);
}
else {
// complex deletion that needs to propagate and be performed in phases
drop_item($i[0]['id'],true,DROPITEM_PHASE1);
drop_item($i[0]['id'], true, DROPITEM_PHASE1);
$complex = true;
}
$ii = q("select * from item where id = %d",
intval($i[0]['id'])
);
if($ii) {
if ($ii) {
xchan_query($ii);
$sync_item = fetch_post_tags($ii);
Libsync::build_sync_packet($i[0]['uid'],array('item' => array(encode_item($sync_item[0],true))));
Libsync::build_sync_packet($i[0]['uid'], array('item' => array(encode_item($sync_item[0], true))));
}
if($complex) {
tag_deliver($i[0]['uid'],$i[0]['id']);
if ($complex) {
tag_deliver($i[0]['uid'], $i[0]['id']);
}
}
}
killme();
}
notice( t('Failed to remove event' ) . EOL);
notice(t('Failed to remove event') . EOL);
killme();
}
}
}
}

View File

@@ -70,7 +70,7 @@ class Chanview extends \Zotlabs\Web\Controller {
$zf = Zotfinger::exec($_REQUEST['url'], null);
if(array_path_exists('signature/signer',$zf) && $zf['signature']['signer'] === $_REQUEST['url'] && intval($zf['signature']['header_valid'])) {
Libzot::import_xchan($j);
Libzot::import_xchan($zf['data']);
$r = q("select * from xchan where xchan_url = '%s'",
dbesc($_REQUEST['url'])
);

View File

@@ -105,7 +105,7 @@ class Cloud extends Controller {
// All we need to do now, is to fire up the server
$server->exec();
$server->start();
if($browser->build_page)
construct_page();

View File

@@ -109,6 +109,7 @@ class Connections extends \Zotlabs\Web\Controller {
case 'all':
$head = t('All');
break;
default:
$search_flags = " and abook_blocked = 0 and abook_ignored = 0 and abook_hidden = 0 and abook_archived = 0 and abook_not_here = 0 ";
$active = true;
@@ -238,7 +239,7 @@ class Connections extends \Zotlabs\Web\Controller {
}
$r = q("SELECT COUNT(abook.abook_id) AS total FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash
where abook_channel = %d and abook_self = 0 and xchan_deleted = 0 and xchan_orphan = 0 $sql_extra $sql_extra2 ",
where abook_channel = %d and abook_self = 0 and xchan_deleted = 0 and xchan_orphan = 0 $sql_extra ",
intval(local_channel())
);
if($r) {
@@ -247,7 +248,7 @@ class Connections extends \Zotlabs\Web\Controller {
}
$r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash
WHERE abook_channel = %d and abook_self = 0 and xchan_deleted = 0 and xchan_orphan = 0 $sql_extra $sql_extra2 ORDER BY $sql_order LIMIT %d OFFSET %d ",
WHERE abook_channel = %d and abook_self = 0 and xchan_deleted = 0 and xchan_orphan = 0 $sql_extra ORDER BY $sql_order LIMIT %d OFFSET %d ",
intval(local_channel()),
intval(App::$pager['itemspage']),
intval(App::$pager['start'])

View File

@@ -9,6 +9,7 @@ namespace Zotlabs\Module;
use App;
use Zotlabs\Lib\Apps;
use Zotlabs\Lib\Crypto;
use Zotlabs\Lib\Libzot;
use Zotlabs\Lib\Libsync;
use Zotlabs\Daemon\Master;
@@ -32,10 +33,10 @@ class Connedit extends Controller {
*/
function init() {
if(! local_channel())
return;
if((argc() >= 2) && intval(argv(1))) {
$r = q("SELECT abook.*, xchan.*
FROM abook left join xchan on abook_xchan = xchan_hash
@@ -47,54 +48,54 @@ class Connedit extends Controller {
App::$poi = array_shift($r);
}
}
$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();
// TODO if configured for hassle-free permissions, we'll post the form with ajax as soon as the
// connection enable is toggled to a special autopost url and set permissions immediately, leaving
// the other form elements alone pending a manual submit of the form. The downside is that there
// will be a window of opportunity when the permissions have been set but before you've had a chance
// to review and possibly restrict them. The upside is we won't have to warn you that your connection
// can't do anything until you save the bloody form.
$autopost = (((argc() > 2) && (argv(2) === 'auto')) ? true : false);
$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
}
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);
$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);
@@ -107,8 +108,8 @@ class Connedit extends Controller {
$autoperms = null;
$is_self = false;
}
$profile_id = ((array_key_exists('profile_assign',$_POST)) ? $_POST['profile_assign'] : $orig_record[0]['abook_profile']);
if($profile_id) {
@@ -121,17 +122,17 @@ class Connedit extends Controller {
return;
}
}
$abook_incl = ((array_key_exists('abook_incl',$_POST)) ? escape_tags($_POST['abook_incl']) : $orig_record[0]['abook_incl']);
$abook_excl = ((array_key_exists('abook_excl',$_POST)) ? escape_tags($_POST['abook_excl']) : $orig_record[0]['abook_excl']);
$hidden = intval($_POST['hidden']);
$priority = intval($_POST['poll']);
if($priority > 5 || $priority < 0)
$priority = 0;
if(! array_key_exists('closeness',$_POST)) {
$_POST['closeness'] = 80;
}
@@ -139,15 +140,15 @@ class Connedit extends Controller {
if($closeness < 0 || $closeness > 99) {
$closeness = 80;
}
$rating = intval($_POST['rating']);
if($rating < (-10))
$rating = (-10);
if($rating > 10)
$rating = 10;
$rating_text = trim(escape_tags($_REQUEST['rating_text']));
$all_perms = Permissions::Perms();
if($all_perms) {
@@ -168,27 +169,27 @@ class Connedit extends Controller {
}
}
if(! is_null($autoperms))
if(! is_null($autoperms))
set_pconfig($channel['channel_id'],'system','autoperms',$autoperms);
$new_friend = false;
// only store a record and notify the directory if the rating changed
if(! $is_self) {
$signed = $orig_record[0]['abook_xchan'] . '.' . $rating . '.' . $rating_text;
$sig = base64url_encode(rsa_sign($signed,$channel['channel_prvkey']));
$sig = base64url_encode(Crypto::sign($signed,$channel['channel_prvkey']));
$rated = ((intval($rating) || strlen($rating_text)) ? true : false);
$record = 0;
$z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1",
dbesc($channel['channel_hash']),
dbesc($orig_record[0]['abook_xchan'])
);
if($z) {
if(($z[0]['xlink_rating'] != $rating) || ($z[0]['xlink_rating_text'] != $rating_text)) {
$record = $z[0]['xlink_id'];
@@ -223,18 +224,18 @@ class Connedit extends Controller {
Master::Summon(array('Ratenotif','rating',$record));
}
}
if(($_REQUEST['pending']) && intval($orig_record[0]['abook_pending'])) {
$new_friend = true;
// @fixme it won't be common, but when you accept a new connection request
// the permissions will now be that of your permissions role and ignore
// any you may have set manually on the form. We'll probably see a bug if somebody
// tries to set the permissions *and* approve the connection in the same
// request. The workaround is to approve the connection, then go back and
// adjust permissions as desired.
$p = Permissions::connect_perms(local_channel());
$my_perms = $p['perms'];
if($my_perms) {
@@ -247,7 +248,7 @@ class Connedit extends Controller {
$abook_pending = (($new_friend) ? 0 : $orig_record[0]['abook_pending']);
$r = q("UPDATE abook SET abook_profile = '%s', abook_closeness = %d, abook_pending = %d,
abook_incl = '%s', abook_excl = '%s'
where abook_id = %d AND abook_channel = %d",
@@ -259,7 +260,7 @@ class Connedit extends Controller {
intval($contact_id),
intval(local_channel())
);
if($r)
info( t('Connection updated.') . EOL);
else
@@ -267,16 +268,16 @@ class Connedit extends Controller {
if(! intval(App::$poi['abook_self'])) {
if($new_friend) {
Master::Summon( [ 'Notifier', 'permission_accept', $contact_id ] );
Master::Summon( [ 'Notifier', 'permission_accept', $contact_id ] );
}
Master::Summon( [
'Notifier',
(($new_friend) ? 'permission_create' : 'permission_update'),
$contact_id
Master::Summon( [
'Notifier',
(($new_friend) ? 'permission_create' : 'permission_update'),
$contact_id
]);
}
if($new_friend) {
$default_group = $channel['channel_default_group'];
if($default_group) {
@@ -285,11 +286,11 @@ class Connedit extends Controller {
if($g)
group_add_member(local_channel(),'',App::$poi['abook_xchan'],$g['id']);
}
// Check if settings permit ("post new friend activity" is allowed, and
// friends in general or this friend in particular aren't hidden)
// and send out a new friend activity
$pr = q("select * from profile where uid = %d and is_default = 1 and hide_friends = 0",
intval($channel['channel_id'])
);
@@ -305,23 +306,23 @@ class Connedit extends Controller {
$xarr['deny_cid'] = $channel['channel_deny_cid'];
$xarr['deny_gid'] = $channel['channel_deny_gid'];
$xarr['item_private'] = (($xarr['allow_cid']||$xarr['allow_gid']||$xarr['deny_cid']||$xarr['deny_gid']) ? 1 : 0);
$xarr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t('is now connected to') . ' ' . '[zrl=' . App::$poi['xchan_url'] . ']' . App::$poi['xchan_name'] . '[/zrl]';
$xarr['body'] .= "\n\n\n" . '[zrl=' . App::$poi['xchan_url'] . '][zmg=80x80]' . App::$poi['xchan_photo_m'] . '[/zmg][/zrl]';
post_activity_item($xarr);
}
// pull in a bit of content if there is any to pull in
Master::Summon(array('Onepoll',$contact_id));
}
// 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",
@@ -331,34 +332,34 @@ class Connedit extends Controller {
if($r) {
App::$poi = $r[0];
}
if($new_friend) {
$arr = array('channel_id' => local_channel(), 'abook' => App::$poi);
call_hooks('accept_follow', $arr);
}
$this->connedit_clone($a);
if(($_REQUEST['pending']) && (!$_REQUEST['done']))
goaway(z_root() . '/connections/ifpending');
return;
}
/* @brief Clone connection
*
*
*/
function connedit_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",
@@ -368,40 +369,40 @@ class Connedit extends Controller {
if($r) {
App::$poi = array_shift($r);
}
$clone = App::$poi;
unset($clone['abook_id']);
unset($clone['abook_account']);
unset($clone['abook_channel']);
$abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']);
if($abconfig)
$clone['abconfig'] = $abconfig;
Libsync::build_sync_packet(0 /* use the current local_channel */, array('abook' => array($clone)));
}
/* @brief Generate content of connection edit 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 = Permissions::connect_perms(local_channel());
$o .= "<script>function connectDefaultShare() {
@@ -415,13 +416,13 @@ class Connedit extends Controller {
}
}
$o .= " }\n</script>\n";
if(argc() == 3) {
$contact_id = intval(argv(1));
if(! $contact_id)
return;
$cmd = argv(2);
$orig_record = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash
@@ -429,17 +430,17 @@ class Connedit extends Controller {
intval($contact_id),
intval(local_channel())
);
if(! count($orig_record)) {
notice( t('Could not access address book record.') . EOL);
goaway(z_root() . '/connections');
}
if($cmd === 'update') {
// pull feed and consume it, which should subscribe to the hub.
Master::Summon(array('Poller',$contact_id));
goaway(z_root() . '/connedit/' . $contact_id);
}
if($cmd === 'fetchvc') {
@@ -474,7 +475,7 @@ class Connedit extends Controller {
dbesc($orig_record[0]['xchan_hash'])
);
$cmd = 'refresh';
}
}
if($cmd === 'refresh') {
if($orig_record[0]['xchan_network'] === 'zot') {
@@ -486,13 +487,13 @@ class Connedit extends Controller {
notice( t('Refresh failed - channel is currently unavailable.') );
}
else {
// if you are on a different network we'll force a refresh of the connection basic info
Master::Summon(array('Notifier','permission_update',$contact_id));
}
goaway(z_root() . '/connedit/' . $contact_id);
}
if($cmd === 'block') {
if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_BLOCKED)) {
$this->connedit_clone($a);
@@ -501,7 +502,7 @@ class Connedit extends Controller {
notice(t('Unable to set address book parameters.') . EOL);
goaway(z_root() . '/connedit/' . $contact_id);
}
if($cmd === 'ignore') {
if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_IGNORED)) {
$this->connedit_clone($a);
@@ -510,7 +511,7 @@ class Connedit extends Controller {
notice(t('Unable to set address book parameters.') . EOL);
goaway(z_root() . '/connedit/' . $contact_id);
}
if($cmd === 'archive') {
if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_ARCHIVED)) {
$this->connedit_clone($a);
@@ -519,7 +520,7 @@ class Connedit extends Controller {
notice(t('Unable to set address book parameters.') . EOL);
goaway(z_root() . '/connedit/' . $contact_id);
}
if($cmd === 'hide') {
if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_HIDDEN)) {
$this->connedit_clone($a);
@@ -528,10 +529,10 @@ class Connedit extends Controller {
notice(t('Unable to set address book parameters.') . EOL);
goaway(z_root() . '/connedit/' . $contact_id);
}
// We'll prevent somebody from unapproving an already approved contact.
// Though maybe somebody will want this eventually (??)
if($cmd === 'approve') {
if(intval($orig_record[0]['abook_pending'])) {
if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_PENDING)) {
@@ -542,10 +543,10 @@ class Connedit extends Controller {
}
goaway(z_root() . '/connedit/' . $contact_id);
}
if($cmd === 'drop') {
contact_remove(local_channel(), $orig_record[0]['abook_id']);
Master::Summon( [ 'Notifier', 'purge', local_channel(), $orig_record[0]['xchan_hash'] ] );
@@ -556,17 +557,17 @@ class Connedit extends Controller {
'entry_deleted' => true))
)
);
info( t('Connection has been removed.') . EOL );
if(x($_SESSION,'return_url'))
goaway(z_root() . '/' . $_SESSION['return_url']);
goaway(z_root() . '/contacts');
}
}
if(App::$poi) {
$abook_prev = 0;
$abook_next = 0;
@@ -595,14 +596,14 @@ class Connedit extends Controller {
}
$tools = array(
'view' => array(
'label' => t('View Profile'),
'url' => chanlink_cid($contact['abook_id']),
'sel' => '',
'title' => sprintf( t('View %s\'s profile'), $contact['xchan_name']),
),
'refresh' => array(
'label' => t('Refresh Permissions'),
'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/refresh',
@@ -616,14 +617,14 @@ class Connedit extends Controller {
'sel' => '',
'title' => t('Fetch updated photo'),
),
'recent' => array(
'label' => t('Recent Activity'),
'url' => z_root() . '/network/?f=&cid=' . $contact['abook_id'],
'sel' => '',
'title' => t('View recent posts and comments'),
),
'block' => array(
'label' => (intval($contact['abook_blocked']) ? t('Unblock') : t('Block')),
'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/block',
@@ -631,7 +632,7 @@ class Connedit extends Controller {
'title' => t('Block (or Unblock) all communications with this connection'),
'info' => (intval($contact['abook_blocked']) ? t('This connection is blocked!') : ''),
),
'ignore' => array(
'label' => (intval($contact['abook_ignored']) ? t('Unignore') : t('Ignore')),
'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/ignore',
@@ -639,7 +640,7 @@ class Connedit extends Controller {
'title' => t('Ignore (or Unignore) all inbound communications from this connection'),
'info' => (intval($contact['abook_ignored']) ? t('This connection is ignored!') : ''),
),
'archive' => array(
'label' => (intval($contact['abook_archived']) ? t('Unarchive') : t('Archive')),
'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/archive',
@@ -647,7 +648,7 @@ class Connedit extends Controller {
'title' => t('Archive (or Unarchive) this connection - mark channel dead but keep content'),
'info' => (intval($contact['abook_archived']) ? t('This connection is archived!') : ''),
),
'hide' => array(
'label' => (intval($contact['abook_hidden']) ? t('Unhide') : t('Hide')),
'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/hide',
@@ -655,18 +656,18 @@ class Connedit extends Controller {
'title' => t('Hide or Unhide this connection from your other connections'),
'info' => (intval($contact['abook_hidden']) ? t('This connection is hidden!') : ''),
),
'delete' => array(
'label' => t('Delete'),
'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/drop',
'sel' => '',
'title' => t('Delete this connection'),
),
);
if($contact['xchan_network'] === 'zot') {
if(in_array($contact['xchan_network'], ['zot6', 'zot'])) {
$tools['fetchvc'] = [
'label' => t('Fetch Vcard'),
'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/fetchvc',
@@ -684,24 +685,24 @@ class Connedit extends Controller {
'sel' => '',
'title' => t('Open Individual Permissions section by default'),
];
$self = false;
if(intval($contact['abook_self'])) {
$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);
$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");
if(Apps::system_app_installed(local_channel(),'Affinity Tool')) {
$sections['affinity'] = [
@@ -710,7 +711,7 @@ class Connedit extends Controller {
'sel' => '',
'title' => t('Open Set Affinity section by default'),
];
$labels = [
t('Me'),
t('Family'),
@@ -720,7 +721,7 @@ class Connedit extends Controller {
];
call_hooks('affinity_labels',$labels);
$label_str = '';
if($labels) {
foreach($labels as $l) {
if($label_str) {
@@ -731,11 +732,11 @@ class Connedit extends Controller {
$label_str .= "'" . $l . "'";
}
}
$slider_tpl = get_markup_template('contact_slider.tpl');
$slideval = intval($contact['abook_closeness']);
$slide = replace_macros($slider_tpl,array(
'$min' => 1,
'$val' => $slideval,
@@ -751,22 +752,22 @@ class Connedit extends Controller {
'title' => t('Open Custom Filter section by default'),
];
}
$rating_val = 0;
$rating_text = '';
$xl = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1",
dbesc($channel['channel_hash']),
dbesc($contact['xchan_hash'])
);
if($xl) {
$rating_val = intval($xl[0]['xlink_rating']);
$rating_text = $xl[0]['xlink_rating_text'];
}
$rating_enabled = get_config('system','rating_enabled');
if($rating_enabled) {
$rating = replace_macros(get_markup_template('rating_slider.tpl'),array(
'$min' => -10,
@@ -776,28 +777,28 @@ class Connedit extends Controller {
else {
$rating = false;
}
$perms = array();
$channel = App::get_channel();
$global_perms = Permissions::Perms();
$existing = get_all_perms(local_channel(),$contact['abook_xchan'],false);
$unapproved = array('pending', t('Approve this connection'), '', t('Accept connection to allow communication'), array(t('No'),('Yes')));
$multiprofs = ((feature_enabled(local_channel(),'multi_profiles')) ? true : false);
if($slide && !$multiprofs)
$affinity = t('Set Affinity');
if(!$slide && $multiprofs)
$affinity = t('Set Profile');
if($slide && $multiprofs)
$affinity = t('Set Affinity & Profile');
$theirs = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'their_perms'",
intval(local_channel()),
dbesc($contact['abook_xchan'])
@@ -812,20 +813,20 @@ class Connedit extends Controller {
foreach($global_perms as $k => $v) {
$thisperm = get_abconfig(local_channel(),$contact['abook_xchan'],'my_perms',$k);
//fixme
$checkinherited = PermissionLimits::Get(local_channel(),$k);
// For auto permissions (when $self is true) we don't want to look at existing
// permissions because they are enabled for the channel owner
if((! $self) && ($existing[$k]))
$thisperm = "1";
$perms[] = array('perms_' . $k, $v, ((array_key_exists($k,$their_perms)) ? intval($their_perms[$k]) : ''),$thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '' : '1'), '', $checkinherited);
}
$pcat = new Permcat(local_channel());
$pcatlist = $pcat->listing();
$permcats = [];
@@ -838,23 +839,23 @@ class Connedit extends Controller {
$locstr = locations_by_netid($contact['xchan_hash']);
if(! $locstr)
$locstr = unpunify($contact['xchan_url']);
$clone_warn = '';
$clonable = (in_array($contact['xchan_network'],['zot', 'zot6', 'rss']) ? true : false);
if(! $clonable) {
$clone_warn = '<strong>';
$clone_warn .= ((intval($contact['abook_not_here']))
$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'])),
'$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),
@@ -910,7 +911,7 @@ class Connedit extends Controller {
'$name' => $contact['xchan_name'],
'$abook_prev' => $abook_prev,
'$abook_next' => $abook_next,
'$vcard_label' => t('Details'),
'$vcard_label' => t('Details'),
'$displayname' => $displayname,
'$name_label' => t('Name'),
'$org_label' => t('Organisation'),
@@ -939,13 +940,13 @@ class Connedit extends Controller {
'$zip_code' => t('ZIP Code'),
'$country' => t('Country')
]);
$arr = array('contact' => $contact,'output' => $o);
call_hooks('contact_edit', $arr);
return $arr['output'];
}
}
}
}

View File

@@ -124,7 +124,7 @@ class Dav extends \Zotlabs\Web\Controller {
// $server->addPlugin(new \Zotlabs\Storage\QuotaPlugin($auth));
// All we need to do now, is to fire up the server
$server->exec();
$server->start();
killme();
}

View File

@@ -19,21 +19,21 @@ class Display extends \Zotlabs\Web\Controller {
if(argc() > 1) {
$module_format = substr(argv(1),strrpos(argv(1),'.') + 1);
if(! in_array($module_format,['atom','zot','json']))
$module_format = 'html';
$module_format = 'html';
}
if(observer_prohibited()) {
notice( t('Public access denied.') . EOL);
return;
}
if(argc() > 1) {
$item_hash = argv(1);
if($module_format !== 'html') {
$item_hash = substr($item_hash,0,strrpos($item_hash,'.'));
}
}
if($_REQUEST['mid'])
$item_hash = $_REQUEST['mid'];
@@ -42,19 +42,19 @@ class Display extends \Zotlabs\Web\Controller {
notice( t('Item not found.') . EOL);
return;
}
$observer_is_owner = false;
if(local_channel() && (! $update)) {
$channel = \App::get_channel();
$channel_acl = array(
'allow_cid' => $channel['channel_allow_cid'],
'allow_gid' => $channel['channel_allow_gid'],
'deny_cid' => $channel['channel_deny_cid'],
'allow_cid' => $channel['channel_allow_cid'],
'allow_gid' => $channel['channel_allow_gid'],
'deny_cid' => $channel['channel_deny_cid'],
'deny_gid' => $channel['channel_deny_gid']
);
);
$x = array(
'is_owner' => true,
@@ -62,7 +62,7 @@ class Display extends \Zotlabs\Web\Controller {
'default_location' => $channel['channel_location'],
'nickname' => $channel['channel_address'],
'lockstate' => (($group || $cid || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
'acl' => populate_acl($channel_acl,true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
'acl' => populate_acl($channel_acl,true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
'permissions' => $channel_acl,
'bang' => '',
'visitor' => true,
@@ -75,21 +75,21 @@ class Display extends \Zotlabs\Web\Controller {
'jotnets' => true,
'reset' => t('Reset form')
);
$o = '<div id="jot-popup">';
$o .= status_editor($a,$x,false,'Display');
$o .= '</div>';
}
// This page can be viewed by anybody so the query could be complicated
// First we'll see if there is a copy of the item which is owned by us - if we're logged in locally.
// If that fails (or we aren't logged in locally),
// If that fails (or we aren't logged in locally),
// query an item in which the observer (if logged in remotely) has cid or gid rights
// and if that fails, look for a copy of the post that has no privacy restrictions.
// and if that fails, look for a copy of the post that has no privacy restrictions.
// If we find the post, but we don't find a copy that we're allowed to look at, this fact needs to be reported.
// find a copy of the item somewhere
$target_item = null;
if(strpos($item_hash,'b64.') === 0)
@@ -100,7 +100,7 @@ class Display extends \Zotlabs\Web\Controller {
$r = q("select id, uid, mid, parent, parent_mid, thr_parent, verb, item_type, item_deleted, author_xchan, item_blocked from item where mid like '%s' limit 1",
dbesc($item_hash . '%')
);
if($r) {
$target_item = $r[0];
}
@@ -117,14 +117,14 @@ class Display extends \Zotlabs\Web\Controller {
if($target_item['item_blocked'] == ITEM_MODERATED) {
goaway(z_root() . '/moderate/' . $target_item['id']);
}
$r = null;
if($target_item['item_type'] == ITEM_TYPE_WEBPAGE) {
$x = q("select * from channel where channel_id = %d limit 1",
intval($target_item['uid'])
);
$y = q("select * from iconfig left join item on iconfig.iid = item.id
$y = q("select * from iconfig left join item on iconfig.iid = item.id
where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'WEBPAGE' and item.id = %d limit 1",
intval($target_item['uid']),
intval($target_item['parent'])
@@ -141,7 +141,7 @@ class Display extends \Zotlabs\Web\Controller {
$x = q("select * from channel where channel_id = %d limit 1",
intval($target_item['uid'])
);
$y = q("select * from iconfig left join item on iconfig.iid = item.id
$y = q("select * from iconfig left join item on iconfig.iid = item.id
where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'ARTICLE' and item.id = %d limit 1",
intval($target_item['uid']),
intval($target_item['parent'])
@@ -160,7 +160,7 @@ class Display extends \Zotlabs\Web\Controller {
intval($target_item['uid'])
);
$y = q("select * from iconfig left join item on iconfig.iid = item.id
$y = q("select * from iconfig left join item on iconfig.iid = item.id
where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'CARD' and item.id = %d limit 1",
intval($target_item['uid']),
intval($target_item['parent'])
@@ -179,7 +179,7 @@ class Display extends \Zotlabs\Web\Controller {
notice( t('Page not found.') . EOL);
return '';
}
$simple_update = '';
if($update && $_SESSION['loadtime'])
$simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) ";
@@ -191,14 +191,14 @@ class Display extends \Zotlabs\Web\Controller {
//$mid = ((($target_item['verb'] == ACTIVITY_LIKE) || ($target_item['verb'] == ACTIVITY_DISLIKE)) ? $target_item['thr_parent'] : $target_item['mid']);
$mid = $target_item['mid'];
// if we got a decoded hash we must encode it again before handing to javascript
// if 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 .= "<script> var profile_uid = " . ((intval(local_channel())) ? local_channel() : (-1))
. "; var netargs = '?f='; var profile_page = " . \App::$pager['page'] . "; </script>\r\n";
\App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array(
'$baseurl' => z_root(),
'$pgtype' => 'display',
@@ -230,7 +230,7 @@ class Display extends \Zotlabs\Web\Controller {
'$mid' => (($mid) ? urlencode($mid) : '')
));
head_add_link([
head_add_link([
'rel' => 'alternate',
'type' => 'application/json+oembed',
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string),
@@ -269,20 +269,23 @@ class Display extends \Zotlabs\Web\Controller {
$sysid = 0;
$r = q("SELECT item.id as item_id from item
WHERE mid = '%s'
AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
AND item.deny_gid = '' AND item_private = 0 )
WHERE ( (mid = '%s'
AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
AND item.deny_gid = '' AND item_private = 0 )
and uid in ( " . stream_perms_api_uids(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " ))
OR uid = %d )
$sql_extra )
OR uid = %d ) ) ) OR
(mid = '%s' $sql_extra ) )
$item_normal
limit 1",
dbesc($target_item['parent_mid']),
intval($sysid)
intval($sysid),
dbesc($target_item['parent_mid'])
);
}
}
elseif($update && !$load) {
$r = null;
@@ -307,8 +310,8 @@ class Display extends \Zotlabs\Web\Controller {
$sysid = 0;
$r = q("SELECT item.parent AS item_id from item
WHERE parent_mid = '%s'
AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
AND item.deny_gid = '' AND item_private = 0 )
AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
AND item.deny_gid = '' AND item_private = 0 )
and uid in ( " . stream_perms_api_uids(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " ))
OR uid = %d )
$sql_extra )
@@ -320,7 +323,7 @@ class Display extends \Zotlabs\Web\Controller {
);
}
}
else {
$r = array();
}
@@ -328,7 +331,7 @@ class Display extends \Zotlabs\Web\Controller {
if($r) {
$parents_str = ids_to_querystr($r,'item_id');
if($parents_str) {
$items = q("SELECT item.*, item.id AS item_id
$items = q("SELECT item.*, item.id AS item_id
FROM item
WHERE parent in ( %s ) $item_normal ",
dbesc($parents_str)
@@ -341,10 +344,10 @@ class Display extends \Zotlabs\Web\Controller {
else {
$items = array();
}
switch($module_format) {
case 'html':
if ($update) {
@@ -363,7 +366,7 @@ class Display extends \Zotlabs\Web\Controller {
\App::$page['title'] = (($items[0]['title']) ? $items[0]['title'] . " - " . \App::$page['title'] : \App::$page['title']);
$o .= conversation($items, 'display', $update, 'client');
}
}
break;
@@ -380,7 +383,7 @@ class Display extends \Zotlabs\Web\Controller {
'$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);
@@ -406,13 +409,13 @@ class Display extends \Zotlabs\Web\Controller {
header('Content-type: application/atom+xml');
echo $atom;
killme();
}
$o .= '<div id="content-complete"></div>';
if((($update && $load) || $noscript_content) && (! $items)) {
$r = q("SELECT id, item_deleted FROM item WHERE mid = '%s' LIMIT 1",
dbesc($item_hash)
);
@@ -421,14 +424,14 @@ class Display extends \Zotlabs\Web\Controller {
if(intval($r[0]['item_deleted'])) {
notice( t('Item has been removed.') . EOL );
}
else {
notice( t('Permission denied.') . EOL );
else {
notice( t('Permission denied.') . EOL );
}
}
else {
notice( t('Item not found.') . EOL );
}
}
$_SESSION['loadtime'] = datetime_convert();

View File

@@ -58,9 +58,9 @@ class Editpost extends \Zotlabs\Web\Controller {
if ($catsenabled){
$itm = fetch_post_tags($itm);
$cats = get_terms_oftype($itm[0]['term'], TERM_CATEGORY);
foreach ($cats as $cat) {
if (strlen($category))
$category .= ', ';
@@ -95,6 +95,7 @@ class Editpost extends \Zotlabs\Web\Controller {
'defloc' => $channel['channel_location'],
'visitor' => true,
'title' => htmlspecialchars_decode($itm[0]['title'],ENT_COMPAT),
'summary' => htmlspecialchars_decode($itm[0]['summary'],ENT_COMPAT),
'category' => $category,
'showacl' => false,
'profile_uid' => $owner_uid,

View File

@@ -40,7 +40,8 @@ class Embedphotos extends \Zotlabs\Web\Controller {
if (!$href) {
json_return_and_die(array('errormsg' => 'Error retrieving link ' . $href, 'status' => false));
}
$resource_id = array_pop(explode('/', $href));
$arr = explode('/', $href);
$resource_id = array_pop($arr);
$x = self::photolink($resource_id);
if($x)
json_return_and_die(array('status' => true, 'photolink' => $x, 'resource_id' => $resource_id));

View File

@@ -15,12 +15,12 @@ class Fhublocs extends \Zotlabs\Web\Controller {
if(! is_site_admin())
return;
$o = '';
$r = q("select * from channel where channel_removed = 0");
$sitekey = get_config('system','pubkey');
if($r) {
foreach($r as $rr) {
@@ -38,14 +38,14 @@ class Fhublocs extends \Zotlabs\Web\Controller {
if($found) {
$o .= 'Hubloc exists for ' . $rr['channel_name'] . EOL;
continue;
}
}
}
$y = q("select xchan_addr from xchan where xchan_hash = '%s' limit 1",
dbesc($rr['channel_hash'])
);
if($y)
$primary_address = $y[0]['xchan_addr'];
$hub_address = channel_reddress($rr);
$primary = (($hub_address === $primary_address) ? 1 : 0);
@@ -56,9 +56,9 @@ class Fhublocs extends \Zotlabs\Web\Controller {
dbesc($rr['channel_hash']),
dbesc(z_root())
);
// Create a verified hub location pointing to this site.
/*
$h = hubloc_store_lowlevel(
[
@@ -69,7 +69,7 @@ class Fhublocs extends \Zotlabs\Web\Controller {
'hubloc_network' => 'zot',
'hubloc_primary' => $primary,
'hubloc_url' => z_root(),
'hubloc_url_sig' => base64url_encode(rsa_sign(z_root(),$rr['channel_prvkey'])),
'hubloc_url_sig' => base64url_encode(Crypto::sign(z_root(),$rr['channel_prvkey'])),
'hubloc_host' => \App::get_hostname(),
'hubloc_callback' => z_root() . '/post',
'hubloc_sitekey' => $sitekey
@@ -99,11 +99,11 @@ class Fhublocs extends \Zotlabs\Web\Controller {
$o . 'local hubloc created for ' . $rr['channel_name'] . EOL;
else
$o .= 'DB update failed for ' . $rr['channel_name'] . EOL;
}
return $o;
}
}
}

View File

@@ -1,6 +1,7 @@
<?php
namespace Zotlabs\Module;
use Zotlabs\Lib\Crypto;
use Zotlabs\Web\HTTPSig;
use Zotlabs\Lib\Libzot;
@@ -106,7 +107,7 @@ class Getfile extends \Zotlabs\Web\Controller {
killme();
}
if(! rsa_verify($hash . '.' . $time,base64url_decode($sig),$channel['channel_pubkey'])) {
if(! Crypto::verify($hash . '.' . $time,base64url_decode($sig),$channel['channel_pubkey'])) {
logger('verify failed.');
killme();
}

View File

@@ -8,6 +8,7 @@ require_once('include/import.php');
require_once('include/perm_upgrade.php');
require_once('library/urlify/URLify.php');
use Zotlabs\Lib\Crypto;
use Zotlabs\Lib\Libzot;
@@ -227,7 +228,7 @@ class Import extends \Zotlabs\Web\Controller {
'hubloc_network' => 'zot',
'hubloc_primary' => (($seize) ? 1 : 0),
'hubloc_url' => z_root(),
'hubloc_url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'])),
'hubloc_url_sig' => base64url_encode(Crypto::sign(z_root(),$channel['channel_prvkey'])),
'hubloc_host' => \App::get_hostname(),
'hubloc_callback' => z_root() . '/post',
'hubloc_sitekey' => get_config('system','pubkey'),
@@ -256,7 +257,7 @@ class Import extends \Zotlabs\Web\Controller {
'hubloc_network' => 'zot6',
'hubloc_primary' => (($seize) ? 1 : 0),
'hubloc_url' => z_root(),
'hubloc_url_sig' => 'sha256.' . base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'])),
'hubloc_url_sig' => 'sha256.' . base64url_encode(Crypto::sign(z_root(),$channel['channel_prvkey'])),
'hubloc_host' => \App::get_hostname(),
'hubloc_callback' => z_root() . '/zot',
'hubloc_sitekey' => get_config('system','pubkey'),

View File

@@ -132,13 +132,14 @@ class Item extends Controller {
$i = Activity::encode_item_collection($items, 'conversation/' . $item_id, 'OrderedCollection');
if($portable_id) {
ThreadListener::store(z_root() . '/item/' . $item_id,$portable_id);
}
if(! $i)
http_status_exit(404, 'Not found');
if($portable_id && (! intval($items[0]['item_private']))) {
ThreadListener::store(z_root() . '/item/' . $item_id, $portable_id);
}
$x = array_merge(['@context' => [
ACTIVITYSTREAMS_JSONLD_REV,
'https://w3id.org/security/v1',
@@ -237,6 +238,16 @@ class Item extends Controller {
if(! $i)
http_status_exit(404, 'Not found');
if ($portable_id && (! intval($items[0]['item_private']))) {
$c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'",
intval($items[0]['uid']),
dbesc($portable_id)
);
if (! $c) {
ThreadListener::store(z_root() . '/item/' . $item_id, $portable_id);
}
}
$x = array_merge(['@context' => [
ACTIVITYSTREAMS_JSONLD_REV,
'https://w3id.org/security/v1',
@@ -810,18 +821,7 @@ class Item extends Controller {
// and will require alternatives for alternative content-types (text/html, text/markdown, text/plain, etc.)
// we may need virtual or template classes to implement the possible alternatives
if(strpos($body,'[/summary]') !== false) {
$match = '';
$cnt = preg_match("/\[summary\](.*?)\[\/summary\]/ism",$body,$match);
if($cnt) {
$summary .= $match[1];
}
$body_content = preg_replace("/\[summary\](.*?)\[\/summary\]/ism", '',$body);
$body = trim($body_content);
}
$summary = cleanup_bbcode($summary);
$body = cleanup_bbcode($body);
// Look for tags and linkify them
@@ -876,15 +876,10 @@ class Item extends Controller {
if(! $preview) {
fix_attached_photo_permissions($profile_uid,$owner_xchan['xchan_hash'],((strpos($body,'[/crypt]')) ? $_POST['media_str'] : $body),$str_contact_allow,$str_group_allow,$str_contact_deny,$str_group_deny);
fix_attached_photo_permissions($profile_uid,$owner_xchan['xchan_hash'],((strpos($summary,'[/crypt]')) ? $_POST['media_str'] : $summary),$str_contact_allow,$str_group_allow,$str_contact_deny,$str_group_deny);
fix_attached_file_permissions($channel,$observer['xchan_hash'],((strpos($body,'[/crypt]')) ? $_POST['media_str'] : $body),$str_contact_allow,$str_group_allow,$str_contact_deny,$str_group_deny);
}
$attachments = '';
$match = false;
@@ -922,10 +917,9 @@ class Item extends Controller {
}
}
// BBCODE end alert
}
// BBCODE end alert
if(strlen($categories)) {
$cats = explode(',',$categories);

View File

@@ -1,37 +1,42 @@
<?php
namespace Zotlabs\Module;
use App;
use Zotlabs\Lib\Activity;
use Zotlabs\Lib\Libsync;
use Zotlabs\Web\Controller;
use Zotlabs\Daemon\Master;
require_once('include/security.php');
require_once('include/bbcode.php');
require_once('include/items.php');
require_once('include/conversation.php');
class Like extends \Zotlabs\Web\Controller {
class Like extends Controller {
private function reaction_to_activity($reaction) {
$acts = [
'like' => ACTIVITY_LIKE ,
'dislike' => ACTIVITY_DISLIKE ,
'agree' => ACTIVITY_AGREE ,
'disagree' => ACTIVITY_DISAGREE ,
'abstain' => ACTIVITY_ABSTAIN ,
'attendyes' => ACTIVITY_ATTEND ,
'attendno' => ACTIVITY_ATTENDNO ,
'like' => ACTIVITY_LIKE,
'dislike' => ACTIVITY_DISLIKE,
'agree' => ACTIVITY_AGREE,
'disagree' => ACTIVITY_DISAGREE,
'abstain' => ACTIVITY_ABSTAIN,
'attendyes' => ACTIVITY_ATTEND,
'attendno' => ACTIVITY_ATTENDNO,
'attendmaybe' => ACTIVITY_ATTENDMAYBE
];
// unlike (etc.) reactions are an undo of positive reactions, rather than a negative action.
// The activity is the same in undo actions and will have the same activity mapping
if(substr($reaction,0,2) === 'un') {
$reaction = substr($reaction,2);
if (substr($reaction, 0, 2) === 'un') {
$reaction = substr($reaction, 2);
}
if(array_key_exists($reaction,$acts)) {
if (array_key_exists($reaction, $acts)) {
return $acts[$reaction];
}
@@ -41,60 +46,69 @@ class Like extends \Zotlabs\Web\Controller {
private function like_response($arr) {
if($arr['conv_mode'] === 'channel') {
$page_mode = (($arr['item']['item_thread_top'] && $_REQUEST['page_mode']) ? $_REQUEST['page_mode'] : 'r_preview');
$conv_mode = (($_REQUEST['conv_mode']) ? $_REQUEST['conv_mode'] : 'network');
if ($conv_mode === 'channel') {
$parts = explode('@', $arr['owner_xchan']['xchan_addr']);
profile_load($parts[0]);
}
$item_normal = item_normal();
$activities = q("SELECT item.*, item.id AS item_id FROM item
WHERE uid = %d $item_normal
AND thr_parent = '%s'
AND verb IN ('%s', '%s', '%s', '%s', '%s')",
intval($arr['item']['uid']),
dbesc($arr['item']['mid']),
dbesc(ACTIVITY_LIKE),
dbesc(ACTIVITY_DISLIKE),
dbesc(ACTIVITY_ATTEND),
dbesc(ACTIVITY_ATTENDNO),
dbesc(ACTIVITY_ATTENDMAYBE)
);
xchan_query($activities,true);
$convitems[] = $arr['item'];
$convitems = array_merge($convitems, $activities);
$convitems = fetch_post_tags($convitems,true);
if ($page_mode === 'list') {
$items = q("SELECT item.*, item.id AS item_id FROM item
WHERE uid = %d $item_normal
AND parent = %d",
intval($arr['item']['uid']),
intval($arr['item']['parent'])
);
xchan_query($items, true);
$items = fetch_post_tags($items, true);
$items = conv_sort($items, 'commented');
}
else {
$activities = q("SELECT item.*, item.id AS item_id FROM item
WHERE uid = %d $item_normal
AND thr_parent = '%s'
AND verb IN ('%s', '%s', '%s', '%s', '%s')",
intval($arr['item']['uid']),
dbesc($arr['item']['mid']),
dbesc(ACTIVITY_LIKE),
dbesc(ACTIVITY_DISLIKE),
dbesc(ACTIVITY_ATTEND),
dbesc(ACTIVITY_ATTENDNO),
dbesc(ACTIVITY_ATTENDMAYBE)
);
xchan_query($activities, true);
$items = array_merge([$arr['item']], $activities);
$items = fetch_post_tags($items, true);
}
$ret = [
'success' => 1,
'orig_id' => $arr['orig_item_id'], //this is required for pubstream items where $item_id != $item['id']
'id' => $arr['item']['id'],
'html' => conversation($convitems, $arr['conv_mode'], true, 'r_preview'),
'id' => $arr['item']['id'],
'html' => conversation($items, $conv_mode, true, $page_mode),
];
return $ret;
}
public function get() {
$o = EMPTY_STR;
$o = EMPTY_STR;
$sys_channel = get_sys_channel();
$sys_channel_id = (($sys_channel) ? $sys_channel['channel_id'] : 0);
$observer = \App::get_observer();
$observer = App::get_observer();
$interactive = $_REQUEST['interactive'];
if((! $observer) || ($interactive)) {
if ((!$observer) || ($interactive)) {
$o .= '<h1>' . t('Like/Dislike') . '</h1>';
$o .= EOL . EOL;
if(! $observer) {
$_SESSION['return_url'] = \App::$query_string;
if (!$observer) {
$_SESSION['return_url'] = App::$query_string;
$o .= t('This action is restricted to members.') . EOL;
$o .= t('Please <a href="rmagic">login with your $Projectname ID</a> or <a href="register">register as a new $Projectname member</a> to continue.') . EOL;
return $o;
@@ -102,56 +116,54 @@ class Like extends \Zotlabs\Web\Controller {
}
$verb = notags(trim($_GET['verb']));
$mode = (($_GET['conv_mode'] === 'channel') ? 'channel' : 'network');
if(! $verb)
if (!$verb)
$verb = 'like';
$activity = $this->reaction_to_activity($verb);
if(! $activity) {
if (!$activity) {
return EMPTY_STR;
}
$is_rsvp = false;
if (in_array($activity, [ ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE ])) {
if (in_array($activity, [ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE])) {
$is_rsvp = true;
}
$extended_like = false;
$object = $target = null;
$post_type = EMPTY_STR;
$objtype = EMPTY_STR;
$object = $target = null;
$post_type = EMPTY_STR;
$objtype = EMPTY_STR;
if(argc() == 3) {
if (argc() == 3) {
if(! $observer)
if (!$observer)
killme();
$extended_like = true;
$obj_type = argv(1);
$obj_id = argv(2);
$public = true;
$obj_type = argv(1);
$obj_id = argv(2);
$public = true;
if($obj_type == 'profile') {
if ($obj_type == 'profile') {
$r = q("select * from profile where profile_guid = '%s' limit 1",
dbesc(argv(2))
);
if(! $r)
if (!$r)
killme();
$owner_uid = $r[0]['uid'];
if($r[0]['is_default'])
if ($r[0]['is_default'])
$public = true;
if(! $public) {
if (!$public) {
$d = q("select abook_xchan from abook where abook_profile = '%s' and abook_channel = %d",
dbesc($r[0]['profile_guid']),
intval($owner_uid)
);
if(! $d) {
if (!$d) {
// forgery - illegal
if($interactive) {
notice( t('Invalid request.') . EOL);
if ($interactive) {
notice(t('Invalid request.') . EOL);
return $o;
}
killme();
@@ -159,25 +171,25 @@ class Like extends \Zotlabs\Web\Controller {
// $d now contains a list of those who can see this profile - only send the status notification
// to them.
$allow_cid = $allow_gid = $deny_cid = $deny_gid = '';
foreach($d as $dd) {
foreach ($d as $dd) {
$allow_cid .= '<' . $dd['abook_xchan'] . '>';
}
}
$post_type = t('channel');
$objtype = ACTIVITY_OBJ_PROFILE;
$objtype = ACTIVITY_OBJ_PROFILE;
$profile = $r[0];
}
elseif($obj_type == 'thing') {
elseif ($obj_type == 'thing') {
$r = q("select * from obj where obj_type = %d and obj_obj = '%s' limit 1",
intval(TERM_OBJ_THING),
dbesc(argv(2))
);
intval(TERM_OBJ_THING),
dbesc(argv(2))
);
if(! $r) {
if($interactive) {
notice( t('Invalid request.') . EOL);
if (!$r) {
if ($interactive) {
notice(t('Invalid request.') . EOL);
return $o;
}
killme();
@@ -187,19 +199,19 @@ class Like extends \Zotlabs\Web\Controller {
$allow_cid = $r[0]['allow_cid'];
$allow_gid = $r[0]['allow_gid'];
$deny_cid = $r[0]['deny_cid'];
$deny_gid = $r[0]['deny_gid'];
if($allow_cid || $allow_gid || $deny_cid || $deny_gid)
$deny_cid = $r[0]['deny_cid'];
$deny_gid = $r[0]['deny_gid'];
if ($allow_cid || $allow_gid || $deny_cid || $deny_gid)
$public = false;
$post_type = t('thing');
$objtype = ACTIVITY_OBJ_PROFILE;
$tgttype = ACTIVITY_OBJ_THING;
$objtype = ACTIVITY_OBJ_PROFILE;
$tgttype = ACTIVITY_OBJ_THING;
$links = array();
$links[] = array('rel' => 'alternate', 'type' => 'text/html',
'href' => z_root() . '/thing/' . $r[0]['obj_obj']);
if($r[0]['imgurl'])
$links[] = array('rel' => 'alternate', 'type' => 'text/html',
'href' => z_root() . '/thing/' . $r[0]['obj_obj']);
if ($r[0]['imgurl'])
$links[] = array('rel' => 'photo', 'href' => $r[0]['obj_imgurl']);
$target = json_encode(array(
@@ -213,9 +225,9 @@ class Like extends \Zotlabs\Web\Controller {
}
if(! ($owner_uid && $r)) {
if($interactive) {
notice( t('Invalid request.') . EOL);
if (!($owner_uid && $r)) {
if ($interactive) {
notice(t('Invalid request.') . EOL);
return $o;
}
killme();
@@ -223,11 +235,11 @@ class Like extends \Zotlabs\Web\Controller {
// The resultant activity is going to be a wall-to-wall post, so make sure this is allowed
$perms = get_all_perms($owner_uid,$observer['xchan_hash']);
$perms = get_all_perms($owner_uid, $observer['xchan_hash']);
if(! ($perms['post_like'] && $perms['view_profile'])) {
if($interactive) {
notice( t('Permission denied.') . EOL);
if (!($perms['post_like'] && $perms['view_profile'])) {
if ($interactive) {
notice(t('Permission denied.') . EOL);
return $o;
}
killme();
@@ -236,18 +248,18 @@ class Like extends \Zotlabs\Web\Controller {
$ch = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1",
intval($owner_uid)
);
if(! $ch) {
if($interactive) {
notice( t('Channel unavailable.') . EOL);
if (!$ch) {
if ($interactive) {
notice(t('Channel unavailable.') . EOL);
return $o;
}
killme();
}
if(! $plink)
if (!$plink)
$plink = '[zrl=' . z_root() . '/profile/' . $ch[0]['channel_address'] . ']' . $post_type . '[/zrl]';
$object = json_encode(Activity::fetch_profile([ 'id' => channel_url($ch[0]) ]));
$object = json_encode(Activity::fetch_profile(['id' => channel_url($ch[0])]));
// second like of the same thing is "undo" for the first like
@@ -255,26 +267,26 @@ class Like extends \Zotlabs\Web\Controller {
intval($ch[0]['channel_id']),
dbesc($observer['xchan_hash']),
dbesc($activity),
dbesc(($tgttype)?$tgttype:$objtype),
dbesc(($tgttype) ? $tgttype : $objtype),
dbesc($obj_id)
);
if($z) {
if ($z) {
$z[0]['deleted'] = 1;
Libsync::build_sync_packet($ch[0]['channel_id'],array('likes' => $z));
Libsync::build_sync_packet($ch[0]['channel_id'], array('likes' => $z));
q("delete from likes where id = %d",
intval($z[0]['id'])
);
if($z[0]['i_mid']) {
if ($z[0]['i_mid']) {
$r = q("select id from item where mid = '%s' and uid = %d limit 1",
dbesc($z[0]['i_mid']),
intval($ch[0]['channel_id'])
);
if($r)
drop_item($r[0]['id'],false);
if($interactive) {
notice( t('Previous action reversed.') . EOL);
if ($r)
drop_item($r[0]['id'], false);
if ($interactive) {
notice(t('Previous action reversed.') . EOL);
return $o;
}
}
@@ -283,7 +295,7 @@ class Like extends \Zotlabs\Web\Controller {
}
else {
if(! $observer)
if (!$observer)
killme();
// this is used to like an item or comment
@@ -304,32 +316,30 @@ class Like extends \Zotlabs\Web\Controller {
// create a copy of the parent in your stream. If not the conversation
// parent, copy that as well.
if($r) {
if($r[0]['uid'] === $sys_channel['channel_id'] && local_channel()) {
$r = [ copy_of_pubitem(\App::get_channel(), $r[0]['mid']) ];
if ($r) {
if ($r[0]['uid'] === $sys_channel['channel_id'] && local_channel()) {
$r = [copy_of_pubitem(App::get_channel(), $r[0]['mid'])];
}
}
if(! $item_id || (! $r)) {
if (!$item_id || (!$r)) {
logger('like: no item ' . $item_id);
killme();
}
xchan_query($r,true);
$item = $r[0];
xchan_query($r, true);
$item = $r[0];
$owner_uid = $r[0]['uid'];
$owner_aid = $r[0]['aid'];
$can_comment = false;
if((array_key_exists('owner',$item)) && intval($item['owner']['abook_self']))
$can_comment = perm_is_allowed($item['uid'],$observer['xchan_hash'],'post_comments');
else
$can_comment = can_comment_on_post($observer['xchan_hash'],$item);
if ((array_key_exists('owner', $item)) && intval($item['owner']['abook_self']))
$can_comment = perm_is_allowed($item['uid'], $observer['xchan_hash'], 'post_comments');
else
$can_comment = can_comment_on_post($observer['xchan_hash'], $item);
if(! $can_comment) {
notice( t('Permission denied') . EOL);
if (!$can_comment) {
notice(t('Permission denied') . EOL);
killme();
}
@@ -337,7 +347,7 @@ class Like extends \Zotlabs\Web\Controller {
dbesc($item['owner_xchan'])
);
if($r)
if ($r)
$thread_owner = $r[0];
else
killme();
@@ -345,24 +355,24 @@ class Like extends \Zotlabs\Web\Controller {
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
dbesc($item['author_xchan'])
);
if($r)
if ($r)
$item_author = $r[0];
else
killme();
$verbs = " '".dbesc($activity)."' ";
$verbs = " '" . dbesc($activity) . "' ";
$multi_undo = false;
// event participation and consensus items are essentially radio toggles. If you make a subsequent choice,
// we need to eradicate your first choice.
if($activity === ACTIVITY_ATTEND || $activity === ACTIVITY_ATTENDNO || $activity === ACTIVITY_ATTENDMAYBE) {
$verbs = " '" . dbesc(ACTIVITY_ATTEND) . "','" . dbesc(ACTIVITY_ATTENDNO) . "','" . dbesc(ACTIVITY_ATTENDMAYBE) . "' ";
if ($activity === ACTIVITY_ATTEND || $activity === ACTIVITY_ATTENDNO || $activity === ACTIVITY_ATTENDMAYBE) {
$verbs = " '" . dbesc(ACTIVITY_ATTEND) . "','" . dbesc(ACTIVITY_ATTENDNO) . "','" . dbesc(ACTIVITY_ATTENDMAYBE) . "' ";
$multi_undo = 1;
}
if($activity === ACTIVITY_AGREE || $activity === ACTIVITY_DISAGREE || $activity === ACTIVITY_ABSTAIN) {
$verbs = " '" . dbesc(ACTIVITY_AGREE) . "','" . dbesc(ACTIVITY_DISAGREE) . "','" . dbesc(ACTIVITY_ABSTAIN) . "' ";
if ($activity === ACTIVITY_AGREE || $activity === ACTIVITY_DISAGREE || $activity === ACTIVITY_ABSTAIN) {
$verbs = " '" . dbesc(ACTIVITY_AGREE) . "','" . dbesc(ACTIVITY_DISAGREE) . "','" . dbesc(ACTIVITY_ABSTAIN) . "' ";
$multi_undo = true;
}
@@ -375,45 +385,41 @@ class Like extends \Zotlabs\Web\Controller {
intval($owner_uid)
);
if($r) {
if ($r) {
// already liked it. Drop that item.
require_once('include/items.php');
foreach($r as $rr) {
drop_item($rr['id'],false,DROPITEM_PHASE1);
foreach ($r as $rr) {
drop_item($rr['id'], false, DROPITEM_PHASE1);
// set the changed timestamp on the parent so we'll see the update without a page reload
$z = q("update item set changed = '%s' where id = %d and uid = %d",
q("update item set changed = '%s' where id = %d and uid = %d",
dbesc(datetime_convert()),
intval($rr['parent']),
intval($rr['uid'])
);
// Prior activity was a duplicate of the one we're submitting, just undo it;
// don't fall through and create another
if(activity_match($rr['verb'],$activity))
if (activity_match($rr['verb'], $activity))
$multi_undo = false;
// drop_item was not done interactively, so we need to invoke the notifier
// in order to push the changes to connections
\Zotlabs\Daemon\Master::Summon(array('Notifier','drop',$rr['id']));
Master::Summon(array('Notifier', 'drop', $rr['id']));
}
if($interactive)
if ($interactive)
return;
if(! $multi_undo) {
if (!$multi_undo) {
$ret = self::like_response([
'item' => $item,
'item' => $item,
'orig_item_id' => $item_id,
'owner_xchan' => $thread_owner,
'conv_mode' => $mode
'owner_xchan' => $thread_owner
]);
json_return_and_die($ret);
}
}
}
@@ -421,43 +427,39 @@ class Like extends \Zotlabs\Web\Controller {
$arr = array();
$arr['uuid'] = $uuid;
$arr['mid'] = z_root() . (($is_rsvp) ? '/activity/' : '/item/') . $uuid;
$arr['uuid'] = $uuid;
$arr['mid'] = z_root() . (($is_rsvp) ? '/activity/' : '/item/') . $uuid;
if($extended_like) {
if ($extended_like) {
$arr['item_thread_top'] = 1;
$arr['item_origin'] = 1;
$arr['item_wall'] = 1;
$arr['item_origin'] = 1;
$arr['item_wall'] = 1;
}
else {
$post_type = (($item['resource_type'] === 'photo') ? t('photo') : t('status'));
if($item['obj_type'] === ACTIVITY_OBJ_EVENT)
if ($item['obj_type'] === ACTIVITY_OBJ_EVENT)
$post_type = t('event');
$links = array(array('rel' => 'alternate','type' => 'text/html', 'href' => $item['plink']));
$objtype = (($item['resource_type'] === 'photo') ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE );
$objtype = (($item['resource_type'] === 'photo') ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE);
if($objtype === ACTIVITY_OBJ_NOTE && (! intval($item['item_thread_top'])))
if ($objtype === ACTIVITY_OBJ_NOTE && (!intval($item['item_thread_top'])))
$objtype = ACTIVITY_OBJ_COMMENT;
$object = json_encode(Activity::fetch_item(['id' => $item['mid']]));
$body = $item['body'];
$object = json_encode(Activity::fetch_item( [ 'id' => $item['mid'] ]));
if(! intval($item['item_thread_top']))
if (!intval($item['item_thread_top']))
$post_type = 'comment';
$arr['item_origin'] = 1;
$arr['item_origin'] = 1;
$arr['item_notshown'] = 1;
$arr['item_type'] = $item['item_type'];
$arr['item_type'] = $item['item_type'];
if(intval($item['item_wall']))
if (intval($item['item_wall']))
$arr['item_wall'] = 1;
// if this was a linked photo and was hidden, unhide it.
if(intval($item['item_hidden'])) {
if (intval($item['item_hidden'])) {
$r = q("update item set item_hidden = 0 where id = %d",
intval($item['id'])
);
@@ -465,103 +467,95 @@ class Like extends \Zotlabs\Web\Controller {
}
if($verb === 'like')
if ($verb === 'like')
$bodyverb = t('%1$s likes %2$s\'s %3$s');
if($verb === 'dislike')
if ($verb === 'dislike')
$bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s');
if($verb === 'agree')
if ($verb === 'agree')
$bodyverb = t('%1$s agrees with %2$s\'s %3$s');
if($verb === 'disagree')
if ($verb === 'disagree')
$bodyverb = t('%1$s doesn\'t agree with %2$s\'s %3$s');
if($verb === 'abstain')
if ($verb === 'abstain')
$bodyverb = t('%1$s abstains from a decision on %2$s\'s %3$s');
if($verb === 'attendyes')
if ($verb === 'attendyes')
$bodyverb = t('%1$s is attending %2$s\'s %3$s');
if($verb === 'attendno')
if ($verb === 'attendno')
$bodyverb = t('%1$s is not attending %2$s\'s %3$s');
if($verb === 'attendmaybe')
if ($verb === 'attendmaybe')
$bodyverb = t('%1$s may attend %2$s\'s %3$s');
if(! isset($bodyverb))
killme();
if (!isset($bodyverb))
killme();
if($extended_like) {
$ulink = '[zrl=' . $ch[0]['xchan_url'] . '][bdi]' . $ch[0]['xchan_name'] . '[/bdi][/zrl]';
$alink = '[zrl=' . $observer['xchan_url'] . '][bdi]' . $observer['xchan_name'] . '[/bdi][/zrl]';
if ($extended_like) {
$ulink = '[zrl=' . $ch[0]['xchan_url'] . '][bdi]' . $ch[0]['xchan_name'] . '[/bdi][/zrl]';
$alink = '[zrl=' . $observer['xchan_url'] . '][bdi]' . $observer['xchan_name'] . '[/bdi][/zrl]';
$private = (($public) ? 0 : 1);
}
else {
$arr['parent'] = $item['id'];
$arr['thr_parent'] = $item['mid'];
$ulink = '[zrl=' . $item_author['xchan_url'] . '][bdi]' . $item_author['xchan_name'] . '[/bdi][/zrl]';
$alink = '[zrl=' . $observer['xchan_url'] . '][bdi]' . $observer['xchan_name'] . '[/bdi][/zrl]';
$plink = '[zrl=' . z_root() . '/display/' . gen_link_id($item['mid']) . ']' . $post_type . '[/zrl]';
$allow_cid = $item['allow_cid'];
$allow_gid = $item['allow_gid'];
$deny_cid = $item['deny_cid'];
$deny_gid = $item['deny_gid'];
$private = $item['private'];
$arr['parent'] = $item['id'];
$arr['thr_parent'] = $item['mid'];
$ulink = '[zrl=' . $item_author['xchan_url'] . '][bdi]' . $item_author['xchan_name'] . '[/bdi][/zrl]';
$alink = '[zrl=' . $observer['xchan_url'] . '][bdi]' . $observer['xchan_name'] . '[/bdi][/zrl]';
$plink = '[zrl=' . z_root() . '/display/' . gen_link_id($item['mid']) . ']' . $post_type . '[/zrl]';
$allow_cid = $item['allow_cid'];
$allow_gid = $item['allow_gid'];
$deny_cid = $item['deny_cid'];
$deny_gid = $item['deny_gid'];
$private = $item['private'];
}
$arr['aid'] = (($extended_like) ? $ch[0]['channel_account_id'] : $owner_aid);
$arr['uid'] = $owner_uid;
$arr['item_flags'] = $item['item_flags'];
$arr['item_wall'] = $item['item_wall'];
$arr['parent_mid'] = (($extended_like) ? $arr['mid'] : $item['mid']);
$arr['owner_xchan'] = (($extended_like) ? $ch[0]['xchan_hash'] : $thread_owner['xchan_hash']);
$arr['author_xchan'] = $observer['xchan_hash'];
$arr['body'] = sprintf($bodyverb, $alink, $ulink, $plink);
$arr['body'] = sprintf( $bodyverb, $alink, $ulink, $plink );
if($obj_type === 'thing' && $r[0]['imgurl']) {
if ($obj_type === 'thing' && $r[0]['imgurl']) {
$arr['body'] .= "\n\n[zmg=80x80]" . $r[0]['imgurl'] . '[/zmg]';
}
if($obj_type === 'profile') {
if($public) {
if ($obj_type === 'profile') {
if ($public) {
$arr['body'] .= "\n\n" . '[embed]' . z_root() . '/profile/' . $ch[0]['channel_address'] . '[/embed]';
}
else
$arr['body'] .= "\n\n[zmg=80x80]" . $profile['thumb'] . '[/zmg]';
}
$arr['verb'] = $activity;
$arr['obj_type'] = $objtype;
$arr['obj'] = $object;
$arr['verb'] = $activity;
$arr['obj_type'] = $objtype;
$arr['obj'] = $object;
if($target) {
$arr['tgt_type'] = $tgttype;
$arr['target'] = $target;
if ($target) {
$arr['tgt_type'] = $tgttype;
$arr['target'] = $target;
}
$arr['allow_cid'] = $allow_cid;
$arr['allow_gid'] = $allow_gid;
$arr['deny_cid'] = $deny_cid;
$arr['deny_gid'] = $deny_gid;
$arr['item_private'] = $private;
$arr['allow_cid'] = $allow_cid;
$arr['allow_gid'] = $allow_gid;
$arr['deny_cid'] = $deny_cid;
$arr['deny_gid'] = $deny_gid;
$arr['item_private'] = $private;
call_hooks('post_local',$arr);
call_hooks('post_local', $arr);
$post = item_store($arr);
$post = item_store($arr);
$post_id = $post['item_id'];
// save the conversation from expiration
if(local_channel() && array_key_exists('item',$post) && (intval($post['item']['id']) != intval($post['item']['parent'])))
if (local_channel() && array_key_exists('item', $post) && (intval($post['item']['id']) != intval($post['item']['parent'])))
retain_item($post['item']['parent']);
$arr['id'] = $post_id;
call_hooks('post_local_end', $arr);
if($extended_like) {
if ($extended_like) {
$r = q("insert into likes (channel_id,liker,likee,iid,i_mid,verb,target_type,target_id,target) values (%d,'%s','%s',%d,'%s','%s','%s','%s','%s')",
intval($ch[0]['channel_id']),
dbesc($observer['xchan_hash']),
@@ -569,36 +563,35 @@ class Like extends \Zotlabs\Web\Controller {
intval($post_id),
dbesc($arr['mid']),
dbesc($activity),
dbesc(($tgttype)? $tgttype : $objtype),
dbesc(($tgttype) ? $tgttype : $objtype),
dbesc($obj_id),
dbesc(($target) ? $target : $object)
dbesc(($target) ? $target : $object)
);
$r = q("select * from likes where liker = '%s' and likee = '%s' and i_mid = '%s' and verb = '%s' and target_type = '%s' and target_id = '%s' ",
dbesc($observer['xchan_hash']),
dbesc($ch[0]['channel_hash']),
dbesc($arr['mid']),
dbesc($activity),
dbesc(($tgttype)? $tgttype : $objtype),
dbesc(($tgttype) ? $tgttype : $objtype),
dbesc($obj_id)
);
if($r)
Libsync::build_sync_packet($ch[0]['channel_id'],array('likes' => $r));
if ($r)
Libsync::build_sync_packet($ch[0]['channel_id'], array('likes' => $r));
}
\Zotlabs\Daemon\Master::Summon(array('Notifier','like',$post_id));
Master::Summon(array('Notifier', 'like', $post_id));
if($interactive) {
notice( t('Action completed.') . EOL);
if ($interactive) {
notice(t('Action completed.') . EOL);
$o .= t('Thank you.');
return $o;
}
$ret = self::like_response([
'item' => $item,
'item' => $item,
'orig_item_id' => $item_id,
'owner_xchan' => $thread_owner,
'conv_mode' => $mode
'owner_xchan' => $thread_owner
]);
json_return_and_die($ret);

View File

@@ -20,44 +20,44 @@ class Network extends \Zotlabs\Web\Controller {
return;
}
if(in_array(substr($_GET['search'],0,1),[ '@', '!', '?']))
if(in_array(substr($_GET['search'],0,1),[ '@', '!', '?']) || strpos($_GET['search'], 'https://') === 0)
goaway('search' . '?f=&search=' . $_GET['search']);
if(count($_GET) < 2) {
$network_options = get_pconfig(local_channel(),'system','network_page_default');
if($network_options)
goaway('network' . '?f=&' . $network_options);
}
$channel = App::get_channel();
App::$profile_uid = local_channel();
head_set_icon($channel['xchan_photo_s']);
}
function get($update = 0, $load = false) {
if(! local_channel()) {
$_SESSION['return_url'] = App::$query_string;
return login(false);
}
$o = '';
$arr = array('query' => App::$query_string);
call_hooks('network_content_init', $arr);
$channel = App::get_channel();
$item_normal = item_normal();
$item_normal_update = item_normal_update();
$datequery = $datequery2 = '';
$group = 0;
$nouveau = false;
$datequery = ((x($_GET,'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : '');
$datequery2 = ((x($_GET,'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : '');
$gid = ((x($_GET,'gid')) ? intval($_GET['gid']) : 0);
@@ -87,13 +87,13 @@ class Network extends \Zotlabs\Web\Controller {
$search = '';
}
}
if($datequery)
$order = 'post';
// filter by collection (e.g. group)
if($gid) {
$r = q("SELECT * FROM pgrp WHERE id = %d AND uid = %d LIMIT 1",
intval($gid),
@@ -106,12 +106,12 @@ class Network extends \Zotlabs\Web\Controller {
goaway(z_root() . '/network');
// NOTREACHED
}
$group = $gid;
$group_hash = $r[0]['hash'];
$def_acl = array('allow_gid' => '<' . $r[0]['hash'] . '>');
}
$default_cmin = ((Apps::system_app_installed(local_channel(),'Affinity Tool')) ? get_pconfig(local_channel(),'affinity','cmin',0) : (-1));
$default_cmax = ((Apps::system_app_installed(local_channel(),'Affinity Tool')) ? get_pconfig(local_channel(),'affinity','cmax',99) : (-1));
@@ -127,7 +127,7 @@ class Network extends \Zotlabs\Web\Controller {
$net = ((x($_GET,'net')) ? $_GET['net'] : '');
$pf = ((x($_GET,'pf')) ? $_GET['pf'] : '');
$unseen = ((x($_GET,'unseen')) ? $_GET['unseen'] : '');
if (Apps::system_app_installed(local_channel(),'Affinity Tool')) {
$affinity_locked = intval(get_pconfig(local_channel(),'affinity','lock',1));
if ($affinity_locked) {
@@ -155,16 +155,16 @@ class Network extends \Zotlabs\Web\Controller {
}
$def_acl = [ 'allow_cid' => '<' . $cid_r[0]['abook_xchan'] . '>', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '' ];
}
if(! $update) {
// search terms header
if($search || $hashtags) {
$o .= replace_macros(get_markup_template("section_title.tpl"),array(
'$title' => t('Search Results For:') . ' ' . (($search) ? htmlspecialchars($search, ENT_COMPAT,'UTF-8') : '#' . htmlspecialchars($hashtags, ENT_COMPAT,'UTF-8'))
));
}
nav_set_selected('Network');
$bang = '!';
@@ -179,14 +179,14 @@ class Network extends \Zotlabs\Web\Controller {
}
$channel_acl = array(
'allow_cid' => $channel['channel_allow_cid'],
'allow_gid' => $channel['channel_allow_gid'],
'deny_cid' => $channel['channel_deny_cid'],
'allow_cid' => $channel['channel_allow_cid'],
'allow_gid' => $channel['channel_allow_gid'],
'deny_cid' => $channel['channel_deny_cid'],
'deny_gid' => $channel['channel_deny_gid']
);
$private_editing = (($group || $cid) ? true : false);
$x = array(
'is_owner' => true,
'allow_location' => ((intval(get_pconfig($channel['channel_id'],'system','use_browser_location'))) ? '1' : ''),
@@ -204,28 +204,28 @@ class Network extends \Zotlabs\Web\Controller {
'jotnets' => true,
'reset' => t('Reset form')
);
$status_editor = status_editor($a,$x,false,'Network');
$o .= $status_editor;
}
// We don't have to deal with ACL's on this page. You're looking at everything
// that belongs to you, hence you can see all of it. We will filter by group if
// desired.
$sql_options = (($star)
? " and item_starred = 1 "
: '');
$sql_nets = '';
$item_thread_top = ' AND item_thread_top = 1 ';
$sql_extra = '';
if($group) {
$contact_str = '';
@@ -241,18 +241,18 @@ class Network extends \Zotlabs\Web\Controller {
}
$item_thread_top = '';
$sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND (( author_xchan IN ( $contact_str ) OR owner_xchan in ( $contact_str )) or allow_gid like '" . protect_sprintf('%<' . dbesc($group_hash) . '>%') . "' ) and id = parent $item_normal ) ";
$x = group_rec_byhash(local_channel(), $group_hash);
if($x) {
$title = replace_macros(get_markup_template("section_title.tpl"),array(
'$title' => t('Privacy group: ') . $x['gname']
));
}
$o = $title;
$o .= $status_editor;
}
elseif($cid_r) {
$item_thread_top = '';
@@ -324,14 +324,217 @@ class Network extends \Zotlabs\Web\Controller {
}
}
if(x($category)) {
$sql_extra .= protect_sprintf(term_query('item', $category, TERM_CATEGORY));
}
if(x($hashtags)) {
$sql_extra .= protect_sprintf(term_query('item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG));
}
$sql_extra3 = '';
if($datequery) {
$sql_extra3 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery))));
}
if($datequery2) {
$sql_extra3 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2))));
}
$sql_extra2 = (($nouveau) ? '' : " AND item.parent = item.id ");
$sql_extra3 = (($nouveau) ? '' : $sql_extra3);
if(x($_GET,'search')) {
$search = escape_tags($_GET['search']);
if(strpos($search,'#') === 0) {
$sql_extra .= term_query('item',substr($search,1),TERM_HASHTAG,TERM_COMMUNITYTAG);
}
else {
$sql_extra .= sprintf(" AND (item.body like '%s' OR item.title like '%s') ",
dbesc(protect_sprintf('%' . $search . '%')),
dbesc(protect_sprintf('%' . $search . '%'))
);
}
}
if ($verb) {
// the presence of a leading dot in the verb determines
// whether to match the type of activity or the child object.
// The name 'verb' is a holdover from the earlier XML
// ActivityStreams specification.
if (substr($verb,0,1) === '.') {
$verb = substr($verb,1);
$sql_extra .= sprintf(" AND item.obj_type like '%s' ",
dbesc(protect_sprintf('%' . $verb . '%'))
);
}
else {
$sql_extra .= sprintf(" AND item.verb like '%s' ",
dbesc(protect_sprintf('%' . $verb . '%'))
);
}
}
if(strlen($file)) {
$sql_extra .= term_query('item',$file,TERM_FILE);
}
if ($dm) {
$sql_extra .= " AND item_private = 2 ";
}
if($conv) {
$item_thread_top = '';
$sql_extra .= " AND ( author_xchan = '" . dbesc($channel['channel_hash']) . "' OR item_mentionsme = 1 ) ";
}
if($update && ! $load) {
// only setup pagination on initial page view
$pager_sql = '';
}
else {
$itemspage = get_pconfig(local_channel(),'system','itemspage');
App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10));
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start']));
}
// cmin and cmax are both -1 when the affinity tool is disabled
if(($cmin != (-1)) || ($cmax != (-1))) {
// Not everybody who shows up in the network stream will be in your address book.
// By default those that aren't are assumed to have closeness = 99; but this isn't
// recorded anywhere. So if cmax is 99, we'll open the search up to anybody in
// the stream with a NULL address book entry.
$sql_nets .= " AND ";
if($cmax == 99)
$sql_nets .= " ( ";
$sql_nets .= "( abook.abook_closeness >= " . intval($cmin) . " ";
$sql_nets .= " AND abook.abook_closeness <= " . intval($cmax) . " ) ";
if($cmax == 99)
$sql_nets .= " OR abook.abook_closeness IS NULL ) ";
}
$net_query = (($net) ? " left join xchan on xchan_hash = author_xchan " : '');
$net_query2 = (($net) ? " and xchan_network = '" . protect_sprintf(dbesc($net)) . "' " : '');
$abook_uids = " and abook.abook_channel = " . local_channel() . " ";
$uids = " and item.uid = " . local_channel() . " ";
if(feature_enabled(local_channel(), 'network_list_mode'))
$page_mode = 'list';
else
$page_mode = 'client';
$parents_str = '';
// This fixes a very subtle bug so I'd better explain it. You wake up in the morning or return after a day
// or three and look at your matrix page - after opening up your browser. The first page loads just as it
// should. All of a sudden a few seconds later, page 2 will get inserted at the beginning of the page
// (before the page 1 content). The update code is actually doing just what it's supposed
// to, it's fetching posts that have the ITEM_UNSEEN bit set. But the reason that page 2 content is being
// returned in an UPDATE is because you hadn't gotten that far yet - you're still on page 1 and everything
// that we loaded for page 1 is now marked as seen. But the stuff on page 2 hasn't been. So... it's being
// treated as "new fresh" content because it is unseen. We need to distinguish it somehow from content
// which "arrived as you were reading page 1". We're going to do this
// by storing in your session the current UTC time whenever you LOAD a network page, and only UPDATE items
// which are both ITEM_UNSEEN and have "changed" since that time. Cross fingers...
$simple_update = '';
if($update && $_SESSION['loadtime'])
$simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) ";
if($nouveau && $load) {
// "New Item View" - show all items unthreaded in reverse created date order
$items = q("SELECT item.*, item.id AS item_id, created FROM item
left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
$net_query
WHERE true $uids $item_normal
and (abook.abook_blocked = 0 or abook.abook_flags is null)
$sql_extra $sql_options $sql_nets
$net_query2
ORDER BY item.created DESC $pager_sql "
);
$parents_str = ids_to_querystr($items,'item_id');
require_once('include/items.php');
xchan_query($items);
$items = fetch_post_tags($items,true);
}
elseif($update) {
// Normal conversation view
if($order === 'post')
$ordering = "created";
else
$ordering = "commented";
if($load) {
// Fetch a page full of parent items for this page
$r = q("SELECT item.parent AS item_id FROM item
left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
$net_query
WHERE true $uids $item_thread_top $item_normal
AND item.mid = item.parent_mid
and (abook.abook_blocked = 0 or abook.abook_flags is null)
$sql_extra3 $sql_extra $sql_options $sql_nets
$net_query2
ORDER BY $ordering DESC $pager_sql "
);
}
else {
// this is an update
$r = q("SELECT item.parent AS item_id FROM item
left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
$net_query
WHERE true $uids $item_normal_update $simple_update
and (abook.abook_blocked = 0 or abook.abook_flags is null)
$sql_extra3 $sql_extra $sql_options $sql_nets $net_query2"
);
}
// Then fetch all the children of the parents that are on this page
if($r) {
$parents_str = ids_to_querystr($r,'item_id');
$items = q("SELECT item.*, item.id AS item_id FROM item
WHERE true $uids $item_normal
AND item.parent IN ( %s )
$sql_extra ",
dbesc($parents_str)
);
xchan_query($items,true);
$items = fetch_post_tags($items,true);
$items = conv_sort($items,$ordering);
}
else {
$items = array();
}
}
$mode = (($nouveau) ? 'network-new' : 'network');
if($search)
$mode = 'search';
if(! $update) {
// The special div is needed for liveUpdate to kick in for this page.
// We only launch liveUpdate if you aren't filtering in some incompatible
@@ -340,13 +543,13 @@ class Network extends \Zotlabs\Web\Controller {
$maxheight = get_pconfig(local_channel(),'system','network_divmore_height');
if(! $maxheight)
$maxheight = 400;
$o .= '<div id="live-network"></div>' . "\r\n";
$o .= "<script> var profile_uid = " . local_channel()
. "; var profile_page = " . App::$pager['page']
$o .= "<script> var profile_uid = " . local_channel()
. "; var profile_page = " . App::$pager['page']
. "; divmore_height = " . intval($maxheight) . "; </script>\r\n";
App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array(
'$baseurl' => z_root(),
'$pgtype' => 'network',
@@ -377,221 +580,19 @@ class Network extends \Zotlabs\Web\Controller {
'$net' => (($net) ? urlencode($net) : ''),
'$dbegin' => $datequery2,
'$pf' => (($pf) ? intval($pf) : 0),
'$unseen' => (($unseen) ? urlencode($unseen) : '')
'$unseen' => (($unseen) ? urlencode($unseen) : ''),
'$page_mode' => $page_mode
));
}
$sql_extra3 = '';
if($datequery) {
$sql_extra3 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery))));
}
if($datequery2) {
$sql_extra3 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2))));
}
$sql_extra2 = (($nouveau) ? '' : " AND item.parent = item.id ");
$sql_extra3 = (($nouveau) ? '' : $sql_extra3);
if(x($_GET,'search')) {
$search = escape_tags($_GET['search']);
if(strpos($search,'#') === 0) {
$sql_extra .= term_query('item',substr($search,1),TERM_HASHTAG,TERM_COMMUNITYTAG);
}
else {
$sql_extra .= sprintf(" AND (item.body like '%s' OR item.title like '%s') ",
dbesc(protect_sprintf('%' . $search . '%')),
dbesc(protect_sprintf('%' . $search . '%'))
);
}
}
if ($verb) {
// the presence of a leading dot in the verb determines
// whether to match the type of activity or the child object.
// The name 'verb' is a holdover from the earlier XML
// ActivityStreams specification.
if (substr($verb,0,1) === '.') {
$verb = substr($verb,1);
$sql_extra .= sprintf(" AND item.obj_type like '%s' ",
dbesc(protect_sprintf('%' . $verb . '%'))
);
}
else {
$sql_extra .= sprintf(" AND item.verb like '%s' ",
dbesc(protect_sprintf('%' . $verb . '%'))
);
}
}
if(strlen($file)) {
$sql_extra .= term_query('item',$file,TERM_FILE);
}
if ($dm) {
$sql_extra .= " AND item_private = 2 ";
}
if($conv) {
$item_thread_top = '';
$sql_extra .= " AND ( author_xchan = '" . dbesc($channel['channel_hash']) . "' OR item_mentionsme = 1 ) ";
}
if($update && ! $load) {
// only setup pagination on initial page view
$pager_sql = '';
}
else {
$itemspage = get_pconfig(local_channel(),'system','itemspage');
App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10));
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start']));
}
// cmin and cmax are both -1 when the affinity tool is disabled
if(($cmin != (-1)) || ($cmax != (-1))) {
// Not everybody who shows up in the network stream will be in your address book.
// By default those that aren't are assumed to have closeness = 99; but this isn't
// recorded anywhere. So if cmax is 99, we'll open the search up to anybody in
// the stream with a NULL address book entry.
$sql_nets .= " AND ";
if($cmax == 99)
$sql_nets .= " ( ";
$sql_nets .= "( abook.abook_closeness >= " . intval($cmin) . " ";
$sql_nets .= " AND abook.abook_closeness <= " . intval($cmax) . " ) ";
if($cmax == 99)
$sql_nets .= " OR abook.abook_closeness IS NULL ) ";
}
$net_query = (($net) ? " left join xchan on xchan_hash = author_xchan " : '');
$net_query2 = (($net) ? " and xchan_network = '" . protect_sprintf(dbesc($net)) . "' " : '');
$abook_uids = " and abook.abook_channel = " . local_channel() . " ";
$uids = " and item.uid = " . local_channel() . " ";
if(feature_enabled(local_channel(), 'network_list_mode'))
$page_mode = 'list';
else
$page_mode = 'client';
$parents_str = '';
// This fixes a very subtle bug so I'd better explain it. You wake up in the morning or return after a day
// or three and look at your matrix page - after opening up your browser. The first page loads just as it
// should. All of a sudden a few seconds later, page 2 will get inserted at the beginning of the page
// (before the page 1 content). The update code is actually doing just what it's supposed
// to, it's fetching posts that have the ITEM_UNSEEN bit set. But the reason that page 2 content is being
// returned in an UPDATE is because you hadn't gotten that far yet - you're still on page 1 and everything
// that we loaded for page 1 is now marked as seen. But the stuff on page 2 hasn't been. So... it's being
// treated as "new fresh" content because it is unseen. We need to distinguish it somehow from content
// which "arrived as you were reading page 1". We're going to do this
// by storing in your session the current UTC time whenever you LOAD a network page, and only UPDATE items
// which are both ITEM_UNSEEN and have "changed" since that time. Cross fingers...
$simple_update = '';
if($update && $_SESSION['loadtime'])
$simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) ";
if($nouveau && $load) {
// "New Item View" - show all items unthreaded in reverse created date order
$items = q("SELECT item.*, item.id AS item_id, created FROM item
left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
$net_query
WHERE true $uids $item_normal
and (abook.abook_blocked = 0 or abook.abook_flags is null)
$sql_extra $sql_options $sql_nets
$net_query2
ORDER BY item.created DESC $pager_sql "
);
$parents_str = ids_to_querystr($items,'item_id');
require_once('include/items.php');
xchan_query($items);
$items = fetch_post_tags($items,true);
}
elseif($update) {
// Normal conversation view
if($order === 'post')
$ordering = "created";
else
$ordering = "commented";
if($load) {
// Fetch a page full of parent items for this page
$r = q("SELECT item.parent AS item_id FROM item
left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
$net_query
WHERE true $uids $item_thread_top $item_normal
AND item.mid = item.parent_mid
and (abook.abook_blocked = 0 or abook.abook_flags is null)
$sql_extra3 $sql_extra $sql_options $sql_nets
$net_query2
ORDER BY $ordering DESC $pager_sql "
);
}
else {
// this is an update
$r = q("SELECT item.parent AS item_id FROM item
left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
$net_query
WHERE true $uids $item_normal_update $simple_update
and (abook.abook_blocked = 0 or abook.abook_flags is null)
$sql_extra3 $sql_extra $sql_options $sql_nets $net_query2"
);
}
// Then fetch all the children of the parents that are on this page
if($r) {
$parents_str = ids_to_querystr($r,'item_id');
$items = q("SELECT item.*, item.id AS item_id FROM item
WHERE true $uids $item_normal
AND item.parent IN ( %s )
$sql_extra ",
dbesc($parents_str)
);
xchan_query($items,true);
$items = fetch_post_tags($items,true);
$items = conv_sort($items,$ordering);
}
else {
$items = array();
}
}
$mode = (($nouveau) ? 'network-new' : 'network');
if($search)
$mode = 'search';
$o .= conversation($items,$mode,$update,$page_mode);
if(($items) && (! $update))
$o .= alt_pager(count($items));
$_SESSION['loadtime'] = datetime_convert();
return $o;
}
}

View File

@@ -19,7 +19,7 @@ class Notifications extends \Zotlabs\Web\Controller {
$r = q("select count(*) as total from notify where uid = %d and seen = 0",
intval(local_channel())
);
if($r && intval($t[0]['total']) > 49) {
if($r && intval($r[0]['total']) > 49) {
$r = q("select * from notify where uid = %d
and seen = 0 order by created desc limit 50",
intval(local_channel())
@@ -32,7 +32,7 @@ class Notifications extends \Zotlabs\Web\Controller {
$r2 = q("select * from notify where uid = %d
and seen = 1 order by created desc limit %d",
intval(local_channel()),
intval(50 - intval($t[0]['total']))
intval(50 - intval($r[0]['total']))
);
$r = array_merge($r1,$r2);
}
@@ -41,7 +41,7 @@ class Notifications extends \Zotlabs\Web\Controller {
$notifications_available = 1;
foreach ($r as $rr) {
$x = strip_tags(bbcode($rr['msg']));
$notif_content .= replace_macros(get_markup_template('notify.tpl'),array(
$notif_content = replace_macros(get_markup_template('notify.tpl'),array(
'$item_link' => z_root().'/notify/view/'. $rr['id'],
'$item_image' => $rr['photo'],
'$item_text' => $x,
@@ -52,7 +52,7 @@ class Notifications extends \Zotlabs\Web\Controller {
}
}
else {
$notif_content .= t('No more system notifications.');
$notif_content = t('No more system notifications.');
}
$o .= replace_macros(get_markup_template('notifications.tpl'),array(

View File

@@ -8,16 +8,16 @@ use Zotlabs\Lib\Libsync;
class Pconfig extends \Zotlabs\Web\Controller {
function post() {
if(! local_channel())
return;
if($_SESSION['delegate'])
return;
check_form_security_token_redirectOnErr('/pconfig', 'pconfig');
$cat = trim(escape_tags($_POST['cat']));
$k = trim(escape_tags($_POST['k']));
$v = trim($_POST['v']);
@@ -27,16 +27,16 @@ class Pconfig extends \Zotlabs\Web\Controller {
if (preg_match('|^a:[0-9]+:{.*}$|s',$v) || preg_match('|O:8:"stdClass":[0-9]+:{.*}$|s',$v)) {
return;
}
if(in_array(argv(2),$this->disallowed_pconfig())) {
notice( t('This setting requires special processing and editing has been blocked.') . EOL);
return;
}
if(strpos($k,'password') !== false) {
$v = z_obscure($v);
$v = obscurify($v);
}
set_pconfig(local_channel(),$cat,$k,$v);
Libsync::build_sync_packet();
@@ -46,24 +46,24 @@ class Pconfig extends \Zotlabs\Web\Controller {
goaway(z_root() . '/pconfig/' . $cat . '/' . $k);
}
function get() {
if(! local_channel()) {
return login();
}
$content = '<h3>' . t('Configuration Editor') . '</h3>';
$content .= '<div class="descriptive-paragraph">' . t('Warning: Changing some settings could render your channel inoperable. Please leave this page unless you are comfortable with and knowledgeable about how to correctly use this feature.') . '</div>' . EOL . EOL;
if(argc() == 3) {
$content .= '<a href="pconfig">pconfig[' . local_channel() . ']</a>' . EOL;
$content .= '<a href="pconfig/' . escape_tags(argv(1)) . '">pconfig[' . local_channel() . '][' . escape_tags(argv(1)) . ']</a>' . EOL . EOL;
$content .= '<a href="pconfig/' . escape_tags(argv(1)) . '/' . escape_tags(argv(2)) . '" >pconfig[' . local_channel() . '][' . escape_tags(argv(1)) . '][' . escape_tags(argv(2)) . ']</a> = ' . get_pconfig(local_channel(),escape_tags(argv(1)),escape_tags(argv(2))) . EOL;
if(in_array(argv(2),$this->disallowed_pconfig())) {
notice( t('This setting requires special processing and editing has been blocked.') . EOL);
return $content;
@@ -71,8 +71,8 @@ class Pconfig extends \Zotlabs\Web\Controller {
else
$content .= $this->pconfig_form(escape_tags(argv(1)),escape_tags(argv(2)));
}
if(argc() == 2) {
$content .= '<a href="pconfig">pconfig[' . local_channel() . ']</a>' . EOL;
load_pconfig(local_channel(),escape_tags(argv(1)));
@@ -80,9 +80,9 @@ class Pconfig extends \Zotlabs\Web\Controller {
$content .= '<a href="pconfig/' . escape_tags(argv(1)) . '/' . $k . '" >pconfig[' . local_channel() . '][' . escape_tags(argv(1)) . '][' . $k . ']</a> = ' . escape_tags($x) . EOL;
}
}
if(argc() == 1) {
$r = q("select * from pconfig where uid = " . local_channel());
if($r) {
foreach($r as $rr) {
@@ -91,33 +91,33 @@ class Pconfig extends \Zotlabs\Web\Controller {
}
}
return $content;
}
function pconfig_form($cat,$k) {
$o = '<form action="pconfig" method="post" >';
$o .= '<input type="hidden" name="form_security_token" value="' . get_form_security_token('pconfig') . '" />';
$v = get_pconfig(local_channel(),$cat,$k);
if(strpos($k,'password') !== false)
$v = z_unobscure($v);
if(strpos($k,'password') !== false)
$v = unobscurify($v);
$o .= '<input type="hidden" name="cat" value="' . $cat . '" />';
$o .= '<input type="hidden" name="k" value="' . $k . '" />';
if(strpos($v,"\n"))
$o .= '<textarea name="v" >' . escape_tags($v) . '</textarea>';
else
$o .= '<input type="text" name="v" value="' . escape_tags($v) . '" />';
$o .= EOL . EOL;
$o .= EOL . EOL;
$o .= '<input type="submit" name="submit" value="' . t('Submit') . '" />';
$o .= '</form>';
return $o;
}
@@ -127,5 +127,5 @@ class Pconfig extends \Zotlabs\Web\Controller {
'permissions_role'
);
}
}

View File

@@ -147,7 +147,7 @@ class Photo extends \Zotlabs\Web\Controller {
);
if($r) {
$allowed = (-1);
$filename = $r[0]['filename'];
$u = intval($r[0]['photo_usage']);
if($u) {
$allowed = 1;
@@ -194,9 +194,9 @@ class Photo extends \Zotlabs\Web\Controller {
$mimetype = $e[0]['mimetype'];
$modified = strtotime($e[0]['edited'] . 'Z');
if(intval($e[0]['os_storage'])) {
if(intval($e[0]['os_storage']))
$streaming = $data;
}
if($e[0]['allow_cid'] != '' || $e[0]['allow_gid'] != '' || $e[0]['deny_gid'] != '' || $e[0]['deny_gid'] != '')
$prvcachecontrol = 'no-store, no-cache, must-revalidate';
}
@@ -282,7 +282,7 @@ class Photo extends \Zotlabs\Web\Controller {
header("Content-Length: " . (isset($filesize) ? $filesize : strlen($data)));
// If it's a file resource, stream it.
if($streaming && $channel) {
if($streaming) {
if(strpos($streaming,'store') !== false)
$istream = fopen($streaming,'rb');
else

View File

@@ -6,6 +6,7 @@ namespace Zotlabs\Module;
*/
use App;
use Zotlabs\Lib\Libsync;
class Pin extends \Zotlabs\Web\Controller {
@@ -64,6 +65,6 @@ class Pin extends \Zotlabs\Web\Controller {
http_status_exit(404, 'Not found');
}
build_sync_packet($r[0]['uid'], [ 'config' ]);
Libsync::build_sync_packet($r[0]['uid'], [ 'config' ]);
}
}

View File

@@ -2,21 +2,23 @@
namespace Zotlabs\Module;
use Zotlabs\Lib\Crypto;
class Prate extends \Zotlabs\Web\Controller {
function init() {
if($_SERVER['REQUEST_METHOD'] === 'post')
return;
if(! local_channel())
return;
$channel = \App::get_channel();
$target = argv(1);
if(! $target)
return;
$r = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1",
dbesc($channel['channel_hash']),
dbesc($target)
@@ -25,34 +27,34 @@ class Prate extends \Zotlabs\Web\Controller {
json_return_and_die(array('rating' => $r[0]['xlink_rating'],'rating_text' => $r[0]['xlink_rating_text']));
killme();
}
function post() {
if(! local_channel())
return;
$channel = \App::get_channel();
$target = trim($_REQUEST['target']);
if(! $target)
return;
if($target === $channel['channel_hash'])
return;
$rating = intval($_POST['rating']);
if($rating < (-10))
$rating = (-10);
if($rating > 10)
$rating = 10;
$rating_text = trim(escape_tags($_REQUEST['rating_text']));
$signed = $target . '.' . $rating . '.' . $rating_text;
$sig = base64url_encode(rsa_sign($signed,$channel['channel_prvkey']));
$sig = base64url_encode(Crypto::sign($signed,$channel['channel_prvkey']));
$z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1",
dbesc($channel['channel_hash']),
dbesc($target)
@@ -87,19 +89,19 @@ class Prate extends \Zotlabs\Web\Controller {
if($record) {
\Zotlabs\Daemon\Master::Summon(array('Ratenotif','rating',$record));
}
json_return_and_die(array('result' => true));;
}
}

View File

@@ -3,6 +3,7 @@ namespace Zotlabs\Module;
use App;
use Zotlabs\Lib\Apps;
use Zotlabs\Lib\Crypto;
require_once('include/zot.php');
@@ -24,18 +25,18 @@ class Probe extends \Zotlabs\Web\Controller {
nav_set_selected('Remote Diagnostics');
$o .= '<h3>Remote Diagnostics</h3>';
$o .= '<form action="probe" method="get">';
$o .= 'Lookup address: <input type="text" style="width: 250px;" name="addr" value="' . $_GET['addr'] .'" />';
$o .= '<input type="submit" name="submit" value="Submit" /></form>';
$o .= '<input type="submit" name="submit" value="Submit" /></form>';
$o .= '<br /><br />';
if(x($_GET,'addr')) {
$channel = App::get_channel();
$addr = trim($_GET['addr']);
$do_import = ((intval($_GET['import']) && is_site_admin()) ? true : false);
$j = \Zotlabs\Zot\Finger::run($addr,$channel,false);
$o .= '<pre>';
@@ -43,17 +44,17 @@ class Probe extends \Zotlabs\Web\Controller {
$o .= "<strong>https connection failed. Trying again with auto failover to http.</strong>\r\n\r\n";
$j = \Zotlabs\Zot\Finger::run($addr,$channel,true);
if(! $j['success']) {
return $o;
return $o;
}
}
if($do_import && $j)
$x = import_xchan($j);
if($j && $j['permissions'] && $j['permissions']['iv'])
$j['permissions'] = json_decode(crypto_unencapsulate($j['permissions'],$channel['channel_prvkey']),true);
$j['permissions'] = json_decode(Crypto::unencapsulate($j['permissions'],$channel['channel_prvkey']),true);
$o .= str_replace("\n",'<br />',print_r($j,true));
$o .= '</pre>';
}
return $o;
}
}

View File

@@ -1,5 +1,13 @@
<?php
namespace Zotlabs\Module; /** @file */
namespace Zotlabs\Module;
use App;
use Zotlabs\Lib\ActivityStreams;
use Zotlabs\Lib\Activity;
use Zotlabs\Web\Controller;
/** @file */
require_once('include/contact_widgets.php');
require_once('include/items.php');
@@ -9,110 +17,115 @@ require_once('include/conversation.php');
require_once('include/acl_selectors.php');
class Profile extends \Zotlabs\Web\Controller {
class Profile extends Controller {
function init() {
if(argc() > 1)
if (argc() > 1)
$which = argv(1);
else {
notice( t('Requested profile is not available.') . EOL );
\App::$error = 404;
notice(t('Requested profile is not available.') . EOL);
App::$error = 404;
return;
}
nav_set_selected('Profile');
$profile = '';
$channel = \App::get_channel();
if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
$which = $channel['channel_address'];
$profile = argv(1);
$r = q("select profile_guid from profile where id = %d and uid = %d limit 1",
$channel = App::get_channel();
if (!$channel)
http_status_exit(404, 'Not found');
if (ActivityStreams::is_as_request()) {
$p = Activity::encode_person($channel, true);
as_return_and_die(['type' => 'Profile', 'describes' => $p], $channel);
}
nav_set_selected('Profile');
if ((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
$which = $channel['channel_address'];
$profile = argv(1);
$r = q("select profile_guid from profile where id = %d and uid = %d limit 1",
intval($profile),
intval(local_channel())
);
if(! $r)
if (!$r)
$profile = '';
$profile = $r[0]['profile_guid'];
}
head_add_link( [
'rel' => 'alternate',
head_add_link([
'rel' => 'alternate',
'type' => 'application/atom+xml',
'title' => t('Posts and comments'),
'href' => z_root() . '/feed/' . $which
]);
head_add_link( [
'rel' => 'alternate',
head_add_link([
'rel' => 'alternate',
'type' => 'application/atom+xml',
'title' => t('Only posts'),
'href' => z_root() . '/feed/' . $which . '?f=&top=1'
]);
if(! $profile) {
if (!$profile) {
$x = q("select channel_id as profile_uid from channel where channel_address = '%s' limit 1",
dbesc(argv(1))
);
if($x) {
\App::$profile = $x[0];
if ($x) {
App::$profile = $x[0];
}
}
profile_load($which,$profile);
profile_load($which, $profile);
}
function get() {
if(observer_prohibited(true)) {
if (observer_prohibited(true)) {
return login();
}
$groups = array();
$groups = [];
$tab = 'profile';
$o = '';
if(! (perm_is_allowed(\App::$profile['profile_uid'],get_observer_hash(), 'view_profile'))) {
notice( t('Permission denied.') . EOL);
$o = '';
if (!(perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'view_profile'))) {
notice(t('Permission denied.') . EOL);
return;
}
if(argc() > 2 && argv(2) === 'vcard') {
if (argc() > 2 && argv(2) === 'vcard') {
header('Content-type: text/vcard');
header('content-disposition: attachment; filename="' . t('vcard') . '-' . $profile['channel_address'] . '.vcf"' );
echo \App::$profile['profile_vcard'];
header('content-disposition: attachment; filename="' . t('vcard') . '-' . App::$profile['channel_address'] . '.vcf"');
echo App::$profile['profile_vcard'];
killme();
}
$is_owner = ((local_channel()) && (local_channel() == \App::$profile['profile_uid']) ? true : false);
if(\App::$profile['hidewall'] && (! $is_owner) && (! remote_channel())) {
notice( t('Permission denied.') . EOL);
$is_owner = ((local_channel()) && (local_channel() == App::$profile['profile_uid']) ? true : false);
if (App::$profile['hidewall'] && (!$is_owner) && (!remote_channel())) {
notice(t('Permission denied.') . EOL);
return;
}
head_add_link([
head_add_link([
'rel' => 'alternate',
'type' => 'application/json+oembed',
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string),
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . App::$query_string),
'title' => 'oembed'
]);
$o .= advanced_profile();
call_hooks('profile_advanced',$o);
call_hooks('profile_advanced', $o);
return $o;
}
}

View File

@@ -749,7 +749,7 @@ class Profiles extends \Zotlabs\Web\Controller {
'$default' => t('This is your default profile.') . EOL . translate_scope(map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'view_profile'))),
'$advanced' => $advanced,
'$name' => array('name', t('Your full name'), $r[0]['fullname'], t('Required'), '*'),
'$pdesc' => array('pdesc', t('Short title/tescription'), $r[0]['pdesc'], t('Maximal 190 characters'), '', 'maxlength="190"'),
'$pdesc' => array('pdesc', t('Short title/description'), $r[0]['pdesc'], t('Maximal 190 characters'), '', 'maxlength="190"'),
'$dob' => dob($r[0]['dob']),
'$hide_friends' => $hide_friends,
'$address' => array('address', t('Street address'), $r[0]['address']),

View File

@@ -3,21 +3,23 @@ namespace Zotlabs\Module;
use Zotlabs\Lib\Crypto;
class Rate extends \Zotlabs\Web\Controller {
function init() {
if(! local_channel())
return;
$channel = \App::get_channel();
$target = $_REQUEST['target'];
if(! $target)
return;
\App::$data['target'] = $target;
if($target) {
$r = q("SELECT * FROM xchan where xchan_hash like '%s' LIMIT 1",
dbesc($target)
@@ -36,43 +38,43 @@ class Rate extends \Zotlabs\Web\Controller {
}
}
}
return;
}
function post() {
if(! local_channel())
return;
if(! \App::$data['target'])
return;
if(! $_REQUEST['execute'])
return;
$channel = \App::get_channel();
$rating = intval($_POST['rating']);
if($rating < (-10))
$rating = (-10);
if($rating > 10)
$rating = 10;
$rating_text = trim(escape_tags($_REQUEST['rating_text']));
$signed = \App::$data['target'] . '.' . $rating . '.' . $rating_text;
$sig = base64url_encode(rsa_sign($signed,$channel['channel_prvkey']));
$sig = base64url_encode(Crypto::sign($signed,$channel['channel_prvkey']));
$z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1",
dbesc($channel['channel_hash']),
dbesc(\App::$data['target'])
);
if($z) {
$record = $z[0]['xlink_id'];
$w = q("update xlink set xlink_rating = '%d', xlink_rating_text = '%s', xlink_sig = '%s', xlink_updated = '%s'
@@ -100,39 +102,39 @@ class Rate extends \Zotlabs\Web\Controller {
if($z)
$record = $z[0]['xlink_id'];
}
if($record) {
\Zotlabs\Daemon\Master::Summon(array('Ratenotif','rating',$record));
}
}
function get() {
if(! local_channel()) {
notice( t('Permission denied.') . EOL);
return;
}
// if(! \App::$data['target']) {
// notice( t('No recipients.') . EOL);
// return;
// }
$rating_enabled = get_config('system','rating_enabled');
if(! $rating_enabled) {
notice('Ratings are disabled on this site.');
return;
}
$channel = \App::get_channel();
$r = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1",
dbesc($channel['channel_hash']),
dbesc(\App::$data['target'])
);
if($r) {
\App::$data['xlink'] = $r[0];
\App::$data['xlink'] = $r[0];
$rating_val = $r[0]['xlink_rating'];
$rating_text = $r[0]['xlink_rating_text'];
}
@@ -140,7 +142,7 @@ class Rate extends \Zotlabs\Web\Controller {
$rating_val = 0;
$rating_text = '';
}
if($rating_enabled) {
$rating = replace_macros(get_markup_template('rating_slider.tpl'),array(
'$min' => -10,
@@ -150,7 +152,7 @@ class Rate extends \Zotlabs\Web\Controller {
else {
$rating = false;
}
$o = replace_macros(get_markup_template('rating_form.tpl'),array(
'$header' => t('Rating'),
'$website' => t('Website:'),
@@ -165,8 +167,8 @@ class Rate extends \Zotlabs\Web\Controller {
'$slide' => $slide,
'$submit' => t('Submit')
));
return $o;
}
}

View File

@@ -6,8 +6,6 @@ class Regver extends \Zotlabs\Web\Controller {
function get() {
global $lang;
$_SESSION['return_url'] = \App::$cmd;
if(argc() != 3)

View File

@@ -1,85 +1,116 @@
<?php
namespace Zotlabs\Module;
use App;
use Zotlabs\Lib\Activity;
use Zotlabs\Lib\ActivityStreams;
use Zotlabs\Web\Controller;
class Search extends \Zotlabs\Web\Controller {
class Search extends Controller {
function init() {
if(x($_REQUEST,'search'))
\App::$data['search'] = escape_tags($_REQUEST['search']);
if (x($_REQUEST, 'search'))
App::$data['search'] = escape_tags($_REQUEST['search']);
}
function get($update = 0, $load = false) {
if((get_config('system','block_public')) || (get_config('system','block_public_search'))) {
if ((! local_channel()) && (! remote_channel())) {
notice( t('Public access denied.') . EOL);
if ((get_config('system', 'block_public')) || (get_config('system', 'block_public_search'))) {
if ((!local_channel()) && (!remote_channel())) {
notice(t('Public access denied.') . EOL);
return;
}
}
nav_set_selected('Search');
require_once("include/bbcode.php");
require_once('include/security.php');
require_once('include/conversation.php');
require_once('include/items.php');
$format = (($_REQUEST['format']) ? $_REQUEST['format'] : '');
if($format !== '') {
if ($format !== '') {
$update = $load = 1;
}
$observer = \App::get_observer();
$observer = App::get_observer();
$observer_hash = (($observer) ? $observer['xchan_hash'] : '');
$o = '<div id="live-search"></div>' . "\r\n";
$o .= '<div class="generic-content-wrapper-styled">' . "\r\n";
$o .= '<h3>' . t('Search') . '</h3>';
if(x(\App::$data,'search'))
$search = trim(\App::$data['search']);
if (x(App::$data, 'search'))
$search = trim(App::$data['search']);
else
$search = ((x($_GET,'search')) ? trim(escape_tags(rawurldecode($_GET['search']))) : '');
$search = ((x($_GET, 'search')) ? trim(escape_tags(rawurldecode($_GET['search']))) : '');
$tag = false;
if(x($_GET,'tag')) {
$tag = true;
$search = ((x($_GET,'tag')) ? trim(escape_tags(rawurldecode($_GET['tag']))) : '');
if (x($_GET, 'tag')) {
$tag = true;
$search = ((x($_GET, 'tag')) ? trim(escape_tags(rawurldecode($_GET['tag']))) : '');
}
$o .= search($search,'search-box','/search',((local_channel()) ? true : false));
if(strpos($search,'#') === 0) {
$tag = true;
$search = substr($search,1);
$o .= search($search, 'search-box', '/search', ((local_channel()) ? true : false));
if (local_channel() && strpos($search, 'https://') === 0 && !$update && !$load) {
$j = Activity::fetch($search, App::get_channel());
if ($j) {
$AS = new ActivityStreams($j);
if ($AS->is_valid()) {
// check if is_an_actor, otherwise import activity
if (is_array($AS->obj) && !ActivityStreams::is_an_actor($AS->obj)) {
$item = Activity::decode_note($AS);
if ($item) {
logger('parsed_item: ' . print_r($item, true), LOGGER_DATA);
Activity::store(App::get_channel(), $observer_hash, $AS, $item, true, true);
goaway(z_root() . '/display/' . gen_link_id($item['mid']));
}
}
}
}
else {
// try other fetch providers (e.g. diaspora)
$hookdata = [
'channel' => App::get_channel(),
'data' => $search
];
call_hooks('fetch_provider', $hookdata);
}
}
if(strpos($search,'@') === 0) {
$search = substr($search,1);
if (strpos($search, '#') === 0) {
$tag = true;
$search = substr($search, 1);
}
if (strpos($search, '@') === 0) {
$search = substr($search, 1);
goaway(z_root() . '/directory' . '?f=1&navsearch=1&search=' . $search);
}
if(strpos($search,'!') === 0) {
$search = substr($search,1);
if (strpos($search, '!') === 0) {
$search = substr($search, 1);
goaway(z_root() . '/directory' . '?f=1&navsearch=1&search=' . $search);
}
if(strpos($search,'?') === 0) {
$search = substr($search,1);
if (strpos($search, '?') === 0) {
$search = substr($search, 1);
goaway(z_root() . '/help' . '?f=1&navsearch=1&search=' . $search);
}
// look for a naked webbie
if(strpos($search,'@') !== false) {
if (strpos($search, '@') !== false) {
goaway(z_root() . '/directory' . '?f=1&navsearch=1&search=' . $search);
}
if(! $search)
if (!$search)
return $o;
if($tag) {
$wildtag = str_replace('*','%',$search);
if ($tag) {
$wildtag = str_replace('*', '%', $search);
$sql_extra = sprintf(" AND item.id IN (select oid from term where otype = %d and ttype in ( %d , %d) and term like '%s') ",
intval(TERM_OBJ_POST),
intval(TERM_HASHTAG),
@@ -88,80 +119,80 @@ class Search extends \Zotlabs\Web\Controller {
);
}
else {
$regstr = db_getfunc('REGEXP');
$regstr = db_getfunc('REGEXP');
$sql_extra = sprintf(" AND (item.title $regstr '%s' OR item.body $regstr '%s') ", dbesc(protect_sprintf(preg_quote($search))), dbesc(protect_sprintf(preg_quote($search))));
}
// Here is the way permissions work in the search module...
// Only public posts can be shown
// OR your own posts if you are a logged in member
// No items will be shown if the member has a blocked profile wall.
// No items will be shown if the member has a blocked profile wall.
if ((!$update) && (!$load)) {
if((! $update) && (! $load)) {
// This is ugly, but we can't pass the profile_uid through the session to the ajax updater,
// because browser prefetching might change it on us. We have to deliver it with the page.
$o .= '<div id="live-search"></div>' . "\r\n";
$o .= "<script> var profile_uid = " . ((intval(local_channel())) ? local_channel() : (-1))
. "; var netargs = '?f='; var profile_page = " . \App::$pager['page'] . "; </script>\r\n";
\App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array(
. "; var netargs = '?f='; var profile_page = " . App::$pager['page'] . "; </script>\r\n";
App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"), [
'$baseurl' => z_root(),
'$pgtype' => 'search',
'$uid' => ((\App::$profile['profile_uid']) ? \App::$profile['profile_uid'] : '0'),
'$gid' => '0',
'$cid' => '0',
'$cmin' => '(-1)',
'$cmax' => '(-1)',
'$star' => '0',
'$liked' => '0',
'$conv' => '0',
'$spam' => '0',
'$fh' => '0',
'$dm' => '0',
'$pgtype' => 'search',
'$uid' => ((App::$profile['profile_uid']) ? App::$profile['profile_uid'] : '0'),
'$gid' => '0',
'$cid' => '0',
'$cmin' => '(-1)',
'$cmax' => '(-1)',
'$star' => '0',
'$liked' => '0',
'$conv' => '0',
'$spam' => '0',
'$fh' => '0',
'$dm' => '0',
'$nouveau' => '0',
'$wall' => '0',
'$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0),
'$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1),
'$search' => (($tag) ? urlencode('#') : '') . $search,
'$xchan' => '',
'$order' => '',
'$file' => '',
'$cats' => '',
'$tags' => '',
'$mid' => '',
'$verb' => '',
'$net' => '',
'$dend' => '',
'$dbegin' => ''
));
'$wall' => '0',
'$list' => ((x($_REQUEST, 'list')) ? intval($_REQUEST['list']) : 0),
'$page' => ((App::$pager['page'] != 1) ? App::$pager['page'] : 1),
'$search' => (($tag) ? urlencode('#') : '') . $search,
'$xchan' => '',
'$order' => '',
'$file' => '',
'$cats' => '',
'$tags' => '',
'$mid' => '',
'$verb' => '',
'$net' => '',
'$dend' => '',
'$dbegin' => ''
]);
}
$item_normal = item_normal_search();
$pub_sql = public_permissions_sql($observer_hash);
$pub_sql = public_permissions_sql($observer_hash);
require_once('include/channel.php');
$sys = get_sys_channel();
if(($update) && ($load)) {
$itemspage = get_pconfig(local_channel(),'system','itemspage');
\App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10));
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start']));
if (($update) && ($load)) {
$itemspage = get_pconfig(local_channel(), 'system', 'itemspage');
App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10));
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start']));
// in case somebody turned off public access to sys channel content with permissions
if(! perm_is_allowed($sys['channel_id'],$observer_hash,'view_stream'))
if (!perm_is_allowed($sys['channel_id'], $observer_hash, 'view_stream'))
$sys['xchan_hash'] .= 'disabled';
if($load) {
if ($load) {
$r = null;
if(local_channel()) {
if (local_channel()) {
$r = q("SELECT mid, MAX(id) as item_id from item
WHERE ((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = '' AND item.deny_gid = '' AND item_private = 0 )
OR ( item.uid = %d )) OR item.owner_xchan = '%s' )
@@ -172,11 +203,11 @@ class Search extends \Zotlabs\Web\Controller {
dbesc($sys['xchan_hash'])
);
}
if($r === null) {
if ($r === null) {
$r = q("SELECT mid, MAX(id) as item_id from item
WHERE (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
AND item.deny_gid = '' AND item_private = 0 )
and owner_xchan in ( " . stream_perms_xchans(($observer) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " ))
and owner_xchan in ( " . stream_perms_xchans(($observer) ? (PERMS_NETWORK | PERMS_PUBLIC) : PERMS_PUBLIC) . " ))
$pub_sql ) OR owner_xchan = '%s')
$item_normal
$sql_extra
@@ -184,51 +215,49 @@ class Search extends \Zotlabs\Web\Controller {
dbesc($sys['xchan_hash'])
);
}
if($r) {
$str = ids_to_querystr($r,'item_id');
$r = q("select *, id as item_id from item where id in ( " . $str . ") order by created desc ");
if ($r) {
$str = ids_to_querystr($r, 'item_id');
$r = q("select *, id as item_id from item where id in ( " . $str . ") order by created desc ");
}
}
else {
$r = array();
$r = [];
}
}
if($r) {
if ($r) {
xchan_query($r);
$items = fetch_post_tags($r,true);
} else {
$items = array();
$items = fetch_post_tags($r, true);
}
if($format == 'json') {
$result = array();
else {
$items = [];
}
if ($format == 'json') {
$result = [];
require_once('include/conversation.php');
foreach($items as $item) {
foreach ($items as $item) {
$item['html'] = zidify_links(bbcode($item['body']));
$x = encode_item($item);
$x['html'] = prepare_text($item['body'],$item['mimetype']);
$result[] = $x;
$x = encode_item($item);
$x['html'] = prepare_text($item['body'], $item['mimetype']);
$result[] = $x;
}
json_return_and_die(array('success' => true,'messages' => $result));
json_return_and_die(['success' => true, 'messages' => $result]);
}
if($tag)
$o .= '<h2>' . sprintf( t('Items tagged with: %s'),$search) . '</h2>';
if ($tag)
$o .= '<h2>' . sprintf(t('Items tagged with: %s'), $search) . '</h2>';
else
$o .= '<h2>' . sprintf( t('Search results for: %s'),$search) . '</h2>';
$o .= conversation($items,'search',$update,'client');
$o .= '<h2>' . sprintf(t('Search results for: %s'), $search) . '</h2>';
$o .= conversation($items, 'search', $update, 'client');
$o .= '</div>';
return $o;
}
}

View File

@@ -63,15 +63,15 @@ class Setup extends \Zotlabs\Web\Controller {
return;
// implied break;
case 3:
$dbhost = trim($_POST['dbhost']);
$dbport = intval(trim($_POST['dbport']));
$dbuser = trim($_POST['dbuser']);
$dbpass = trim($_POST['dbpass']);
$dbdata = trim($_POST['dbdata']);
$dbtype = intval(trim($_POST['dbtype']));
$phpath = trim($_POST['phpath']);
$adminmail = trim($_POST['adminmail']);
$siteurl = trim($_POST['siteurl']);
$dbhost = ((isset($_POST['dbhost'])) ? trim($_POST['dbhost']) : '');
$dbuser = ((isset($_POST['dbuser'])) ? trim($_POST['dbuser']) : '');
$dbport = ((isset($_POST['dbport'])) ? intval(trim($_POST['dbport'])) : 0);
$dbpass = ((isset($_POST['dbpass'])) ? trim($_POST['dbpass']) : '');
$dbdata = ((isset($_POST['dbdata'])) ? trim($_POST['dbdata']) : '');
$dbtype = ((isset($_POST['dbtype'])) ? intval(trim($_POST['dbtype'])) : 0);
$phpath = ((isset($_POST['phpath'])) ? trim($_POST['phpath']) : '');
$adminmail = ((isset($_POST['adminmail'])) ? trim($_POST['adminmail']) : '');
$siteurl = ((isset($_POST['siteurl'])) ? trim($_POST['siteurl']) : '');
// $siteurl should not have a trailing slash
@@ -88,16 +88,16 @@ class Setup extends \Zotlabs\Web\Controller {
return;
// implied break;
case 4:
$dbhost = trim($_POST['dbhost']);
$dbport = intval(trim($_POST['dbport']));
$dbuser = trim($_POST['dbuser']);
$dbpass = trim($_POST['dbpass']);
$dbdata = trim($_POST['dbdata']);
$dbtype = intval(trim($_POST['dbtype']));
$phpath = trim($_POST['phpath']);
$timezone = trim($_POST['timezone']);
$adminmail = trim($_POST['adminmail']);
$siteurl = trim($_POST['siteurl']);
$dbhost = ((isset($_POST['dbhost'])) ? trim($_POST['dbhost']) : '');
$dbuser = ((isset($_POST['dbuser'])) ? trim($_POST['dbuser']) : '');
$dbport = ((isset($_POST['dbport'])) ? intval(trim($_POST['dbport'])) : 0);
$dbpass = ((isset($_POST['dbpass'])) ? trim($_POST['dbpass']) : '');
$dbdata = ((isset($_POST['dbdata'])) ? trim($_POST['dbdata']) : '');
$dbtype = ((isset($_POST['dbtype'])) ? intval(trim($_POST['dbtype'])) : 0);
$phpath = ((isset($_POST['phpath'])) ? trim($_POST['phpath']) : '');
$timezone = ((isset($_POST['timezone'])) ? trim($_POST['timezone']) : '');
$adminmail = ((isset($_POST['adminmail'])) ? trim($_POST['adminmail']) : '');
$siteurl = ((isset($_POST['siteurl'])) ? trim($_POST['siteurl']) : '');
if($siteurl != z_root()) {
$test = z_fetch_url($siteurl."/setup/testrewrite");
@@ -108,12 +108,14 @@ class Setup extends \Zotlabs\Web\Controller {
}
}
if(! \DBA::$dba->connected) {
$db = null;
if(! isset(\DBA::$dba->connected)) {
// connect to db
$db = \DBA::dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, true);
}
if(! \DBA::$dba->connected) {
if(! isset(\DBA::$dba->connected)) {
echo 'CRITICAL: DB not connected.';
killme();
}
@@ -126,7 +128,7 @@ class Setup extends \Zotlabs\Web\Controller {
'$dbpass' => $dbpass,
'$dbdata' => $dbdata,
'$dbtype' => $dbtype,
'$server_role' => 'pro',
'$server_role' => '',
'$timezone' => $timezone,
'$siteurl' => $siteurl,
'$site_id' => random_string(),
@@ -267,14 +269,14 @@ class Setup extends \Zotlabs\Web\Controller {
case 2: { // Database config
$dbhost = ((x($_POST,'dbhost')) ? trim($_POST['dbhost']) : '127.0.0.1');
$dbuser = trim($_POST['dbuser']);
$dbport = intval(trim($_POST['dbport']));
$dbpass = trim($_POST['dbpass']);
$dbdata = trim($_POST['dbdata']);
$dbtype = intval(trim($_POST['dbtype']));
$phpath = trim($_POST['phpath']);
$adminmail = trim($_POST['adminmail']);
$dbhost = ((isset($_POST['dbhost'])) ? trim($_POST['dbhost']) : '127.0.0.1');
$dbuser = ((isset($_POST['dbuser'])) ? trim($_POST['dbuser']) : '');
$dbport = ((isset($_POST['dbport'])) ? intval(trim($_POST['dbport'])) : 0);
$dbpass = ((isset($_POST['dbpass'])) ? trim($_POST['dbpass']) : '');
$dbdata = ((isset($_POST['dbdata'])) ? trim($_POST['dbdata']) : '');
$dbtype = ((isset($_POST['dbtype'])) ? intval(trim($_POST['dbtype'])) : 0);
$phpath = ((isset($_POST['phpath'])) ? trim($_POST['phpath']) : '');
$adminmail = ((isset($_POST['adminmail'])) ? trim($_POST['adminmail']) : '');
$tpl = get_markup_template('install_db.tpl');
$o .= replace_macros($tpl, array(
@@ -307,17 +309,17 @@ class Setup extends \Zotlabs\Web\Controller {
}; break;
case 3: { // Site settings
require_once('include/datetime.php');
$dbhost = ((x($_POST,'dbhost')) ? trim($_POST['dbhost']) : '127.0.0.1');
$dbport = intval(trim($_POST['dbuser']));
$dbuser = trim($_POST['dbuser']);
$dbpass = trim($_POST['dbpass']);
$dbdata = trim($_POST['dbdata']);
$dbtype = intval(trim($_POST['dbtype']));
$phpath = trim($_POST['phpath']);
$adminmail = trim($_POST['adminmail']);
$timezone = ((x($_POST,'timezone')) ? ($_POST['timezone']) : 'America/Los_Angeles');
$dbhost = ((isset($_POST['dbhost'])) ? trim($_POST['dbhost']) : '127.0.0.1');
$dbuser = ((isset($_POST['dbuser'])) ? trim($_POST['dbuser']) : '');
$dbport = ((isset($_POST['dbport'])) ? intval(trim($_POST['dbport'])) : 0);
$dbpass = ((isset($_POST['dbpass'])) ? trim($_POST['dbpass']) : '');
$dbdata = ((isset($_POST['dbdata'])) ? trim($_POST['dbdata']) : '');
$dbtype = ((isset($_POST['dbtype'])) ? intval(trim($_POST['dbtype'])) : 0);
$phpath = ((isset($_POST['phpath'])) ? trim($_POST['phpath']) : '');
$timezone = ((isset($_POST['timezone'])) ? trim($_POST['timezone']) : 'America/Los_Angeles');
$adminmail = ((isset($_POST['adminmail'])) ? trim($_POST['adminmail']) : '');
$siteurl = ((isset($_POST['siteurl'])) ? trim($_POST['siteurl']) : '');
$tpl = get_markup_template('install_settings.tpl');
$o .= replace_macros($tpl, array(

View File

@@ -181,7 +181,10 @@ class Sse_bs extends Controller {
$result['network']['offset'] = ((count($items) == $limit) ? intval($offset + $limit) : -1);
xchan_query($items);
foreach($items as $item) {
$result['network']['notifications'][] = Enotify::format($item);
$parsed = Enotify::format($item);
if($parsed) {
$result['network']['notifications'][] = $parsed;
}
}
}
else {
@@ -250,7 +253,10 @@ class Sse_bs extends Controller {
$result['dm']['offset'] = ((count($items) == $limit) ? intval($offset + $limit) : -1);
xchan_query($items);
foreach($items as $item) {
$result['dm']['notifications'][] = Enotify::format($item);
$parsed = Enotify::format($item);
if($parsed) {
$result['dm']['notifications'][] = $parsed;
}
}
}
else {
@@ -319,7 +325,10 @@ class Sse_bs extends Controller {
$result['home']['offset'] = ((count($items) == $limit) ? intval($offset + $limit) : -1);
xchan_query($items);
foreach($items as $item) {
$result['home']['notifications'][] = Enotify::format($item);
$parsed = Enotify::format($item);
if($parsed) {
$result['home']['notifications'][] = $parsed;
}
}
}
else {
@@ -400,7 +409,10 @@ class Sse_bs extends Controller {
$result['pubs']['offset'] = ((count($items) == $limit) ? intval($offset + $limit) : -1);
xchan_query($items);
foreach($items as $item) {
$result['pubs']['notifications'][] = Enotify::format($item);
$parsed = Enotify::format($item);
if($parsed) {
$result['pubs']['notifications'][] = $parsed;
}
}
}
else {
@@ -592,7 +604,10 @@ class Sse_bs extends Controller {
if($r) {
xchan_query($r);
foreach($r as $rr) {
$result['files']['notifications'][] = Enotify::format($rr);
$parsed = Enotify::format($rr);
if($parsed) {
$result['files']['notifications'][] = $parsed;
}
}
$result['files']['count'] = count($r);
}

View File

@@ -17,6 +17,7 @@ class Uexport extends Controller {
if(argc() > 1) {
$sections = (($_REQUEST['sections']) ? explode(',',$_REQUEST['sections']) : '');
$zap_compat = (($_REQUEST['zap_compat']) ? intval($_REQUEST['zap_compat']) : false);
$channel = App::get_channel();
@@ -32,12 +33,12 @@ class Uexport extends Controller {
header('content-disposition: attachment; filename="' . $channel['channel_address'] . (($year) ? '-' . $year : '') . (($month) ? '-' . $month : '') . (($_REQUEST['sections']) ? '-' . $_REQUEST['sections'] : '') . '.json"' );
if($year) {
echo json_encode(identity_export_year(local_channel(),$year,$month));
echo json_encode(identity_export_year(local_channel(),$year,$month, $zap_compat));
killme();
}
if(argc() > 1 && argv(1) === 'basic') {
echo json_encode(identity_basic_export(local_channel(),$sections));
echo json_encode(identity_basic_export(local_channel(),$sections, $zap_compat));
killme();
}
@@ -46,7 +47,7 @@ class Uexport extends Controller {
if(argc() > 1 && argv(1) === 'complete') {
$sections = get_default_export_sections();
$sections[] = 'items';
echo json_encode(identity_basic_export(local_channel(),$sections));
echo json_encode(identity_basic_export(local_channel(),$sections, $zap_compat));
killme();
}
}

View File

@@ -3,34 +3,35 @@ namespace Zotlabs\Module;
require_once('include/zot.php');
use Zotlabs\Lib\Keyutils;
use Zotlabs\Lib\Libzot;
class Wfinger extends \Zotlabs\Web\Controller {
function init() {
session_write_close();
$result = array();
$scheme = '';
if(x($_SERVER,'HTTPS') && $_SERVER['HTTPS'])
$scheme = 'https';
elseif(x($_SERVER,'SERVER_PORT') && (intval($_SERVER['SERVER_PORT']) == 443))
$scheme = 'https';
$zot = intval($_REQUEST['zot']);
if(($scheme !== 'https') && (! $zot)) {
header($_SERVER["SERVER_PROTOCOL"] . ' ' . 500 . ' ' . 'Webfinger requires HTTPS');
killme();
}
$resource = $_REQUEST['resource'];
logger('webfinger: ' . $resource,LOGGER_DEBUG);
$root_resource = false;
$pchan = false;
@@ -39,9 +40,9 @@ class Wfinger extends \Zotlabs\Web\Controller {
$root_resource = true;
$r = null;
if(($resource) && (! $root_resource)) {
if(strpos($resource,'acct:') === 0) {
$channel = str_replace('acct:','',$resource);
if(substr($channel,0,1) === '@' && strpos(substr($channel,1),'@')) {
@@ -56,12 +57,12 @@ class Wfinger extends \Zotlabs\Web\Controller {
goaway('https://' . $host . '/.well-known/webfinger?f=&resource=' . $resource . (($zot) ? '&zot=' . $zot : ''));
}
$channel = substr($channel,0,strpos($channel,'@'));
}
}
}
if(strpos($resource,'http') === 0) {
$channel = str_replace('~','',basename($resource));
}
if(substr($channel,0,1) === '[' ) {
$channel = substr($channel,1);
$channel = substr($channel,0,-1);
@@ -74,16 +75,16 @@ class Wfinger extends \Zotlabs\Web\Controller {
$r[0] = pchan_to_chan($r[0]);
}
}
else {
else {
$r = q("select * from channel left join xchan on channel_hash = xchan_hash
where channel_address = '%s' limit 1",
dbesc($channel)
);
}
}
header('Access-Control-Allow-Origin: *');
if($root_resource) {
$result['subject'] = $resource;
@@ -100,52 +101,52 @@ class Wfinger extends \Zotlabs\Web\Controller {
}
if($resource && $r) {
$h = q("select hubloc_addr from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0",
dbesc($r[0]['channel_hash'])
);
$result['subject'] = $resource;
$aliases = array(
z_root() . (($pchan) ? '/pchan/' : '/channel/') . $r[0]['channel_address'],
z_root() . '/~' . $r[0]['channel_address'],
z_root() . '/@' . $r[0]['channel_address']
);
if($h) {
foreach($h as $hh) {
$aliases[] = 'acct:' . $hh['hubloc_addr'];
}
}
$result['aliases'] = [];
$result['properties'] = [
'http://webfinger.net/ns/name' => $r[0]['channel_name'],
'http://xmlns.com/foaf/0.1/name' => $r[0]['channel_name'],
'https://w3id.org/security/v1#publicKeyPem' => $r[0]['xchan_pubkey'],
'http://purl.org/zot/federation' => 'zot6,zot'
];
foreach($aliases as $alias)
foreach($aliases as $alias)
if($alias != $resource)
$result['aliases'][] = $alias;
if($pchan) {
$result['links'] = [
[
'rel' => 'http://webfinger.net/rel/avatar',
'type' => $r[0]['xchan_photo_mimetype'],
'href' => $r[0]['xchan_photo_l']
],
[
'rel' => 'http://webfinger.net/rel/profile-page',
'href' => $r[0]['xchan_url'],
@@ -153,7 +154,7 @@ class Wfinger extends \Zotlabs\Web\Controller {
[
'rel' => 'magic-public-key',
'href' => 'data:application/magic-public-key,' . salmon_key($r[0]['channel_pubkey']),
'href' => 'data:application/magic-public-key,' . Keyutils::salmonKey($r[0]['channel_pubkey']),
]
];
@@ -167,13 +168,13 @@ class Wfinger extends \Zotlabs\Web\Controller {
[
'rel' => 'http://webfinger.net/rel/avatar',
'type' => $r[0]['xchan_photo_mimetype'],
'href' => $r[0]['xchan_photo_l']
'href' => $r[0]['xchan_photo_l']
],
[
'rel' => 'http://microformats.org/profile/hcard',
'type' => 'text/html',
'href' => z_root() . '/hcard/' . $r[0]['channel_address']
'href' => z_root() . '/hcard/' . $r[0]['channel_address']
],
[
@@ -187,8 +188,8 @@ class Wfinger extends \Zotlabs\Web\Controller {
],
[
'rel' => 'http://schemas.google.com/g/2010#updates-from',
'type' => 'application/atom+xml',
'rel' => 'http://schemas.google.com/g/2010#updates-from',
'type' => 'application/atom+xml',
'href' => z_root() . '/ofeed/' . $r[0]['channel_address']
],
@@ -221,7 +222,7 @@ class Wfinger extends \Zotlabs\Web\Controller {
[
'rel' => 'magic-public-key',
'href' => 'data:application/magic-public-key,' . salmon_key($r[0]['channel_pubkey']),
'href' => 'data:application/magic-public-key,' . Keyutils::salmonKey($r[0]['channel_pubkey']),
]
];
}
@@ -236,12 +237,12 @@ class Wfinger extends \Zotlabs\Web\Controller {
header($_SERVER["SERVER_PROTOCOL"] . ' ' . 400 . ' ' . 'Bad Request');
killme();
}
$arr = [ 'channel' => $r[0], 'pchan' => $pchan, 'request' => $_REQUEST, 'result' => $result ];
call_hooks('webfinger',$arr);
json_return_and_die($arr['result'],'application/jrd+json');
}
}

View File

@@ -1,19 +1,21 @@
<?php
namespace Zotlabs\Module;
use Zotlabs\Lib\Keyutils;
require_once('include/crypto.php');
class Xrd extends \Zotlabs\Web\Controller {
function init() {
$uri = urldecode(notags(trim($_GET['uri'])));
$subject = $uri;
logger('xrd: ' . $uri,LOGGER_DEBUG);
$resource = $uri;
if(substr($uri,0,4) === 'http') {
$uri = str_replace('~','',$uri);
$name = basename($uri);
@@ -22,29 +24,29 @@ class Xrd extends \Zotlabs\Web\Controller {
$local = str_replace('acct:', '', $uri);
if(substr($local,0,2) == '//')
$local = substr($local,2);
$name = substr($local,0,strpos($local,'@'));
}
$r = q("SELECT * FROM channel WHERE channel_address = '%s' LIMIT 1",
dbesc($name)
);
if(! $r)
if(! $r)
killme();
$salmon_key = salmon_key($r[0]['channel_pubkey']);
$salmon_key = Keyutils::salmonKey($r[0]['channel_pubkey']);
header('Access-Control-Allow-Origin: *');
header("Content-type: application/xrd+xml");
$aliases = array('acct:' . channel_reddress($r[0]), z_root() . '/channel/' . $r[0]['channel_address'], z_root() . '/~' . $r[0]['channel_address']);
for($x = 0; $x < count($aliases); $x ++) {
if($aliases[$x] === $resource)
unset($aliases[$x]);
}
$o = replace_macros(get_markup_template('xrd_person.tpl'), array(
'$nick' => $r[0]['channel_address'],
'$accturi' => $resource,
@@ -60,14 +62,14 @@ class Xrd extends \Zotlabs\Web\Controller {
'$modexp' => 'data:application/magic-public-key,' . $salmon_key,
'$subscribe' => z_root() . '/follow?f=&amp;url={uri}',
));
$arr = array('user' => $r[0], 'xml' => $o);
call_hooks('personal_xrd', $arr);
echo $arr['xml'];
killme();
}
}

View File

@@ -1,29 +1,142 @@
<?php
namespace Zotlabs\Module;
require_once('include/items.php');
require_once('include/zot.php');
use App;
use Zotlabs\Lib\Activity;
use Zotlabs\Lib\ActivityStreams;
use Zotlabs\Lib\Config;
use Zotlabs\Lib\ThreadListener;
use Zotlabs\Web\Controller;
use Zotlabs\Web\HTTPSig;
class Zotfeed extends \Zotlabs\Web\Controller {
class Zotfeed extends Controller {
function init() {
if (ActivityStreams::is_as_request()) {
if (observer_prohibited(true)) {
killme();
}
$channel = ((argv(1)) ? channelx_by_nick(argv(1)) : get_sys_channel());
if (!$channel) {
killme();
}
if (intval($channel['channel_system'])) {
killme();
}
$sigdata = HTTPSig::verify(($_SERVER['REQUEST_METHOD'] === 'POST') ? file_get_contents('php://input') : EMPTY_STR);
if ($sigdata['portable_id'] && $sigdata['header_valid']) {
$portable_id = $sigdata['portable_id'];
if (!check_channelallowed($portable_id)) {
http_status_exit(403, 'Permission denied');
}
if (!check_siteallowed($sigdata['signer'])) {
http_status_exit(403, 'Permission denied');
}
observer_auth($portable_id);
}
elseif (Config::get('system', 'require_authenticated_fetch', false)) {
http_status_exit(403, 'Permission denied');
}
$observer_hash = get_observer_hash();
$params = [];
$params['begin'] = ((x($_REQUEST, 'date_begin')) ? $_REQUEST['date_begin'] : NULL_DATE);
$params['end'] = ((x($_REQUEST, 'date_end')) ? $_REQUEST['date_end'] : '');
$params['type'] = 'json';
$params['pages'] = ((x($_REQUEST, 'pages')) ? intval($_REQUEST['pages']) : 0);
$params['top'] = ((x($_REQUEST, 'top')) ? intval($_REQUEST['top']) : 0);
$params['direction'] = ((x($_REQUEST, 'direction')) ? dbesc($_REQUEST['direction']) : 'desc'); // unimplemented
$params['cat'] = ((x($_REQUEST, 'cat')) ? escape_tags($_REQUEST['cat']) : '');
$params['compat'] = 1;
$total = items_fetch(
[
'total' => true,
'wall' => 1,
'datequery' => $params['end'],
'datequery2' => $params['begin'],
'direction' => dbesc($params['direction']),
'pages' => $params['pages'],
'order' => dbesc('post'),
'top' => $params['top'],
'cat' => $params['cat'],
'compat' => $params['compat']
], $channel, $observer_hash, CLIENT_MODE_NORMAL, App::$module
);
if ($total) {
App::set_pager_total($total);
App::set_pager_itemspage(30);
}
if (App::$pager['unset'] && $total > 30) {
$ret = Activity::paged_collection_init($total, App::$query_string);
}
else {
$items = items_fetch(
[
'wall' => 1,
'datequery' => $params['end'],
'datequery2' => $params['begin'],
'records' => intval(App::$pager['itemspage']),
'start' => intval(App::$pager['start']),
'direction' => dbesc($params['direction']),
'pages' => $params['pages'],
'order' => dbesc('post'),
'top' => $params['top'],
'cat' => $params['cat'],
'compat' => $params['compat']
], $channel, $observer_hash, CLIENT_MODE_NORMAL, App::$module
);
if ($items && $observer_hash) {
// check to see if this observer is a connection. If not, register any items
// belonging to this channel for notification of deletion/expiration
$x = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'",
intval($channel['channel_id']),
dbesc($observer_hash)
);
if (!$x) {
foreach ($items as $item) {
if (strpos($item['mid'], z_root()) === 0) {
ThreadListener::store($item['mid'], $observer_hash);
}
}
}
}
$ret = Activity::encode_item_collection($items, App::$query_string, 'OrderedCollection', $total);
}
as_return_and_die($ret, $channel);
}
/*
$result = array('success' => false);
$mindate = (($_REQUEST['mindate']) ? datetime_convert('UTC','UTC',$_REQUEST['mindate']) : '');
if(! $mindate)
$mindate = datetime_convert('UTC','UTC', 'now - 14 days');
if(observer_prohibited()) {
$result['message'] = 'Public access denied';
json_return_and_die($result);
}
$observer = \App::get_observer();
$observer = App::get_observer();
logger('observer: ' . get_observer_hash(), LOGGER_DEBUG);
$channel_address = ((argc() > 1) ? argv(1) : '');
if($channel_address) {
$r = q("select channel_id, channel_name from channel where channel_address = '%s' and channel_removed = 0 limit 1",
@@ -40,12 +153,12 @@ class Zotfeed extends \Zotlabs\Web\Controller {
$result['message'] = 'Channel not found.';
json_return_and_die($result);
}
logger('zotfeed request: ' . $r[0]['channel_name'], LOGGER_DEBUG);
$result['project'] = 'Hubzilla';
$result['project'] = 'Hubzilla';
$result['messages'] = zot_feed($r[0]['channel_id'],$observer['xchan_hash'],array('mindate' => $mindate));
$result['success'] = true;
json_return_and_die($result);
*/
}
}

View File

@@ -2,6 +2,8 @@
namespace Zotlabs\Photo;
use Zotlabs\Lib\Hashpath;
/**
* @brief Abstract photo driver class.
*
@@ -505,18 +507,25 @@ abstract class PhotoDriver {
* @return boolean
*/
public function storeThumbnail($arr, $scale = 0) {
// We only process thumbnails here
if($scale == 0)
return false;
$arr['imgscale'] = $scale;
if(boolval(get_config('system','filesystem_storage_thumbnails', 0))) {
$channel = channelx_by_n($arr['uid']);
// We only process thumbnails here
if($scale == 0)
return false;
$arr['imgscale'] = $scale;
if(boolval(get_config('system','photo_storage_type', 1))) {
$arr['os_storage'] = 1;
$arr['os_syspath'] = 'store/' . $channel['channel_address'] . '/' . $arr['os_path'] . '-' . $scale;
if(! $this->saveImage($arr['os_syspath']))
if (array_key_exists('uid', $arr) && ! in_array($scale, [ PHOTO_RES_PROFILE_300, PHOTO_RES_PROFILE_80, PHOTO_RES_PROFILE_48 ])) {
$channel = channelx_by_n($arr['uid']);
$arr['os_syspath'] = 'store/' . $channel['channel_address'] . '/' . $arr['os_path'] . '-' . $scale;
}
else
$arr['os_syspath'] = Hashpath::path($arr['resource_id'], 'store/[data]/[xchan]', 2, 1) . '-' . $scale;
if (! $this->saveImage($arr['os_syspath']))
return false;
}
else

0
Zotlabs/Render/SimpleTemplate.php Executable file → Normal file
View File

2
Zotlabs/Render/SmartyInterface.php Executable file → Normal file
View File

@@ -35,7 +35,7 @@ class SmartyInterface extends Smarty {
$this->right_delimiter = App::get_template_rdelim('smarty3');
// Don't report errors so verbosely
$this->error_reporting = E_ALL & (~E_NOTICE);
$this->error_reporting = E_ALL & ~E_WARNING & ~E_NOTICE;
}
function parsed($template = '') {

0
Zotlabs/Render/SmartyTemplate.php Executable file → Normal file
View File

Some files were not shown because too many files have changed in this diff Show More