Compare commits

...

1642 Commits
5.0.3 ... 7.0

Author SHA1 Message Date
Mario
c2e21e837f wrong function name 2022-01-21 07:45:42 +00:00
Mario
755d0f54f7 Merge branch '7.0RC' 2022-01-21 07:28:24 +00:00
Mario
f62d66ff25 version 7.0 2022-01-21 07:27:35 +00:00
Mario
406d19f930 Merge branch 'dev' into 7.0RC 2022-01-21 07:27:00 +00:00
Mario
42b13614eb update changelog 2022-01-21 07:26:23 +00:00
Mario
c942bd67fe Merge branch 'dev' into 7.0RC 2022-01-21 07:20:30 +00:00
Mario
b8dc3d74b6 update strings 2022-01-21 07:20:04 +00:00
Mario
38fb263737 string 2022-01-21 07:14:40 +00:00
Mario
b55beed2f9 string update 2022-01-20 14:27:28 +00:00
Mario
e9278c03c1 Merge branch 'dev' into 7.0RC 2022-01-20 10:29:52 +00:00
Mario
ae1fe83784 fix potential issue with ap addressing in mod hq 2022-01-20 10:27:55 +00:00
Mario
717a547c40 Merge branch 'dev' into 7.0RC 2022-01-20 10:03:02 +00:00
Mario
ec491e87ab remove deprecated template 2022-01-20 10:02:39 +00:00
Mario
42e30d0835 fix pgsql profile photo issue 2022-01-20 08:14:03 +00:00
Mario
5b19418e48 fix pgsql profile photo issue 2022-01-20 08:12:14 +00:00
Mario
1bc9a7373f Merge branch 'dev' into 7.0RC 2022-01-19 19:14:54 +00:00
Mario
23e59b5dcc update changelog 2022-01-19 19:14:30 +00:00
Mario
c6b459cf96 drop_item() requires the item id not the item array 2022-01-19 19:11:49 +00:00
Mario
33254b4cac Merge branch 'dev' into 7.0RC 2022-01-19 13:22:23 +00:00
Mario
44da40d18d revert background color 2022-01-19 13:21:32 +00:00
Mario
c742f25801 prevent duplicate ids and adjust spinner color 2022-01-19 13:19:32 +00:00
Mario
b153687bf1 prevent duplicate ids and adjust spinner color 2022-01-19 13:18:47 +00:00
Mario
3318f093da Merge branch 'dev' into 7.0RC 2022-01-19 11:25:06 +00:00
Mario
d98d56c3b5 provide a spinner for edit connection action in threads 2022-01-19 11:24:42 +00:00
Mario
c3f5f6c7ad Merge branch 'dev' into 7.0RC 2022-01-19 10:04:42 +00:00
Mario
5f21edcc53 update changelog 2022-01-19 10:04:20 +00:00
Mario
cd0731cbb0 version RC2 2022-01-19 09:51:32 +00:00
Mario
f392ddec2f Merge branch 'dev' into 7.0RC 2022-01-19 09:41:57 +00:00
Mario
df71168ab7 fix channel app naming and translation and cleanup apps with an db update 2022-01-19 09:41:16 +00:00
Mario
e93b26bf54 Merge branch 'dev' into 'dev'
Fix strings translation

See merge request hubzilla/core!1997
2022-01-19 09:21:55 +00:00
Mario
a73d4a8cbd Merge branch 'dev' into 7.0RC 2022-01-19 08:39:12 +00:00
Mario
20ee57801c we must check if actor.id is empty(). checking for isset() only could still end up in an empty string and produce unexpected results 2022-01-19 08:29:44 +00:00
Max Kostikov
6a270d7f02 Fix strings translation 2022-01-18 22:40:25 +02:00
Mario
68639637c9 RC1 2022-01-18 10:27:37 +00:00
Mario
0d1eabbc33 Merge branch 'dev' into 7.0RC 2022-01-18 10:26:21 +00:00
Mario
dce249f7a9 change name on all associated xchans by matching the url 2022-01-18 10:24:52 +00:00
Mario
1723d4fbd8 fix version 2022-01-18 09:59:54 +00:00
Mario
c4b09f1a4f check for existence of vcard 2022-01-18 10:50:25 +01:00
Mario
788c973c13 vcards are not actually implemented anymore 2022-01-18 10:39:00 +01:00
Mario
465c5c8cfb make sure to use the correct default role 2022-01-18 10:26:13 +01:00
Mario
ee28ba5be1 adjust lock hover text if item_private === 2 2022-01-17 08:23:15 +00:00
Mario
9a22e9cf39 bump dev version 2022-01-16 12:47:26 +00:00
Mario
2513f605b6 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2022-01-16 12:45:58 +00:00
Mario
3b1ffb2028 changelog 2022-01-16 12:45:00 +00:00
Max Kostikov
47c6624e12 Merge branch 'dev' into 'dev'
Update Russian translation

See merge request hubzilla/core!1996
2022-01-14 19:22:43 +00:00
Max Kostikov
b6f1b064d3 Update Russian translation 2022-01-14 21:20:40 +02:00
Mario
17d89467df composer dump autoload 2022-01-14 18:31:38 +00:00
Mario
1282214d48 strings and version 2022-01-14 18:28:33 +00:00
Mario
f4bc6ee615 ux improvements 2022-01-13 13:07:59 +00:00
Mario
f8b8d8c540 make sure to fallback if local_channel and no nav_bg is set 2022-01-13 10:32:36 +00:00
Mario
57ff667438 pwa improvements according to lighthouse 2022-01-13 10:18:53 +00:00
Mario
abe3039926 ux improvements 2022-01-12 21:08:29 +00:00
Mario
82a1117e91 mod profile_photo template cleanup 2022-01-12 13:43:30 +00:00
Mario
b6ff3a4d99 mod profile_photo cleanup 2022-01-12 13:35:51 +00:00
Mario
f4046efcb2 refactor mod profile_photo 2022-01-12 13:09:53 +00:00
Mario
fc1d3831cf revert commit 7e2aecd8 2022-01-11 09:59:07 +00:00
Mario
867deda247 remove legacy mail which has been deprecated since a year 2022-01-11 09:29:18 +00:00
Mario
f8149face5 toc: add headings 2022-01-11 09:17:39 +00:00
Mario
7e2aecd8bb lifetime->expires 2022-01-10 11:37:47 +00:00
Mario
105d121199 set samesite cookie flag to none - some browsers start to default the flag to lax (previous none) 2022-01-10 11:36:20 +00:00
Mario
37d662f2f5 css fixes 2022-01-10 09:29:59 +00:00
Mario
5b50454b4d make toc bbcode find its own container by default 2022-01-09 20:44:30 +00:00
Mario
b5e4c08fc5 fix get_tags() parsing toc bbcodes 2022-01-09 18:25:17 +00:00
Mario
db39cd8b7c fix php error 2022-01-09 16:38:10 +00:00
Mario
a35f741a35 deprecate AccessList::widget() 2022-01-09 15:40:54 +00:00
Mario
fc02e018cb mark group actors as such in items and minor text change 2022-01-08 18:57:59 +00:00
Mario
b14a530efb missing nav_set_selected() 2022-01-08 13:22:15 +00:00
Mario
f70bc571bd css fix 2022-01-08 13:17:19 +00:00
Mario
8cc64176b4 missing files 2022-01-07 20:14:11 +00:00
Mario
7450ac1a31 missing files 2022-01-07 20:07:09 +00:00
Mario
c72e5e3b66 streamline privacy groups 2022-01-07 20:03:40 +00:00
Mario
5e811819e2 add link to create new contact roles 2022-01-07 19:14:14 +00:00
Mario
f1c0034a18 more work on access tokens 2022-01-06 21:09:18 +00:00
Mario
7342cb81a3 bump version 2022-01-04 20:42:43 +00:00
Mario
b40e858556 only display connections widget if there are any connections to show 2022-01-04 20:42:07 +00:00
Mario
95a4ed7d6a do not show blocked or ignored contacts in connections 2022-01-04 20:31:42 +00:00
Mario
2c2d4b6b95 remove suggestions widget from mod directory 2022-01-04 19:57:04 +00:00
Mario
4490eae4fe remove suggestions widget from mod network 2022-01-04 19:55:53 +00:00
Mario
9d59cb0135 minor wording change and fix connections link 2022-01-04 19:48:15 +00:00
Mario
7d348fe69f fix Access^CccessList include and plink in post_activity_item() 2022-01-03 20:20:42 +00:00
Mario
fa8fb9e73f more lockview ui improvements 2022-01-03 11:00:14 +00:00
Mario
f6093872ec minor usability improvement 2022-01-03 09:35:42 +00:00
Mario
e8030e29d9 remove logging 2022-01-02 20:46:44 +00:00
Mario
df8bb0596a port new_token from zap, fixes and more cleanup 2022-01-02 20:45:25 +00:00
Mario
0003e0b8a5 lockview: fix guest links for profile groups and photos, cleanup 2022-01-02 19:33:10 +00:00
Mario
e42703d557 lockview: provide guest links for private resources 2022-01-02 08:49:36 +00:00
Mario
4636e56395 minor theme fixes 2021-12-29 18:45:03 +00:00
Mario
27ebeffad4 update_poll() can be called many times in a row for the same item if a multiple poll is being updated. This could result in the queueworker not processing duplicates. We are now adding the source item mid to the notifier call as the third argument (fragment) so that the queueworker will not think they are duplicates. The fragment is also passed to the deliver_hooks call in the notifier 2021-12-22 09:50:50 +00:00
Mario
07110cee17 add the title to the object 2021-12-21 09:58:07 +00:00
Mario
afa1f1416b string change 2021-12-21 09:20:53 +00:00
Mario
f8dfcab0ca string change 2021-12-21 09:20:21 +00:00
Mario
e14fd920d6 version 2021-12-21 09:19:07 +00:00
Mario
8c10fdae5b missing label 2021-12-21 09:14:48 +00:00
Mario
eee027d9ff Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-12-21 09:09:43 +00:00
Mario
1b1fb5d26a improve pconfig sync at the sending side 2021-12-21 09:08:36 +00:00
Mario Vavti
c36e0805d8 improve pconfig sync at the receiving side 2021-12-21 10:04:51 +01:00
Mario
5c56041185 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-12-18 19:45:42 +00:00
Mario
5aefe0b74f guest token xchan_network = "token" and remove permission checks since the guest tokens are now added to the abook automatically 2021-12-18 19:09:15 +00:00
Max Kostikov
20e0359efd Merge branch 'dev' into 'dev'
Update Russian translation

See merge request hubzilla/core!1995
2021-12-17 22:42:36 +00:00
Max Kostikov
9c790e5a90 Update Russian translation 2021-12-18 00:39:47 +02:00
Mario
9c79b5be77 version 2021-12-17 21:10:00 +00:00
Mario
2d9a4f4e42 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-12-17 21:08:54 +00:00
Mario
565602538c main.js simplify notify_id checks 2021-12-17 21:08:20 +00:00
Mario Vavti
78972725ae mod tokens cleanup and fixes 2021-12-17 22:05:45 +01:00
Mario
5ab90f7791 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-12-17 20:29:06 +01:00
Mario
b90d98fc2b implement background deleting of items in contact_remove() 2021-12-17 20:26:36 +01:00
Mario
eca3ae393b daemon to delete abbok items in the background 2021-12-17 19:25:28 +00:00
Mario
2bd69495d2 missing file 2021-12-17 19:52:54 +01:00
Mario
bfd3da43ac access token refactor 2021-12-17 19:48:09 +01:00
Mario
32a9eaf3b6 update db schemas 2021-12-17 15:30:26 +01:00
Mario
91cea1f28a add template 2021-12-17 15:01:25 +01:00
Mario
220ed35f58 implement contact role deletion 2021-12-17 14:59:25 +01:00
Mario
b1cf5d4e44 nag channel owners to select achannel role if they have not yet done so yet 2021-12-15 12:58:33 +00:00
Mario
fe330ec1bb bump version 2021-12-15 12:18:07 +00:00
Mario
2968bf8241 merge branch perms_ng into dev 2021-12-15 12:17:19 +00:00
Mario Vavti
a40babbf0d version 6.4.2 2021-12-14 11:12:43 +01:00
Mario Vavti
7822257e1c Merge branch 'dev' 2021-12-14 11:11:57 +01:00
Mario Vavti
b37165c62b changelog 2021-12-14 11:09:27 +01:00
Mario Vavti
5e9d267959 mod sse_bs: when processing returned mids, do not assume they are b64 encoded 2021-12-14 11:04:26 +01:00
Mario Vavti
1a1e6b6810 Announce missing in is_response_activity() 2021-12-11 10:56:50 +01:00
Mario Vavti
88140002e7 Merge branch 'dev' 2021-12-03 16:26:10 +01:00
Mario Vavti
efc203d958 fix blured profile images and pdl files 2021-12-03 16:25:42 +01:00
Mario Vavti
42d4cdcc39 Merge branch 'dev' 2021-12-03 15:13:57 +01:00
Mario Vavti
fd433b3eb6 main_width in rem 2021-12-03 15:10:59 +01:00
Mario Vavti
7483adb8ad Merge branch 'dev' 2021-12-03 14:55:39 +01:00
Mario Vavti
45fd462f80 fix content width for dark schema 2021-12-03 14:54:47 +01:00
Mario Vavti
807003adf7 version 6.4.1 2021-12-03 13:47:58 +01:00
Mario Vavti
1b0a17c7db Merge branch 'dev' 2021-12-03 13:46:41 +01:00
Mario Vavti
60b145833c changelog and version 2021-12-03 13:45:19 +01:00
Mario Vavti
39458b2ba8 fix hubloc_site_id in fix_system_urls() on detected site rename events and during sync_locations() if it changed or was stored incorrectly. 2021-11-30 10:50:31 +01:00
Mario Vavti
5de38b3632 mod channel: lookup zotinfo based on hash instead of address 2021-11-29 11:26:29 +01:00
Mario Vavti
6ced3426cf do not deliver to the same channel multiple times in case duplicate hubloc entries for the channel exist 2021-11-29 11:17:14 +01:00
Mario
43460c9d19 re-add css that was removed by accident 2021-11-26 19:29:43 +00:00
Mario
ca17fb01bc profile cleanup and fixes 2021-11-25 07:54:53 +00:00
Mario
a6f65aa9c5 add source option so that the right makros will be used in attach_store() 2021-11-25 07:44:31 +00:00
Mario
ae9a7727d6 maximum width of content region is now calculated in rem 2021-11-24 20:47:18 +00:00
Mario
3ac5d5257b fix issue where likes notices are emited allthough they are actually disabled 2021-11-24 20:19:35 +00:00
Mario
668d7c73ed address issue #1651 (reload page after comment or like) 2021-11-24 20:01:16 +00:00
Mario
c95f708c91 port httpmeta from zap 2021-11-24 09:08:11 +00:00
Mario
06e214e567 more work on responsive aside 2021-11-23 09:17:04 +00:00
Mario
18f8cafee0 minor vcard fixes 2021-11-21 20:17:14 +00:00
Mario
6bd6afac05 streamline profile vcard with xchan vcard 2021-11-21 19:50:36 +00:00
Mario
fe7ecede70 Merge branch '6.4RC' 2021-11-09 09:10:19 +00:00
Mario
089708ab9f version 6.4 2021-11-09 09:08:52 +00:00
Mario
daa844c038 Merge branch 'dev' into 6.4RC 2021-11-09 09:07:55 +00:00
Mario
4049992228 update changelog 2021-11-09 09:07:37 +00:00
Mario
7c576c91b7 Merge branch 'dev' into 6.4RC 2021-10-30 09:08:32 +00:00
Mario
17bd364614 remove logging 2021-10-30 09:07:56 +00:00
Mario
25ffd39519 Merge branch 'dev' into 6.4RC 2021-10-30 09:05:24 +00:00
Mario
acfa527e3e css fixes 2021-10-30 09:04:50 +00:00
Mario
b512416cb3 fix version 2021-10-28 14:17:53 +00:00
Mario
bd116c53a1 update changelog 2021-10-28 14:14:20 +00:00
Mario
1251fca256 remove mcrypt from the docs 2021-10-27 18:42:25 +00:00
Mario
b2fe21709c update sbom 2021-10-27 12:13:47 +00:00
Mario
c082d12b59 bump dev version 2021-10-27 08:11:09 +00:00
Mario
9a4ca44255 version and strings 2021-10-27 08:05:57 +00:00
Mario
6fce9a41b0 remove logging 2021-10-25 08:12:17 +00:00
Mario
65acdd7b15 mod regate: auto-connect the invitee with the inviter if auto channel create is enabled (default). fix issue where the default group was not set in the return array of create_identity() 2021-10-25 08:03:12 +00:00
Mario
a209374cbd invite: fix variable name in template and do not substitute the Â@ in the webfinger address with @+ 2021-10-22 09:52:30 +00:00
Mario
c1bb87db98 mod item: cleanup and remove some unused variables 2021-10-22 08:16:19 +00:00
Mario
8bae40449f remove library/urlify and use vendor/jbroadway/urlify instead 2021-10-22 08:07:19 +00:00
Mario
bc3bb4694a mod import: formating 2021-10-22 07:50:35 +00:00
Mario
22588e58f3 install urlify via composer 2021-10-22 07:46:30 +00:00
Mario
69ba4eb055 whitespace 2021-10-22 07:27:37 +00:00
Mario
687b9fb6a2 comment out warning about db version differences - it is not relevant 2021-10-22 07:26:30 +00:00
Mario
9b9ca9695c import_items: cleanup 2021-10-21 10:36:31 +00:00
Mario
6357c69868 import_items: provide a possibility to import exported zip files by year 2021-10-21 10:29:44 +00:00
Mario
15cb7ab7a1 nativeWikiPage: more whitespace and cleanup 2021-10-20 19:54:59 +00:00
Mario Vavti
2c741bd24d fix for issue #1640 - use item_store() instead of post_activity_item() which is checking for post_comment permission which we might not have in this case. item_store() requires slightly more data but basically does the same. Also some minor improvements and whitespace changes. 2021-10-20 21:35:42 +02:00
Mario
3f72a3beb6 fix xchan vcard rendering 2021-10-20 09:57:45 +00:00
Mario
42de18d96d fix dutch registration email verification email template
(cherry picked from commit c7515b8687)
2021-10-20 10:09:19 +02:00
Mario
4bdbdab399 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-10-20 08:08:09 +00:00
Mario
c7515b8687 fix dutch registration email verification email template 2021-10-20 08:07:06 +00:00
Mario
c79e39a488 improve code comments 2021-10-20 08:06:29 +00:00
Mario
d639104b71 invite: use the actual set language and check if we have a template for it
(cherry picked from commit c66a5ba732)
2021-10-18 21:44:06 +02:00
Mario
c66a5ba732 invite: use the actual set language and check if we have a template for it 2021-10-18 21:41:08 +02:00
Mario
79f9b49dd7 provide tags indicating the supported protocols in the actor object and probe for zot6 if appropiate 2021-10-18 07:53:45 +00:00
Mario
8b542c250a mod invite: skip the pre-check for valid email 2021-10-16 20:07:34 +00:00
Mario
55237683d2 xrd whitespace 2021-10-16 19:24:58 +00:00
Mario
27401794e1 rename functions after heavy lifting and expand custom sections to all possible sections 2021-10-16 18:10:23 +00:00
Mario
862a7c2dba manifest: remove orientation so that os default will be used and add default theme_color 2021-10-16 14:03:35 +00:00
Mario
bb31a4620e notes: provide translateable strings 2021-10-15 19:30:38 +00:00
Mario
7aaade8b23 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-10-15 19:17:31 +00:00
Mario
a622f533ad some heavylifting on manual item export 2021-10-15 19:17:06 +00:00
Max Kostikov
0dd27dabd6 Merge branch 'dev' into 'dev'
Update Russian translation

See merge request hubzilla/core!1994
2021-10-15 15:08:16 +00:00
Max Kostikov
8ab464acf2 Update Russian translation 2021-10-15 16:55:21 +02:00
Mario
db18438db2 escape_tags only once 2021-10-15 08:15:41 +00:00
Mario
f885f98611 use the proprt syntax 2021-10-14 18:59:41 +00:00
Mario
9b8b85545f Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-10-14 18:16:27 +00:00
Mario
532b479f96 provide local copies of the w3.org jsonld documents - addresses issue #1637 2021-10-14 18:15:38 +00:00
Mario
422dfca6d7 fix cacert missing some certificates after last update 2021-10-14 18:13:02 +00:00
Mario
c3d1474f59 Merge branch 'dev' into 'dev'
Support IDNA URLs embedding

See merge request hubzilla/core!1990
2021-10-14 13:16:18 +00:00
Max Kostikov
99873504e4 Support IDNA URLs embedding 2021-10-14 13:16:16 +00:00
Mario
138a67298d version 2021-10-13 11:36:18 +00:00
Mario
aca1551e86 implement AS representation of photos and albums, cleanup and minor fixes 2021-10-13 09:23:59 +00:00
Mario
ca32850a32 fix image object as per AS2 2021-10-12 20:06:11 +00:00
Mario
ba6f069997 HTTPSig: do not query for hubloc_addr 2021-10-12 19:05:21 +00:00
Mario
c6c6b52ccd notes: minor css fix 2021-10-12 18:59:52 +00:00
Mario
96c334e730 bbcode for notes app 2021-10-12 11:27:36 +00:00
Mario
3e503ec3a3 Revert "httpsig: add parentheses"
This reverts commit e455fae334.
2021-10-12 11:25:44 +00:00
Mario
e455fae334 httpsig: add parentheses 2021-10-12 11:25:24 +00:00
Mario
29f3dc2fa3 notifications_widget: fix regression hiding the #nav- * -sub element when there are no more notifications 2021-10-11 09:12:05 +00:00
Mario
aa41b16757 look for hubloc_id_url or hubloc_hash, otherwise we will always fetch the key from the net on platforms where those are different (e.g. mastodon). 2021-10-11 07:41:12 +00:00
Mario
f4d59abe41 streamline logic 2021-10-10 21:13:30 +00:00
Mario
18de58fd8b HTTPSig: cleanup, add some doco and implement missing force mechanism for fetching keys 2021-10-10 21:00:22 +00:00
Mario
4c2b188f8b if we do not have a display path, we are looking at the root directory 2021-10-10 18:16:13 +00:00
Mario
08f65420f4 messages widget: show user-plus icon for connection requests 2021-10-10 09:49:12 +00:00
Mario
b90228b319 make sure we do not select removed channels as importer in onepoll 2021-10-10 08:37:44 +00:00
Mario
ad2c165f26 bbcode: deal with codeblocks before we escape other tags 2021-10-10 08:10:49 +00:00
Mario
af5218593a update composer libs 2021-10-10 07:59:31 +00:00
Mario
f19acd9f50 remove redundant variable and provide missing phpdoc 2021-10-10 07:56:42 +00:00
Mario
59940e7f05 make sure to not include removed channels in xrd or webfinger queries 2021-10-09 19:46:27 +00:00
Mario Vavti
094536e633 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-10-09 20:08:23 +02:00
Mario Vavti
4f2a439873 mod import: only run automatic content and files import if api version is compatible 2021-10-09 20:08:11 +02:00
Mario
63bdab2b5f use Libzot::fetch_conversation to fetch conversations from search and add an optional force argument to process_delivery 2021-10-09 15:00:21 +00:00
Mario
14733f8482 more bs5 fixes 2021-10-09 08:58:11 +00:00
Mario
b830bbd084 remove hz_syslog and deal with intro notifications in the messages widget 2021-10-08 17:35:36 +00:00
Mario
c1894c5a39 bump version 2021-10-08 13:01:09 +00:00
Mario
e91e488e1f Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-10-08 12:26:08 +00:00
Mario
e6dac085cb update composer libs 2021-10-08 12:24:19 +00:00
Mario
5023a5b56b Merge branch 'Aksel-dev-patch-31902' into 'dev'
German roles.bb

See merge request hubzilla/core!1992
2021-10-06 15:22:43 +00:00
Aksel K
32d37d1178 Aktualisieren doc/de/roles.bb 2021-10-06 15:12:55 +00:00
Aksel K
848221649e Neue Datei hochladen 2021-10-06 14:56:01 +00:00
Mario
f5f357060b fix alt_pager() 2021-10-06 14:32:49 +00:00
Mario
98eea41865 fix drop_query_params() if no query params are left 2021-10-06 14:32:25 +00:00
Mario
8ac529f5ae simplify 2021-10-06 08:43:40 +00:00
Mario
b5fed08dd4 really de-duplicate entries for dead hubs 2021-10-06 08:33:10 +00:00
Mario
9bfcaf2669 do not show duplicate entries for dead hubs 2021-10-06 08:05:16 +00:00
Mario Vavti
af05ee7e1c Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-10-06 09:40:15 +02:00
Mario
3918439020 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-10-06 07:39:34 +00:00
Mario
3b71e115a4 implement sync logic in mod appman 2021-10-06 07:39:10 +00:00
Mario Vavti
c33660a015 move sync logic for apps to mod appman. this way we can re-use the functions without creating sync loops. 2021-10-06 09:36:14 +02:00
Max Kostikov
7963d4cb8f Merge branch 'ab-dev' into 'dev'
Polish translation: fixes and updates

See merge request hubzilla/core!1989
2021-10-05 18:27:42 +00:00
Mario
16281e0e7f disable app sync due to a possible loop 2021-10-04 19:16:38 +00:00
Mario Vavti
72c58e60d7 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-10-04 20:32:32 +02:00
Mario Vavti
4b48ff2868 also sync the undestroy action 2021-10-04 20:32:19 +02:00
Mario
8e212d30d0 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-10-04 18:21:08 +00:00
Mario
b9ae396e74 unset id before syncing 2021-10-04 18:20:51 +00:00
Mario Vavti
3a38946f8a more app sync 2021-10-04 20:19:16 +02:00
Andrzej Budziński
d0d3a5454e Polish translation: fixes and updates 2021-10-04 19:24:16 +02:00
Mario Vavti
04c6d77d2c set the sync flag to true 2021-10-04 14:14:30 +02:00
Mario Vavti
c2c5730d00 more app sync fixes 2021-10-04 14:08:39 +02:00
Mario Vavti
21a6dffd5f Revert "more app sync fixes"
This reverts commit 7430989212.
2021-10-04 13:54:45 +02:00
Mario Vavti
7430989212 more app sync fixes 2021-10-04 13:41:54 +02:00
Mario Vavti
2e26a13f81 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-10-04 13:31:30 +02:00
Mario Vavti
404ebd4d5e app sync fixes - part 2 2021-10-04 13:31:26 +02:00
Mario
11ea7bf0fc app sync fixes - part 1 2021-10-04 11:25:52 +00:00
Mario
6da7fe7d27 provide system app sync 2021-10-04 09:24:13 +00:00
Mario
538e540531 commment out deprecated code 2021-10-04 08:46:56 +00:00
Mario
53138f4b09 fix typo 2021-10-04 08:32:36 +00:00
Mario
3d71367f30 add pem 2021-10-04 08:31:00 +00:00
Mario
bb52ff9b4b fix site lookup and minor cleanup 2021-10-04 08:28:57 +00:00
Mario
ab5b82221c update certs 2021-10-03 18:24:26 +00:00
Mario
5c3b89a68b mod locs: do not show drop icon for local clones and get rid of redundant for loop 2021-10-03 17:48:00 +00:00
Mario
da923d7749 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-10-03 16:54:04 +00:00
Mario
55d905fdd9 clone channel delete issues - part 2 2021-10-03 16:53:48 +00:00
Mario Vavti
4ba70a3fae clone channel delete issues - part 1 2021-10-03 18:52:14 +02:00
Mario
a5835b0e85 disable pg tests 2021-10-03 12:59:10 +00:00
Mario
ed4e5c9bcf version 6.2.2 2021-10-03 12:40:48 +00:00
Mario
d8793de629 make sure we have a sender here
(cherry picked from commit 0722188ea6)
2021-10-03 14:38:59 +02:00
Mario
f45cb38cd3 make sure to return if we have no xchan here
(cherry picked from commit d6f81e139a)
2021-10-03 14:38:29 +02:00
Mario
0722188ea6 make sure we have a sender here 2021-10-03 12:36:17 +00:00
Mario
d6f81e139a make sure to return if we have no xchan here 2021-10-03 12:22:33 +00:00
Mario
58ee147653 fix typo 2021-10-03 08:20:16 +00:00
Mario
28ad6a6883 remove redundant query and exit with status 410 if channel was removed 2021-10-03 07:18:49 +00:00
Mario
9de8aefa98 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-10-03 07:11:27 +00:00
Mario
66c273ae8d channel_purge: raise limit by factor of 10 2021-10-03 07:11:12 +00:00
Mario Vavti
b27fbf209e Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-10-03 09:05:54 +02:00
Mario Vavti
4afd1ac705 add optional $removed argument to channelx_by functions to allow inclusion of removed channels which is required (mod channel, daemon notifier -> refresh_all) if a channel got removed also remove caching to App so we always get a fresh copy. In import_hublocs() add site_id to the array passed to Libzot::gethubs() because it is expected there. 2021-10-03 09:05:32 +02:00
Mario
d556ef59e6 sigh... 2021-10-02 14:09:55 +00:00
Mario
81e972b85c another try on pg test 2021-10-02 14:02:58 +00:00
Mario
3bb04cc323 nope - disable pg test until the issue is resolved 2021-10-02 13:28:35 +00:00
Mario
9ff43f081f another try to fix pg test 2021-10-02 13:23:44 +00:00
Mario
8c014e3b6b see if this fixes pgsql test issue 2021-10-02 13:15:17 +00:00
Mario
d8378a17c9 nav move header outsite of container - fixes app sticking above header when sorting 2021-10-02 13:04:10 +00:00
Mario
574a01727e fix removed channels counted for max id check and disable moving until we decide what to do with it 2021-10-02 12:56:35 +00:00
Mario
b5cea3301d cleanup api_auth and make it fetch the identity if we do not have it cached yet 2021-10-02 12:28:13 +00:00
Mario Vavti
9346a06f35 also check for vnotify 2021-10-01 22:48:09 +02:00
Mario Vavti
250e917c6e only show sse pubs if the app is installed 2021-10-01 22:44:26 +02:00
Mario Vavti
7b1cd37cd6 only bootstrap pubs if the app is installed 2021-10-01 22:30:00 +02:00
Mario Vavti
47e83a15c1 import_progress: deal with the situation where items/files are being imported but there are none to import 2021-10-01 21:52:30 +02:00
Mario
597e847a3b css fixes 2021-10-01 17:17:02 +00:00
Mario Vavti
47f3b41d5e remove redundant notice 2021-10-01 19:15:39 +02:00
Mario Vavti
e7f4c1ffd1 missing template class logic 2021-10-01 18:10:32 +02:00
Mario Vavti
9a87b8bf1b only allow resume if we are not completed yet 2021-10-01 17:24:19 +02:00
Mario Vavti
dac27aab68 remove logging 2021-10-01 17:11:14 +02:00
Mario Vavti
069a5429c9 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-10-01 17:09:54 +02:00
Mario Vavti
b1eaa810ce improve channel import progress page 2021-10-01 17:09:36 +02:00
Mario
e5e3c268a2 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-10-01 07:14:37 +00:00
Mario
22dff49673 improve file upload performance: start uploading next file only after the previous finished, make sure to not return when uploading via ajax 2021-10-01 07:14:05 +00:00
Max Kostikov
591905c282 Merge branch 'dev' into 'dev'
Fix possible storage conversion stuck on file save error

See merge request hubzilla/core!1988
2021-09-30 20:45:02 +00:00
Mario Vavti
6ed160e4fa wording 2021-09-30 17:50:36 +02:00
Mario Vavti
d462230b82 minor display change 2021-09-30 17:43:29 +02:00
Mario
e48ed9d06d Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-09-30 15:38:49 +00:00
Mario Vavti
6236869ebe implement file totals and add mod import_progress 2021-09-30 17:34:30 +02:00
Mario
2c7c9ae2d7 provide files total 2021-09-30 15:33:10 +00:00
Mario Vavti
b9b4e71f7d provide a very simple status page for content import 2021-09-30 12:25:03 +02:00
Mario Vavti
b0bf646d71 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-09-30 12:10:11 +02:00
Mario Vavti
5cb5ecdb54 implement channel purge daemon and send a notifier purge_all message if the xchan was deleted 2021-09-30 12:09:50 +02:00
Mario Vavti
44fa5ac9a1 add channel purge daemon 2021-09-30 12:06:28 +02:00
Max Kostikov
9a19f7eac9 Fix possible storage conversion stuck on file save error 2021-09-29 23:01:27 +02:00
Mario
af0896bb8b a possible fix for the nested list test 2021-09-29 20:57:16 +00:00
Mario
817237ef77 composer update league/html-to-markdown 2021-09-29 20:36:32 +00:00
Mario Vavti
fbefff6eed Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-09-29 21:47:36 +02:00
Mario Vavti
4ba47698d7 revise content import/export part 2 2021-09-29 21:47:12 +02:00
Mario
2688abf25a revise content import/export part 1 2021-09-29 19:43:22 +00:00
Mario
5eb79bd51e importer daemons: do not call with zap_compat flag and use return instead of kill so that queueworker can go on 2021-09-27 21:58:26 +00:00
Mario
d3f5f778a4 cleanup mod import and implement importer daemons ported from zap 2021-09-27 20:49:37 +02:00
Mario
3eeb2b0ee4 add importer daemons ported from zap 2021-09-27 18:37:09 +00:00
Mario
230a1919dd add outbox 2021-09-27 18:36:04 +00:00
Mario
14004fbf7f support un-starring of apps in app bin 2021-09-27 11:13:16 +00:00
Mario
73e8af98f2 fix notification panel collapsed state not saved if closed manually 2021-09-27 07:01:33 +00:00
Mario
0117a0019b make sure to also include ap hublocs here. we will select zot6 later in the function if present 2021-09-26 18:10:34 +00:00
Mario
35ff8781f0 always promote the outbox 2021-09-26 12:15:14 +00:00
Mario
2d17442f28 externals: if dealing with AP profiles also fetch comments. there is no way to fetch conversations later 2021-09-25 10:17:45 +00:00
Mario
5c179522bb bring back externals (slightly different approach), rename zotfeed to outbox for consistency wit AP naming. warning: this commit requires update of addons! 2021-09-25 09:03:16 +00:00
Mario
b35d95da52 dismiss deleted xchans in query 2021-09-25 08:47:39 +00:00
Mario
feca5afaa5 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-09-23 20:43:49 +00:00
Mario
9cb5274d30 add zot6 specific handling to onepoll 2021-09-23 20:43:37 +00:00
Mario Vavti
2870fd46da Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-09-23 21:54:12 +02:00
Mario Vavti
dff8ef91a6 implement the top option in items_fetch 2021-09-23 21:52:27 +02:00
Mario
0588975e37 Ãfix wrong variable name and streamline icon with unseen notifications icon 2021-09-23 14:59:40 +00:00
Mario
e0600b241a make sure we do not mix up likes on direct messages and commments on direct messages in notices 2021-09-23 12:45:55 +00:00
Mario
d19aa8fb3b make sure entries is initialized 2021-09-23 11:17:45 +00:00
Mario
989a4f3d49 add notices tab to HQ widget 2021-09-23 10:42:37 +00:00
Mario
2a2c4d3e9c fix bs regression 2021-09-23 08:50:44 +00:00
Mario
a451449766 Revert "composer update bootstrap to version 5.1.1"
This reverts commit 89e4006b2d.
2021-09-23 08:33:36 +00:00
Mario
3347fab105 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-09-22 16:16:50 +00:00
Mario
33a6c92629 version 2021-09-22 16:16:35 +00:00
Mario
0707d33493 bootstrap update fixes 2021-09-22 16:14:28 +00:00
Mario
89e4006b2d composer update bootstrap to version 5.1.1 2021-09-22 06:38:27 +00:00
Mario Vavti
4eb8921635 improve item_url_replace() - fixes #1507 2021-09-21 11:07:23 +02:00
Mario
26ac452c96 mod manage: do not query info which we do not use in the UI and probably should not due to performance considerations 2021-09-21 07:40:00 +00:00
Mario
7122e1522a perform profile sync after all the fields are updated otherwise we will sync outdated data 2021-09-21 07:33:02 +00:00
Mario
5497adfde6 add option to mark all notices of a thread read if a notice of the thread is clicked (default 1) and fix a php error in find_parent() if $act->obj is not an array 2021-09-18 18:06:32 +00:00
Mario
d4c2e50285 changelog and version 2021-09-16 09:50:08 +00:00
Mario
7ba58208f2 version 6.2.1 and changelog 2021-09-16 08:04:59 +00:00
Mario
cc83677711 Merge branch 'master' of https://framagit.org/hubzilla/core 2021-09-16 07:49:43 +00:00
Mario
c28cce1b54 Merge branch 'dev' 2021-09-16 07:48:13 +00:00
Mario
9052695a13 typo 2021-09-15 11:03:19 +00:00
Mario
46b8db53ab provide a get_cached_actor_provider hook and improve the author/owner handling in Libzot::import() 2021-09-15 10:59:16 +00:00
Mario
0b716b3cc7 fix $desturl set to wrong value (null) 2021-09-13 11:36:41 +00:00
Mario
d115e09abc do not process summary in cleanup_bbcode() fixes issue #1612 2021-09-12 17:54:20 +00:00
Mario
0f803aa3ae when updating the channel name from profiles make sure to lookup the xchan entry by xchan_hash since xchan_url is set to the primary location but we might be updating from a clone
(cherry picked from commit e5dc3c05df)
2021-09-10 14:34:21 +02:00
Mario
e5dc3c05df when updating the channel name from profiles make sure to lookup the xchan entry by xchan_hash since xchan_url is set to the primary location but we might be updating from a clone 2021-09-10 12:29:05 +00:00
Mario
1cfe5c3e16 fix spacing issue for collapsed pinned apps with an image
(cherry picked from commit e2d0269b5c)
2021-09-10 10:12:39 +02:00
Mario
e2d0269b5c fix spacing issue for collapsed pinned apps with an image 2021-09-10 08:11:19 +00:00
Mario
b95c61d2c2 fix language selector reloading the page if not clicking the icon exactly and bs5 modal issues
(cherry picked from commit 7b0f8f2896)
2021-09-08 21:50:25 +02:00
Mario
7b0f8f2896 fix language selector reloading the page if not clicking the icon exactly and bs5 modal issues 2021-09-08 19:48:42 +00:00
Mario
25a81ea500 update release date 2021-09-08 07:50:57 +00:00
Mario
4c5f0a05c7 Merge branch '6.2RC' 2021-09-08 07:43:40 +00:00
Mario
977a55eb84 version 6.2 2021-09-08 07:42:44 +00:00
Mario
8ec001c87b Merge branch 'dev' into 6.2RC 2021-09-07 10:22:07 +00:00
Mario
ddbc55d166 fix mod display regressions 2021-09-07 10:21:02 +00:00
Mario
9a3a0d94ea Merge branch 'dev' into 6.2RC 2021-09-07 09:29:14 +00:00
Mario
1d3a59e0cd resolve some vsprintf issues 2021-09-07 09:26:06 +00:00
Mario
ad7c84eda7 Merge branch 'dev' into 6.2RC 2021-09-07 07:36:53 +00:00
Mario
fe62b245ca update changelog 2021-09-07 07:34:59 +00:00
Mario
6084360588 deprecate the custom highlight [hl] bbcode in favor of [mark] which is a html5 standard 2021-09-07 07:33:36 +00:00
Mario
52995bde12 deprecate the custom highlight [hl] bbcode in favor of [mark] which is a html5 standard 2021-09-07 07:32:49 +00:00
Mario
0f54b26e9d bump version 2021-09-06 19:26:30 +00:00
Mario
2523ebc76a version 6.2RC1 2021-09-06 19:24:45 +00:00
Mario
c1ce211b56 Merge branch 'dev' into 6.2RC 2021-09-06 19:22:39 +00:00
Mario
1aa7826331 strings update 2021-09-06 19:22:04 +00:00
Mario
29a1556541 more changelog 2021-09-06 19:17:24 +00:00
Mario
93f48aa805 update changelog 2021-09-06 19:13:30 +00:00
Mario
95367a8267 if posting from hq return to the message we just posted 2021-09-06 10:19:37 +00:00
Mario
97ef781a0f fix post mail check in Activity::create_note() 2021-09-06 09:38:41 +00:00
Mario
81351d2952 update strings 2021-09-06 09:29:23 +00:00
Mario
8d28649e1b check the post_mail permission for direct messages 2021-09-06 09:10:19 +00:00
Mario
9495fef79b fix anon comments for cards and articles 2021-09-05 11:46:52 +00:00
Mario
de02d4c04b do not save collections in a separate xconfig anymore 2021-09-05 11:16:20 +00:00
Mario
18cd3926d7 omit deleted hublocs in get_actor_hublocs() and use Activity::get_actor_collections() to get collections. Fallback to xconfig->collections if Activity::get_actor_collections() does not return anything yet. 2021-09-05 11:11:51 +00:00
Mario
0e1e1cda7a fix regressions in mod hq 2021-09-04 20:18:59 +00:00
Mario
b3f2374b57 work around some weird regex interference 2021-09-04 19:46:17 +00:00
Mario
793881b9f9 more gen_link_id() 2021-09-04 08:30:04 +00:00
Mario
529824d010 more unpack_link_id() 2021-09-04 08:18:41 +00:00
Mario
c47e21f3a7 refactor actor_store and actor cache part 1 2021-09-04 07:37:49 +00:00
Mario
d83c013bec Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-09-04 07:36:28 +00:00
Mario
17220b2465 implement unpack_link_id() in mod channel 2021-09-04 07:34:09 +00:00
Mario
5dcf053b4c implement strict mode for base64url_decode() and introduce unpack_link_id() 2021-09-04 07:32:01 +00:00
Max Kostikov
a11fe8c6c6 Merge branch 'dev' into 'dev'
Update Russian translation

See merge request hubzilla/core!1987
2021-09-01 20:09:21 +00:00
Max Kostikov
70370407ad Fix index in Russian plurals 2021-09-01 22:05:50 +02:00
Max Kostikov
7973f11cd7 Fix Russian plurals 2021-09-01 22:02:20 +02:00
Max Kostikov
44371c9adf Update Russian translation 2021-09-01 21:36:16 +02:00
Mario
3d40ea7f44 version 2021-09-01 19:33:14 +00:00
Mario
8a3446c021 missing file 2021-09-01 19:31:09 +00:00
Mario
6a8cc313da bump version 2021-09-01 18:33:10 +00:00
Mario
7a1c72d5a4 composer dump autoload 2021-09-01 18:18:57 +00:00
Mario
4e7525c355 version and strings 2021-09-01 18:17:01 +00:00
Mario
e20a2752d6 add an optional force flag to actor_store() 2021-08-30 18:03:54 +00:00
Mario
e25558e24d improve icon lookup 2021-08-30 15:36:12 +00:00
Mario
ada7d4eef5 Merge branch 'owafix' into 'dev'
OWA: very difficult to trace failures due to empty public key record. The...

See merge request hubzilla/core!1986
2021-08-30 11:08:40 +00:00
Mario
3fb4077672 Merge branch 'photodir' into 'dev'
file is stored in wrong directory (/) if uploaded using photo module and it...

See merge request hubzilla/core!1985
2021-08-30 07:56:00 +00:00
Zot
5b73cee0d8 file is stored in wrong directory (/) if uploaded using photo module and it... 2021-08-30 07:56:00 +00:00
nobody
8343f63964 OWA: very difficult to trace failures due to empty public key record. The signature might succeed because an empty key triggers an external key fetch. But the empty key cannot encrypt the token. This has been observed in the wild on a number of sites/projects. 2021-08-29 04:54:50 -07:00
Mario
5532560d07 do not define colors in manifest (system colors are mostly the better fit) and use profile fullname instead of channel_name in nav 2021-08-29 10:51:44 +00:00
Mario
ed277dbda9 more app descriptions and remove some unused images 2021-08-28 17:57:06 +00:00
nobody
2866c0b173 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-08-28 01:09:11 -07:00
Mario
5eaabbdb18 slightly improve push notification handling for HQ and some app descriptions 2021-08-27 18:41:52 +00:00
Mario
d24fbb51fc adjust background color 2021-08-26 18:27:38 +00:00
Mario
6e4c9d684d port latest pwa work from zap 2021-08-26 18:03:17 +00:00
Mario
3ff184f8bb whitespace 2021-08-26 11:57:50 +00:00
Mario
a68b5f9de4 more app descriptions 2021-08-26 10:28:38 +00:00
Mario
d5bf42faf0 Merge branch 'dev' into 'dev'
issue 1599

See merge request hubzilla/core!1984
2021-08-26 08:38:42 +00:00
Zot
88b13658a7 issue 1599 2021-08-26 08:38:41 +00:00
nobody
05152ac8c8 issue 1599 - import_author_zot failing if primary is both dead and unknown 2021-08-25 19:15:46 -07:00
nobody
aa2106f949 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-08-25 19:13:31 -07:00
Mario
6261d0826c db update 1248 to clean up possible bogus entries in xconfig and remove gnusoc from app 2021-08-25 15:54:26 +00:00
Mario
2e7a915ee8 add appstore widget to appman 2021-08-25 10:19:20 +00:00
Mario
0081bafab2 more app descriptions 2021-08-25 08:56:34 +00:00
Mario
64b59b4358 capitalize widget titles 2021-08-25 06:56:45 +00:00
Mario
19f9bbcad4 nav: fix minor display issue and add some code duplication for better readability 2021-08-25 06:37:14 +00:00
Mario
f399528055 more app descriptions and change the image counter to display % of images loaded instead of loaded images count 2021-08-24 18:50:19 +00:00
Mario
fea3980c01 channel manager -> channels 2021-08-24 09:03:09 +00:00
Mario
8804499cb7 channel_menu is not used anymore 2021-08-24 08:41:02 +00:00
Mario
fa1878fda1 nav cleanup 2021-08-24 08:37:51 +00:00
Mario
b129d74a38 affinity needs a version bump to pick up the description 2021-08-23 11:42:53 +00:00
Mario
189da4fdc1 untangle the app template into separate templates and fix bbcode view 2021-08-23 10:32:48 +00:00
Mario
824894baf0 more app descriptions and return to the app if installed from the module itself 2021-08-23 07:59:37 +00:00
Mario
2bd4f7384e more app descriptions 2021-08-22 18:56:04 +00:00
Mario
1c44b37cb0 rename variable 2021-08-22 18:14:16 +00:00
Mario
ab0da7db13 use the slightly altered app_render() function instead of a separate function 2021-08-22 17:55:38 +00:00
Mario
052633d570 improve documentation 2021-08-22 10:13:25 +00:00
Mario
3bb71a6ba8 infrastructure to provide an app install widget for modules and make the bookmark app use it 2021-08-22 09:20:40 +00:00
Mario
7093b66b76 fix typo 2021-08-21 08:30:13 +00:00
Mario
168010a32c remove deprecated forum term type and re-introduce bookmark term type 2021-08-21 08:26:46 +00:00
Mario
6eb84a3d9a restructure apps to make space for app descritions 2021-08-21 08:25:15 +00:00
Mario
69d909596a only redirect to hq if local 2021-08-17 18:37:19 +00:00
Mario
dd296e1aaa more legacy mail cleanup - issue #1595 2021-08-17 18:18:52 +00:00
Mario
c3bbc35e84 more bs5 fixes 2021-08-17 18:07:30 +00:00
Mario
952407363e make sure we have a path before running getimagesize() on it
(cherry picked from commit a2403042c2)
2021-08-17 09:59:03 +02:00
Mario
2deb75de8d remove redundant closing div tag
(cherry picked from commit 87cf2039ad)
2021-08-17 09:58:42 +02:00
Mario
a2403042c2 make sure we have a path before running getimagesize() on it 2021-08-17 07:53:07 +00:00
Mario
87cf2039ad remove redundant closing div tag 2021-08-16 19:36:47 +00:00
Mario
db4109c2a0 streamline default link color 2021-08-15 08:26:11 +00:00
Mario
36564b5aa7 bump version 2021-08-04 14:47:52 +00:00
Mario
101fc33c63 bs5 sets scroll-behavior to smooth which does weird things especially on mobile devices - unset it 2021-08-04 14:46:46 +00:00
Mario
bd2270deb6 app-bin-ng: add a link to the bin for convenience and use the traditional ajax call instead of the post shortcut 2021-08-04 14:13:28 +00:00
Mario
5b72f6f09d fix another bs5 regression 2021-08-04 12:36:20 +00:00
Mario
ee1cec8de2 the default 400px is slightly overkill 2021-08-03 07:35:43 +00:00
Mario
b0a499d8b1 remove logging 2021-08-03 07:17:55 +00:00
Mario
08f70c49f8 Merge branch 'app-bin-ng' into 'dev'
Apps drag and drop feature

See merge request hubzilla/core!1982
2021-08-03 07:12:36 +00:00
Mario
cddc021772 Apps drag and drop feature 2021-08-03 07:12:35 +00:00
Mario
571bae9d1c Merge branch 'ab-dev' into 'dev'
Updated Polish GUI translation

See merge request hubzilla/core!1981
2021-08-03 07:05:45 +00:00
Andrzej Budziński
e01666526e Updated Polish GUI translation according to changes made in version 6.0
/ 6.1 Hubzilla + stylistic fixes and typos.
2021-08-01 03:41:24 +02:00
Mario
562a160a52 remove another possible source for hubloc confusion 2021-07-29 12:29:39 +00:00
Mario
cb57c4ea18 Merge branch 'bs5' into 'dev'
Update to bootstrap 5 and implement next generation app menu (work in progress)

See merge request hubzilla/core!1980
2021-07-29 09:31:47 +00:00
Mario
b7ffec6fbe bs5 border fix 2021-07-29 09:15:18 +00:00
Mario
94be9f115b another badge fix 2021-07-29 09:06:02 +00:00
Mario
693736df7c dropdown-menu-right -> dropdown-menu-end 2021-07-29 09:03:22 +00:00
Mario
943e7dd242 fix notification button class 2021-07-29 08:45:42 +00:00
Mario
c1526b473b bump version 2021-07-29 08:34:33 +00:00
Mario
d459dfac74 update to bootstrap 5.0.2 2021-07-29 08:25:05 +00:00
Mario
cec2f0d894 more work on bs5 2021-07-29 08:19:33 +00:00
Mario
9722d157bf Merge branch 'dev' into bs5 2021-07-29 06:59:13 +00:00
Mario
6bcd24ab90 check if isset before unsetting to omit php errors
(cherry picked from commit c6133d2558)
2021-07-27 21:12:59 +02:00
Mario
c6133d2558 check if isset before unsetting to omit php errors 2021-07-27 19:07:09 +00:00
Mario
ea8d38dec0 version 6.0.1 2021-07-27 07:12:59 +00:00
Mario
0fa41f082d Merge branch 'dev' 2021-07-27 07:11:12 +00:00
Mario
83b1f62e13 more changelog 2021-07-27 07:10:43 +00:00
Mario
b19213b60b Merge branch 'dev' 2021-07-27 07:07:53 +00:00
Mario
3c5b18913f changelog 2021-07-27 07:06:22 +00:00
Mario Vavti
676a65cd61 notifications: move handlers out of jquery ready function otherwise they might not fire on pageload 2021-07-17 14:00:03 +02:00
Mario Vavti
95fb66b433 code style 2021-07-16 13:53:32 +02:00
Mario Vavti
a57529bc54 bump min version 2021-07-16 13:50:38 +02:00
Mario Vavti
4f15c08805 more work on moving notifications handling from main.js to the notifications widget 2021-07-16 13:48:35 +02:00
Mario Vavti
7b2f4b0814 fix a regression in regard to unified session page load times intoduced in 6.0 2021-07-16 12:56:57 +02:00
Mario Vavti
3051e2c268 redirect to the local item instead of the item at the primary location if we deal with a wall item 2021-07-16 12:04:31 +02:00
Mario
d7489e3913 Merge branch 'dev' into 'dev'
Fix link to source on clones

See merge request hubzilla/core!1975
2021-07-16 09:46:08 +00:00
Mario Vavti
62606bf006 photo upload: always show the textarea so that text and tags can be added even if no status post is sent 2021-07-16 11:42:54 +02:00
Max Kostikov
c68f2bc2d1 Fix link to source on clones 2021-07-16 11:12:32 +02:00
Mario Vavti
f5669c9935 chanview: dismiss xchans which are marked deleted 2021-07-15 12:07:54 +02:00
Mario Vavti
9e2bdb012e fix release date 2021-07-09 12:02:50 +02:00
Mario Vavti
d8ac25c35a version 6.0 2021-07-09 11:33:19 +02:00
Mario Vavti
2dd47a9f59 Merge branch '6.0RC' 2021-07-09 11:31:26 +02:00
Mario Vavti
a92ad512bb Merge branch 'dev' into 6.0RC 2021-07-08 13:36:06 +02:00
Mario Vavti
e39b29cc4b set touch_max to 1/10 of the screen width to prevent overlaping with cursor positioning 2021-07-08 13:35:28 +02:00
Mario
76ed9f3915 typo 2021-07-08 13:23:49 +02:00
nobody
73b53675b1 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-07-06 05:02:52 -07:00
Mario Vavti
fd6ec17d4b version rc1 2021-07-05 10:55:10 +02:00
Mario Vavti
8de364c83e Merge branch 'dev' into 6.0RC 2021-07-05 10:54:29 +02:00
Mario Vavti
9b9ac5054f changelog 2021-07-05 10:54:03 +02:00
Mario Vavti
9efea4e188 Merge branch 'dev' into 6.0RC 2021-07-05 10:51:31 +02:00
Mario Vavti
d45df824ed redbasic: close left aside if hq control button is clicked 2021-07-05 10:42:36 +02:00
Mario Vavti
50ead82bc4 remove redundant z-index 2021-07-04 14:05:48 +02:00
Mario Vavti
c43f501716 ux fixes 2021-07-04 13:57:20 +02:00
Mario Vavti
86d471834e do not call stickyScroll() on small screens - it is not functional 2021-07-03 14:52:00 +02:00
Mario Vavti
a1f7f7a966 since position sticky has no effect if overflow is hidden and the workarounds also have issues, we will automatically scroll to top when left aside is brought in 2021-07-03 14:36:27 +02:00
Mario Vavti
081d82218b implement a very simple swipe mechanism for bringing in left aside 2021-07-03 14:27:55 +02:00
Mario Vavti
cca3eb8c56 work around the fact that sticky does not stick if a parent element has set overflow to hidden 2021-07-02 17:49:03 +02:00
Mario Vavti
933c097a52 changelog typos 2021-07-02 16:46:49 +02:00
Mario Vavti
f5912e05ef do not use summary in photo object 2021-07-02 16:37:50 +02:00
Mario Vavti
e94eb1af0c remove mail and conv tables from install SQL schemas 2021-07-02 16:13:48 +02:00
Mario Vavti
0ab7996a2a update changelog 2021-07-02 16:07:31 +02:00
Mario
faeec0b77b revert ebc84eab3f instead be more picky about the xchan in handle_tag() 2021-07-02 07:23:18 +00:00
Mario Vavti
ebc84eab3f update by xchan_url to catch all associated entries 2021-07-01 22:30:29 +02:00
Mario
b560b6fbd3 Merge branch 'dev' into 6.0RC 2021-07-01 09:27:14 +00:00
Mario
c6b3bc5b20 redbasic: bump version limits 2021-07-01 09:26:20 +00:00
Mario
e31cb28b08 Merge branch 'dev' into 6.0RC 2021-07-01 07:44:51 +00:00
Mario
458fa7bfeb port fixes from as_actor_store() 2021-06-30 19:04:42 +00:00
Mario
fab3f0f2de fix RC version after last merge 2021-06-30 12:06:55 +00:00
Mario
c8d9238c58 missing composer file 2021-06-30 09:11:07 +00:00
Mario
5aa79caf84 bump dev version to 6.1 2021-06-30 07:25:23 +00:00
Mario
12cabbde9e update sbom 2021-06-30 07:19:38 +00:00
Mario
ca3ab2014f update composer autoload 2021-06-30 07:19:16 +00:00
Mario
3e6283a262 strings update 2021-06-30 07:11:44 +00:00
Mario
bc0d0a6b39 version 6.0RC 2021-06-30 07:07:58 +00:00
Mario
6a4727e3eb fix variable name 2021-06-29 18:21:12 +00:00
Mario
ff6d1c808d version 2021-06-29 09:54:13 +00:00
Mario
197d15b7de only remove elements after the delete has happened 2021-06-29 09:53:40 +00:00
Mario
bb5f6a1d79 tools -> features 2021-06-29 09:40:34 +00:00
Mario
e8c6121b4e version 2021-06-29 09:24:13 +00:00
Mario
bed81d785c an attempt to improve the query for direct messages on some systems with hopefully no bad side-effect for others 2021-06-29 09:22:38 +00:00
Mario
0503914527 fix deleting and starring in unthreaded view 2021-06-29 08:45:48 +00:00
Mario
cb65ae6848 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-06-29 07:49:34 +00:00
Mario
652d083766 implement removing of notifications/preview-messages of deleted items 2021-06-29 07:49:19 +00:00
Mario
091d9c10fb Merge branch 'clean-up' into 'dev'
mod network clean-up

See merge request hubzilla/core!1974
2021-06-29 07:15:44 +00:00
Xanthor
835fe10bfe mod network clean-up 2021-06-29 07:15:42 +00:00
Mario
5a474f94e0 fix query logic 2021-06-29 05:45:05 +00:00
Mario
d322feeb54 more deprecate legacy zot 2021-06-28 08:37:05 +00:00
Mario
842c7b31fb Merge branch 'fix' into 'dev'
fix call to prepare_body

See merge request hubzilla/core!1973
2021-06-28 06:55:47 +00:00
Michael Johnston
1034f02d4d fix call to prepare_body 2021-06-28 06:55:47 +00:00
Mario
3f6b6dfaf3 fix regression in relation with recent photo changes 2021-06-27 15:20:06 +00:00
Mario
d3d4dee36a version 2021-06-27 13:57:57 +00:00
Mario
7002248325 update 1247 to clean up bogus entries in updates. this only affects directory servers. 2021-06-27 13:57:18 +00:00
Mario
d8d0f01f80 bump version 2021-06-27 13:46:10 +00:00
Mario
b3b842c071 update 1246 to flag legacy zot hublocs and xchans deleted. we will set the deleted flag to 2 so we can distinguish them from real deletes if necessary 2021-06-27 13:45:06 +00:00
Mario
aca8d1b8f9 bump version 2021-06-25 11:00:36 +00:00
Mario
4f328740dc more work on notifications 2021-06-25 10:53:37 +00:00
Mario Vavti
2f1c2f42b1 check if empty 2021-06-25 08:47:05 +02:00
Mario
d42a998e49 strip html tags from notification message 2021-06-25 06:24:46 +00:00
Mario
167db22e15 slightly refactor for desktop notifications and fix minor issues 2021-06-24 19:31:19 +00:00
Mario
108777251e some preperatory work on desktop notifications 2021-06-24 11:27:51 +00:00
Mario
088713a555 Notification.requestPermission() only fires if wraped in click handler 2021-06-24 08:15:44 +00:00
Mario
7582ebc9c8 remove deprecated dir and queue fns 2021-06-24 07:08:12 +00:00
Mario Vavti
97d9764f01 if there are no messages display that there are no messages 2021-06-23 22:14:01 +02:00
Mario Vavti
dfcd8395d5 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-06-23 21:15:26 +02:00
Mario
6e91bee0ba some work on streamlining mod photos 2021-06-23 15:52:04 +00:00
Mario Vavti
cf791a1909 libzotdir: make sure we have the relevant data before string into updates 2021-06-23 17:09:45 +02:00
Mario
c6d872d177 jot: do not collapse the form if in popup mode 2021-06-23 07:39:20 +00:00
Mario
cc4f3a827c streamline jot popup for mod hq 2021-06-21 18:45:33 +00:00
Mario
0489fbb685 theme: slightly more transparency for the backdrop 2021-06-21 18:21:19 +00:00
Mario
7da23603ec fiÃlter children by tt-filter-active class instead of visibility selector to omit reload loop in mobile view where notifications ar not visible while off-canvas 2021-06-21 18:07:19 +00:00
Mario
afb4ae2109 Merge branch 'dev' into 'dev'
Clean up Search.php & Enotify.php code

See merge request hubzilla/core!1972
2021-06-21 17:42:57 +00:00
Xanthor
e024375b15 Clean up Search.php & Enotify.php code 2021-06-21 17:42:56 +00:00
Mario
3632fb359f calendar: emit a warning if the calendar for the created event is disabled 2021-06-21 07:52:47 +00:00
Mario
2a3ba5d5f0 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-06-20 08:25:41 +00:00
Mario
5b9dc764c5 make sure to not calculate timeago before the translations are loaded 2021-06-20 08:25:29 +00:00
Max Kostikov
24a0d4f308 Merge branch 'dev' into 'dev'
Update Russian translation

See merge request hubzilla/core!1970
2021-06-19 18:06:49 +00:00
Max Kostikov
88f5b10b22 Update Russian translation 2021-06-19 20:00:52 +02:00
Mario
cf69859885 one more place to drop media 2021-06-18 10:12:08 +00:00
Mario
af71f7f8cd remove notes from network pdl - it is now located in HQ 2021-06-18 10:06:42 +00:00
Mario
ec22ca7553 css and js fixes 2021-06-18 09:58:00 +00:00
Mario
c42d8a81c7 bbcode: add option to drop media content 2021-06-18 09:51:20 +00:00
Mario
0e7473c3ba more css improvements 2021-06-18 08:59:22 +00:00
Mario
f4f9ccc3b2 css fixes 2021-06-18 08:55:49 +00:00
nobody
efda8aac1d Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-06-17 14:57:47 -07:00
Mario
a84cec4acd fix wrong class and bump version 2021-06-17 12:21:39 +00:00
Mario
cf6b7a4236 whitespace 2021-06-17 12:13:40 +00:00
Mario
998f46b45c update hq_controls widget pdl 2021-06-17 12:12:50 +00:00
Mario
5ca352a6c3 allow to add a wrapper class to the hq_controls widget 2021-06-17 12:10:54 +00:00
Mario
a34bd3b013 fix issue where notifications were not loaded if a filter was applied 2021-06-17 11:21:59 +00:00
Mario
c268bc327a fix issues with browser back button and minor cleanup 2021-06-17 10:14:23 +00:00
Mario
e79a27c654 just use ... as preview if we could not wind anything useful 2021-06-17 08:08:14 +00:00
Mario
2f0bac8ddf consolidate notifications strings 2021-06-17 08:06:26 +00:00
Mario
12d7d1c3f0 fix wrong variable 2021-06-17 07:50:16 +00:00
Mario
34ca2cddd4 only show notes if the app is enabled 2021-06-17 07:43:32 +00:00
Mario
fa076efd3b Merge branch 'dm' into 'dev'
New landing page HQ with separate views for direct messages, public/limited messages and starred messages if the feature is enabled

See merge request hubzilla/core!1969
2021-06-17 07:33:46 +00:00
Mario
b55676d089 New landing page HQ with separate views for direct messages, public/limited messages and starred messages if the feature is enabled 2021-06-17 07:33:45 +00:00
Mario
9b71c090c5 Merge branch 'translation-pl' into 'dev'
Translation pl - generated new util/hmessages.po, translated new strings + few fixes

See merge request hubzilla/core!1968
2021-06-17 07:33:15 +00:00
Mario
0f8e4e4eed Merge branch 'dev' into 'dev'
Fix email local part validation

See merge request hubzilla/core!1967
2021-06-17 07:30:57 +00:00
Andrzej Budziński
de1e3d7b17 Polish translation: fixes 2021-06-13 02:30:27 +02:00
Andrzej Budziński
3d077a0bc6 Generated new util/hmesages.po + new Polish translations 2021-06-12 03:16:09 +02:00
Andrzej Budziński
c74d1f4bf7 Polish translation: a little fixes 2021-06-10 23:47:27 +02:00
Andrzej Budziński
776e1211bc fixes in .gitignore file 2021-06-10 23:39:22 +02:00
Max Kostikov
b5a8ca6ef7 Merge branch 'translation-pl' into 'dev'
Polish translation: some fixes

See merge request hubzilla/core!1966
2021-06-10 08:11:20 +00:00
Max Kostikov
2c198ed89a Remove unnecessary parentheses 2021-06-09 12:53:55 +02:00
Max Kostikov
17fdeb9e1f Fix email local part validation 2021-06-09 11:06:12 +02:00
Mario Vavti
e41858f57c remove redundant arg 2021-06-09 09:45:25 +02:00
Mario
219d47f04c bs5: more fixes 2021-06-07 18:38:54 +00:00
Mario
750721c1a0 bs5: minor fix 2021-06-07 14:12:30 +00:00
Mario
b66b43256b bs5: more notifications fixes 2021-06-07 13:21:44 +00:00
Mario
58cacaff06 bs5: more notifications work 2021-06-07 12:37:12 +00:00
Mario
9aebb01d62 bs5: notifications work 2021-06-07 14:10:57 +02:00
Mario
f3b4308cb5 upgrade to bootstrap 5.0.1 and first batch of fixes 2021-06-07 12:56:27 +02:00
Andrzej Budziński
12089e127a Polish Translation: a little fixes 2021-06-05 21:37:29 +02:00
Andrzej Budziński
c75b8711b1 Polish Translation: a little fixes 2021-06-05 20:43:49 +02:00
Mario
67322c1264 more work on directory sync 2021-06-05 18:40:23 +00:00
Mario
607f0346f4 version 2021-06-05 10:14:08 +00:00
Mario
d5bb34f65d composer update symfony/polyfill-ctype 2021-06-05 09:42:45 +00:00
Mario
3e18efd89f composer update psr/log 2021-06-05 09:38:58 +00:00
Mario
bec3cb48e5 composer update commerceguys/intl to version 1.1.0 2021-06-05 09:34:18 +00:00
Mario
e8d2819c42 fix test 2021-06-05 09:17:51 +00:00
Mario
cc85c2f4d7 composer update commerceguys/intl 2021-06-05 09:11:39 +00:00
Mario
bee4fa9937 missing use statement 2021-06-05 09:06:09 +00:00
Mario
14ab5801d2 league/html-to-markdown suports tables now 2021-06-05 08:55:32 +00:00
Mario
fd8a5ff4c4 composer update league/html-to-markdown 2021-06-05 08:47:24 +00:00
Andrzej Budziński
ef9ae0db94 Polish translation: some fixes 2021-06-05 10:45:09 +02:00
Mario
4db384da34 composer update smarty 2021-06-05 08:32:34 +00:00
Mario
0784d2ea4e Merge branch 'dev' into six 2021-06-05 07:52:43 +00:00
Mario
b90db6931d Merge branch 'dev' into 'dev'
Changed behavior in the user interaction of the languages selection. Now works...

See merge request hubzilla/core!1952
2021-06-05 07:51:38 +00:00
Hilmar Runge
25497336bb Changed behavior in the user interaction of the languages selection. Now works... 2021-06-05 07:51:38 +00:00
Mario
a0ee9557f0 Merge branch 'translation-pl' into 'dev'
The Polish translation: ixes and new doc translation

See merge request hubzilla/core!1965
2021-06-05 07:50:50 +00:00
Mario
7b3eb09067 Merge branch 'dev' into six 2021-06-05 07:48:44 +00:00
Andrzej Budziński
1fc3be0c9f Polish translation:
Final fixes in 'view/pl/hmessages.po' + 'docs/pl'.
The Polish translation of Habzill's and Zap's GUI is consistent.
The most important articles of the documentation are also translated
Quality improvements to the documentation remain to be made, including the writing of new articles
(guides).
2021-06-04 23:35:49 +02:00
Mario
6de327402b version 5.6.1 2021-06-04 11:27:09 +02:00
Mario
131ce826c3 Merge branch 'dev' 2021-06-04 11:10:37 +02:00
Mario
a3f4ad9ea0 fix es plural return 2021-06-04 11:10:14 +02:00
Mario
ec3b1131d9 changelog 2021-06-04 11:08:55 +02:00
Mario
74c0345009 Merge branch 'dev' 2021-06-04 10:26:17 +02:00
Mario
628b03da29 fix css issue 2021-06-04 10:25:36 +02:00
Mario
bd59fb0b4e Merge branch 'dev' 2021-06-04 10:09:22 +02:00
mjfriaza
443b436be8 Update Spanish
(cherry picked from commit 993d648011)
2021-06-04 07:52:45 +00:00
mjfriaza
993d648011 Update Spanish 2021-06-04 07:51:53 +00:00
Mario
343f3059e6 fix login name label for the case when system.verify_email is disabled
(cherry picked from commit e44bf42c64)
2021-06-04 07:48:25 +00:00
Mario
10f8fe8973 use uuid for hash 2021-06-04 07:46:36 +00:00
Mario
e44bf42c64 fix login name label for the case when system.verify_email is disabled 2021-06-04 07:45:33 +00:00
Mario
3d1684fa94 Revert "fix login name label for the case when system.verify_email is disabled"
This reverts commit d882bad706.
2021-06-04 07:44:37 +00:00
Mario
d882bad706 fix login name label for the case when system.verify_email is disabled 2021-06-04 07:43:23 +00:00
nobody
686530c187 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-06-03 16:01:16 -07:00
Mario Vavti
e5c8273f72 Merge branch 'six' of https://framagit.org/hubzilla/core into six 2021-06-03 11:00:39 +02:00
Mario Vavti
440f7bacd6 directory improvements 2021-06-03 10:59:12 +02:00
Mario
ba22d3e9b6 fix issue where a deleted channel will return 404 before returning zotinfo
(cherry picked from commit 33463152e8)
2021-06-02 18:13:48 +00:00
Mario
33463152e8 fix issue where a deleted channel will return 404 before returning zotinfo 2021-06-02 17:58:46 +00:00
Mario
657af3024e Merge branch 'dev' into 'dev'
Make pubstream ordering configurable

See merge request hubzilla/core!1964
2021-06-02 08:33:55 +00:00
Max Kostikov
7d82a34538 Make pubstream ordering configurable 2021-06-02 08:33:54 +00:00
Mario
a0b788e96a fix article summary duplicated when editing - issue #1577
(cherry picked from commit 50c14d353b)
2021-06-02 08:32:41 +00:00
Mario
50c14d353b fix article summary duplicated when editing - issue #1577 2021-06-02 08:31:43 +00:00
Mario Vavti
b63aa3079b fix regression where authors from non zot6, activitypub networks got dismissed (e.g. relayed diaspora comments)
(cherry picked from commit b3df15a3c6)
2021-06-02 07:52:40 +00:00
Mario
25be24e6b8 Merge branch 'six' of https://framagit.org/hubzilla/core into six 2021-06-02 07:44:36 +00:00
Mario Vavti
2ec2da5dff Merge branch 'six' of https://framagit.org/hubzilla/core into six 2021-06-02 09:42:27 +02:00
Mario Vavti
b3df15a3c6 fix regression where authors from non zot6, activitypub networks got dismissed (e.g. relayed diaspora comments) 2021-06-02 09:41:57 +02:00
nobody
462980c70a Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-05-31 14:36:14 -07:00
Max Kostikov
2171686284 Merge branch 'translation-pl' into 'dev'
New traslations: view/pl/invite* files + some fixes

See merge request hubzilla/core!1963
2021-05-31 18:29:38 +00:00
Andrzej Budziński
b382edc61d Fixes to docs/pl/about/about.bb 2021-05-31 18:07:16 +02:00
Andrzej Budziński
5ae21d04b0 New traslations: view/pl/invite* files + some fixes 2021-05-31 13:39:11 +02:00
Mario
b0825ead84 Merge branch 'dev' into six 2021-05-31 11:33:47 +00:00
Mario
2980f852aa fix admin button state not displayed correctly
(cherry picked from commit baabb3a873)
2021-05-31 11:32:09 +00:00
Mario
5e07ebe7fa fix registration bug - issue #1574 2021-05-31 09:07:50 +00:00
Mario
baabb3a873 fix admin button state not displayed correctly 2021-05-31 10:14:26 +02:00
Mario
5ee1c3f2c8 include items.php in boot since it is required almost everywhere 2021-05-31 10:03:34 +02:00
Mario
3fe2a2b181 do not overwrite the original rawmsg iconfig that came with the item 2021-05-31 07:12:36 +00:00
Mario
3d2b923102 notifier fixes 2021-05-29 06:20:28 +00:00
Mario
43c941d370 fix notifier for non-zot hublocs 2021-05-28 20:15:34 +00:00
Mario
e1721b8496 remove masto hack - it does not make sense in threaded view 2021-05-28 20:14:15 +00:00
Mario
ccf3ed185f remove mod ping 2021-05-28 17:18:03 +00:00
Mario
99af27770e Merge branch 'dev' into six 2021-05-28 10:16:34 +00:00
Mario
e9088bd52e notifications: if we have to return early, make sure to set offset to -1 to prevent looping
(cherry picked from commit f72b8ce30f)
2021-05-28 10:13:25 +00:00
Mario
f72b8ce30f notifications: if we have to return early, make sure to set offset to -1 to prevent looping 2021-05-28 10:02:05 +00:00
Mario
19bb96121b move mark notifications read code to mod notifications 2021-05-28 09:58:18 +00:00
Mario
69ef7cf168 remove more mail leftovers 2021-05-28 08:42:08 +00:00
Mario
f1aace5a22 remove unobscure() 2021-05-28 08:28:32 +00:00
Mario
0718ac514d remove deprecated mail code 2021-05-28 08:11:40 +00:00
Mario
d289994da4 missing include 2021-05-28 07:22:49 +00:00
Mario
30f258b3f9 add check for type 2021-05-28 07:19:49 +00:00
Mario
d06d22c7c9 bump version 2021-05-27 20:06:22 +00:00
Mario
57c301d59c composer dump autoload 2021-05-27 19:58:34 +00:00
Mario
4bde2f64bd remove zot 2021-05-27 19:55:06 +00:00
Mario
8ca487115f remove include/msglib 2021-05-27 19:50:53 +00:00
Mario
7ad0a1e557 remove include/message (the file) 2021-05-27 19:50:35 +00:00
Mario
1aa626f0e8 remove include/message 2021-05-27 19:49:44 +00:00
Mario
7e36d17135 remove include/zot 2021-05-27 19:48:19 +00:00
Mario
2f7e875eb4 remove mod post 2021-05-27 19:45:34 +00:00
Mario
3ab8632d3b update mail widgets to not require include message and minor fixes 2021-05-27 19:20:07 +00:00
Mario
190fc4e3c4 fix typo 2021-05-27 17:44:24 +00:00
Mario
3eb1b9d168 remove reply_message_request(), implement force_refresh and minor fixes 2021-05-27 17:42:28 +00:00
Mario
2fb3d6ddf5 remove zot6/finger 2021-05-27 15:40:28 +00:00
Mario
bf74a75303 bump version 2021-05-27 12:25:23 +00:00
Mario
7d1b240954 fix typo 2021-05-27 12:07:29 +00:00
Mario
2db3e4ca48 fix test 2021-05-27 11:49:09 +00:00
Mario
cee2e63278 fix typo 2021-05-27 11:30:27 +00:00
Mario
9d5732400f remove mod message 2021-05-27 11:21:30 +00:00
Mario
3cb0613d04 mising use statement 2021-05-27 11:16:29 +00:00
Mario
d9920fce3a missing include 2021-05-27 11:10:09 +00:00
Mario
2765a0a9fd missing includes 2021-05-27 10:50:53 +00:00
Max Kostikov
92ea7fcfb1 Merge branch 'translation-pl' into 'dev'
Next fixes to Polish translation

See merge request hubzilla/core!1962
2021-05-27 10:05:30 +00:00
Mario
9d96793e1a update fresh 2021-05-27 09:48:50 +00:00
Mario
7776283a47 remove zot includes 2021-05-27 09:45:39 +00:00
Mario
c9d4802bf1 Ãremove queue_fn includes 2021-05-27 09:33:22 +00:00
Mario
37558e24f8 remove dir_fns includes 2021-05-27 09:30:57 +00:00
Mario
67cf9f6caf deprecate find_upstream_directory() 2021-05-27 09:22:38 +00:00
Mario
16146af039 deprecate remove_queue_by_posturl() 2021-05-27 09:18:46 +00:00
Mario
6a7e06f11c deprecate get_rpost_path() 2021-05-27 09:09:52 +00:00
Mario
adba56a5e5 remove mod events 2021-05-27 08:55:52 +00:00
Mario
90c9fc5338 deprecate import_xchan() 2021-05-27 08:39:23 +00:00
Mario
0a09f507fc remove zping 2021-05-27 08:30:00 +00:00
Mario
9ea60ba79f deprecate make_xchan_hash() 2021-05-27 08:27:33 +00:00
Mario
43ef82aaaa remove zfinger 2021-05-27 08:19:22 +00:00
Mario
7171d790f4 import Lib/Queue as LibQueue 2021-05-27 08:02:54 +00:00
Mario
4099549609 remove deprecated rating code 2021-05-27 07:58:56 +00:00
Mario
4e4bffe5c5 deprecate queue_deliver() 2021-05-27 07:52:18 +00:00
Mario
1c8000d026 remove more legacy zot quirks 2021-05-26 19:02:13 +00:00
Mario
ff34a787c3 php8: more id3 parser fixes 2021-05-26 18:02:29 +00:00
Mario
84c5f57d22 php8: more id3 parser fixes 2021-05-26 17:54:07 +00:00
Andrzej Budziński
64181c7cf1 Next fixes. It already looks very nice, but it's not end work yet for
this translation.
2021-05-26 17:15:09 +02:00
Mario
3c5f840cf0 typo 2021-05-26 12:29:15 +00:00
Mario
1fa4bc9ac0 remove most legacy zot quirks 2021-05-26 12:18:59 +00:00
Mario
b742910107 remove legacy zot from supported protocols 2021-05-26 11:28:33 +00:00
Mario
b7f124072f import_author_xchan(): do not import legacy zot 2021-05-26 11:25:36 +00:00
Mario
ec02eda113 handle_tag(): only use xchans with xhchan_deleted = 0 2021-05-26 09:36:13 +00:00
Mario
8d8523684c more id3parser 2021-05-26 08:51:35 +00:00
Max Kostikov
8a0c7b3fe1 Merge branch 'translation-pl' into 'dev'
Updating translatons strings + fixes to Polish translation

See merge request hubzilla/core!1961
2021-05-25 15:01:33 +00:00
Mario
a29dbaba21 disable mod post for now 2021-05-25 12:17:45 +00:00
Mario
51ad4fac01 php8: even even more fix unmaintained id3 parser 2021-05-25 12:08:58 +00:00
Mario
d863ba1b2a syntax error 2021-05-25 12:04:32 +00:00
Mario
175001eccd php8: even more fix unmaintained id3 parser 2021-05-25 11:47:26 +00:00
Mario
846d99cfce php8: more fix unmaintained id3 parser 2021-05-25 11:24:16 +00:00
Mario
2486a9c914 php8: fix un maintained id3 parser 2021-05-25 11:15:22 +00:00
Mario
a47a81db6f more notifier work 2021-05-25 11:13:13 +00:00
Andrzej Budziński
587e790892 Regenerating hstrings.ph file 2021-05-24 18:37:53 +02:00
Andrzej Budziński
f73a83aa55 Next fixes and generating new hstrings.php file 2021-05-24 17:18:13 +02:00
Andrzej Budziński
513cf2b8e2 Updating translation strings (v. 5.7) + fixes to Polish translation 2021-05-23 23:51:27 +02:00
Mario
ea215697ed remove location command from notifier 2021-05-23 20:36:00 +00:00
Mario
d40686e5d0 remove request command from notifier 2021-05-23 20:31:03 +00:00
Mario
0b7d343c7c remove mail and some hubzilla < 5.0 quirks from notifier 2021-05-23 20:10:43 +00:00
Mario
d692ed634a some cleanup 2021-05-23 19:44:37 +00:00
Mario Vavti
7d4e07df79 AccessList::is_private() does not return info about the private state (1 or 2). Use the info from the parent item until this will be sorted out 2021-05-23 19:17:09 +02:00
Mario
8211bc09d4 remove todo since the zot6 xchan should be merely imported in this case. also only return if we already have a result. 2021-05-21 06:54:37 +00:00
Mario
5705005ca3 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-05-21 06:44:21 +00:00
Mario
79b4642b32 introduce the direct flag for direct messages 2021-05-21 06:44:15 +00:00
Mario
c9981ff0e1 Merge branch 'Malend-dev-patch-02229' into 'dev'
Remove useless test

See merge request hubzilla/core!1957
2021-05-21 06:38:40 +00:00
Mario
0948b061fe Merge branch 'Malend-dev-patch-19605' into 'dev'
Fix phpDoc

See merge request hubzilla/core!1958
2021-05-21 06:37:33 +00:00
Mario
a537e78f14 Merge branch 'cherry-pick-a7a47275' into 'master'
Merge branch 'dev' into 'dev'

See merge request hubzilla/core!1960
2021-05-20 13:40:47 +00:00
Max Kostikov
25edeebf2b Merge branch 'dev' into 'dev'
Fix updated variables in member verificaton template

See merge request hubzilla/core!1959

(cherry picked from commit a7a4727591)

bc2afb21 Fix updated variables
2021-05-20 12:40:54 +00:00
Max Kostikov
a7a4727591 Merge branch 'dev' into 'dev'
Fix updated variables in member verificaton template

See merge request hubzilla/core!1959
2021-05-20 12:33:03 +00:00
Max Kostikov
bc2afb21e1 Fix updated variables 2021-05-20 12:29:37 +00:00
Mario
64fe93b9eb Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-05-20 10:15:08 +00:00
Mario
33d2a852c9 make sure to set the correct item_private state 2021-05-20 10:14:49 +00:00
Malendur
300679c053 Fix phpDoc 2021-05-20 08:23:45 +00:00
Malendur
f9c85c52f3 Remove useless test 2021-05-20 08:14:58 +00:00
Max Kostikov
98985b2761 Merge branch 'dev' into 'dev'
Fix security headers switching

See merge request hubzilla/core!1953
2021-05-19 23:30:39 +00:00
Mario
8fe00d428d bring back the channel_protocols hook 2021-05-19 17:47:26 +00:00
Max Kostikov
02229482b8 Fix security headers switching 2021-05-17 22:30:47 +02:00
Mario
9a5c1aa02f there might be errors in cli without this 2021-05-17 09:42:29 +00:00
Mario
a46e340a13 Ãmake sure we do not deal with diaspora hublocs here 2021-05-17 09:09:24 +00:00
Mario
70c3cd99ac Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-05-15 13:21:22 +00:00
Mario
e89bbde575 add zid and delegate parameters to the bdest string so that we will be authenticated when being redirected offsite 2021-05-15 13:21:07 +00:00
Mario Vavti
2ee1e2af72 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-05-15 15:16:05 +02:00
Mario Vavti
c3ad21c548 make sure we do not mess up the query string when removing single parameters 2021-05-15 15:15:48 +02:00
Mario
635a24dff4 Merge branch 'dev' into 'dev'
Random PHP 8 fixes

See merge request hubzilla/core!1951
2021-05-14 08:56:07 +00:00
Max Kostikov
a03423794a Random PHP 8 fixes 2021-05-14 08:56:06 +00:00
Mario
d4e723a8eb fix regression in regard to menu wrapping
(cherry picked from commit ded9f18b8a)
2021-05-12 08:00:59 +00:00
Mario
ded9f18b8a fix regression in regard to menu wrapping 2021-05-12 07:56:30 +00:00
Mario
3a2e5d480c update include/items.php 2021-05-11 12:14:44 +00:00
Mario
26e851ff7f Merge branch '5.6RC' 2021-05-11 11:59:49 +00:00
Mario
89ec043ce1 version 5.6 2021-05-11 11:58:16 +00:00
Mario
98f0272a84 Merge branch '5.6RC' of https://framagit.org/hubzilla/core into 5.6RC 2021-05-11 11:57:22 +00:00
Mario
0933925a2b Merge branch 'dev' into 5.6RC 2021-05-11 11:57:13 +00:00
Mario
e92929fce4 changelog 2021-05-11 11:56:54 +00:00
Mario
f388412c48 id should be intval here
(cherry picked from commit 836de7f1a5)
2021-05-10 09:07:59 +00:00
Mario
836de7f1a5 id should be intval here 2021-05-10 09:05:27 +00:00
Mario
43008aa42b Merge branch '5.6RC' of https://framagit.org/hubzilla/core into 5.6RC 2021-05-08 08:44:29 +00:00
Mario
7618d8301a 5.6RC3 2021-05-08 08:44:13 +00:00
Mario
09cfc979e4 Merge branch 'dev' into 5.6RC 2021-05-08 08:43:00 +00:00
Mario
00fc5541db remove redundant placeholder in query
(cherry picked from commit 954d06bdb7)
2021-05-08 08:29:56 +00:00
Mario
954d06bdb7 remove redundant placeholder in query 2021-05-08 08:29:04 +00:00
Mario
12828ee4d4 update 1245 to fix hubloc_hash index for postgres
(cherry picked from commit c2e007a839)
2021-05-07 18:47:06 +00:00
Mario
c2e007a839 update 1245 to fix hubloc_hash index for postgres 2021-05-07 15:02:55 +00:00
Mario
605bf3b9d3 register: postgres - add default values for timestamps
(cherry picked from commit ebd0333256)
2021-05-07 12:15:56 +00:00
Mario
ebd0333256 register: postgres - add default values for timestamps 2021-05-07 12:15:00 +00:00
Mario
d7dcf192c7 remove logging
(cherry picked from commit 2ad6f6e11f)
2021-05-07 11:09:09 +00:00
Mario
2ad6f6e11f remove logging 2021-05-07 11:08:40 +00:00
Mario
36a814b03e version 5.6RC2 2021-05-07 11:03:59 +00:00
Mario
92bc99a805 strings 2021-05-07 11:02:21 +00:00
Mario
b5ce207344 register: implement remove_expired_registrations() and minor fixes 2021-05-07 10:03:12 +00:00
Mario
d04ff264fa register: fix minor string issue 2021-05-07 08:26:59 +00:00
Mario
9ad2b017e2 register: fix language issue and add additional info to the infobox if email verification is configured 2021-05-07 08:15:06 +00:00
Mario
1fd5f5c893 register: redirect unverified registration emails to the verification form 2021-05-06 19:06:53 +00:00
Mario
43260891b7 register: we have already checked for existing email in check_account_email() 2021-05-06 13:54:02 +00:00
Mario
aef0350346 remove duplicate singletons hublocs once a day 2021-05-05 09:15:02 +00:00
Mario
83fbb0678c use hubloc_hash instead of hubloc_id_url - otherwise it will bite hublocs which use more than one protocol 2021-05-05 08:50:03 +00:00
Mario
df3778c64f Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-05-05 08:36:43 +00:00
Mario
0dc09ea238 possible minor performance improvement 2021-05-05 08:36:18 +00:00
Max Kostikov
f085c3c98f Merge branch 'translation-pl' into 'dev'
Fixes related to correction plural expression, plus typos and some other

See merge request hubzilla/core!1950
2021-05-02 12:17:13 +00:00
Mario
8d4b1ba7d4 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-05-02 11:33:45 +00:00
Mario
b3c543265d introduce function to remove duplicate singleton hublocs 2021-05-02 11:33:26 +00:00
Andrzej Budziński
6eee404bb1 Fixes related to correction plural expression, plus typos and some other
fixes
2021-05-01 02:43:17 +02:00
Max Kostikov
ec4226b5de Merge branch 'dev' into 'dev'
Fix Polish plurals expression

See merge request hubzilla/core!1949
2021-04-30 19:28:15 +00:00
Max Kostikov
8266a1490a Fix Polish plurals expression 2021-04-30 21:24:44 +02:00
Max Kostikov
56554710ea Merge branch 'dev' into 'dev'
Dev sync

See merge request kostikov/core!2
2021-04-30 19:23:26 +00:00
Max Kostikov
6a101e6260 Merge branch 'translation-pl' into 'dev'
Translation update to v.5.7 plus fixes and typos

See merge request hubzilla/core!1948
2021-04-30 18:34:29 +00:00
Andrzej Budziński
f12038e63e Translation update to v.5.7 plus fixes and typos 2021-04-30 12:54:22 +02:00
Max Kostikov
ad2bf187bb Merge branch 'dev' into 'dev'
Update Russian translation; fix missprint

See merge request hubzilla/core!1947
2021-04-29 10:10:27 +00:00
Max Kostikov
4cbd97e409 Update Russian translation 2021-04-29 12:06:53 +02:00
Max Kostikov
e67c780afd Fix missprint 2021-04-29 11:35:14 +02:00
Max Kostikov
0cbdeb7bf1 Merge branch 'dev' into 'dev'
Dev Sync

See merge request kostikov/core!1
2021-04-29 09:32:02 +00:00
Mario
6be464ef84 bump version 2021-04-29 08:40:47 +00:00
Mario
54845a7627 composer dump autoload 2021-04-29 08:33:58 +00:00
Mario
2f6da0be7e version and strings 2021-04-29 08:30:31 +00:00
Mario
cf87a5af3b fix typos in Activity::follow() 2021-04-29 07:35:22 +00:00
Mario
207057c92d Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-04-29 06:47:26 +00:00
Mario
5300f180db really fix manual fetching of non-ascii domains 2021-04-29 06:47:03 +00:00
Mario
ec7166eb00 fix manual fetching of non-ascii domains 2021-04-28 19:38:43 +02:00
Mario
36f041a1ff cleanup 2021-04-28 14:23:53 +02:00
Mario
0dd2e9004d do not attempt to translate twice 2021-04-28 13:21:49 +02:00
Mario
94f1c001f1 register: more testing and fixes 2021-04-28 13:17:45 +02:00
Mario
531a03562d register: new install testing fixes 2021-04-27 15:09:27 +02:00
Mario
3699f78e95 register: remove single quotes in advanced examples - they might be misleading 2021-04-27 08:08:21 +00:00
Mario
ebd2283b38 more strings changes 2021-04-26 20:33:16 +00:00
Mario
a7788570e5 register: remove debug messages from UI and streamline some strings 2021-04-26 20:30:38 +00:00
Mario
2932ac9d86 register: only log to separate file if configured that way. default to standard logging via logger() 2021-04-26 18:31:08 +00:00
Mario
888c211f44 check perms for comments since in AP they can be different from the top level post 2021-04-26 11:53:25 +00:00
Max Kostikov
61cf92ebdd Support new parse_str() syntax 2021-04-24 22:23:50 +00:00
Mario
80ec45e4f9 fix variable mixup 2021-04-22 19:48:59 +00:00
Mario
9e9851681f Merge branch 'dev' into 'dev'
Fix clones sync when wiki or single wiki page deletion

See merge request hubzilla/core!1945
2021-04-22 17:53:47 +00:00
Max Kostikov
8394d4857c Fix clones sync when wiki or single wiki page deletion 2021-04-22 17:53:47 +00:00
Mario
c700a017a0 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-04-22 17:43:26 +00:00
Mario
c19eb94c52 make sure we transform events to UTC on import before storing. Transform from event timezone if available otherwise channel default 2021-04-22 17:42:58 +00:00
Mario Vavti
597f24ca49 invite: fix javascript issue 2021-04-22 10:07:17 +02:00
Mario
eb793b1601 bump version 2021-04-21 19:28:41 +00:00
Mario
07525c5b45 next batch of fixes 2021-04-21 18:51:53 +00:00
Mario
35df50c39d start sending author id, id_sig and key fields along with author/owner and adjust import_author_xchan() accordingly 2021-04-21 07:55:35 +00:00
Mario Vavti
406ca20634 version 5.4.3 2021-04-20 11:13:19 +02:00
Mario
021e7861b8 changelog
(cherry picked from commit 5dfe4ef6f8)
2021-04-20 11:12:13 +02:00
Mario
5dfe4ef6f8 changelog 2021-04-20 09:11:45 +00:00
Mario
60a0fdc76b fix regression in mod notifications
(cherry picked from commit b8a5f5fbf2)
2021-04-20 10:58:56 +02:00
Mario
cd760454a5 floc off google
(cherry picked from commit 7ccd7b439f)
2021-04-20 10:58:38 +02:00
Mario
c7144dbf96 use protect_sprintf() on query strings
(cherry picked from commit f9793e870f)
2021-04-20 10:57:36 +02:00
Miłosz Kłosowicz
c31e203104 Wfinger - check https from http_x_forwarded_proto
(cherry picked from commit aa2450fae1)
2021-04-20 10:57:00 +02:00
Mario
6feefc5ce0 fix regression finding bookmarks
(cherry picked from commit 16cc695115)
2021-04-20 10:56:37 +02:00
Mario
1d7f9e05ed Merge branch 'dev' into 'dev'
more PHP 8 fixes

See merge request hubzilla/core!1943
2021-04-20 08:53:32 +00:00
Mario
6a858b29fd potential export issue when using PHP8
(cherry picked from commit ba412bc6cf)
2021-04-20 10:52:39 +02:00
Mario
3f0e687558 if we use dbescbin on save we should use dbunescbin when retrieving (at least that is true for postgres)
(cherry picked from commit 31abcac4b4)
2021-04-20 10:52:18 +02:00
Mario
ba412bc6cf potential export issue when using PHP8 2021-04-20 08:49:03 +00:00
Mario
31abcac4b4 if we use dbescbin on save we should use dbunescbin when retrieving (at least that is true for postgres) 2021-04-20 08:42:58 +00:00
Mario
d7f04ff6ee when importing a channel, make sure we import the xchan before the hubloc - otherwise we can not verify the hubloc hash
(cherry picked from commit eaf9003ca2)
2021-04-20 10:36:08 +02:00
Mario
76fd81fad1 revert last part of previous commit -> see comment above the change
(cherry picked from commit eded0f6c09)
2021-04-20 10:35:27 +02:00
Mario
1cfcffc510 import_items(): make sure we compare the correct revision and only call item_store_update() if edited timestamp of the received item > stored item timestamp
(cherry picked from commit c95a6fe1e5)
2021-04-20 10:35:11 +02:00
Mario
eaf9003ca2 when importing a channel, make sure we import the xchan before the hubloc - otherwise we can not verify the hubloc hash 2021-04-20 08:09:33 +00:00
Mario
751d6fe8a4 register: minor strings changes and whitespace 2021-04-19 19:29:35 +00:00
Mario
20ca6676d2 registration: reveal possibility to show all registrations in the UI 2021-04-19 19:07:50 +00:00
Mario
eded0f6c09 revert last part of previous commit -> see comment above the change 2021-04-19 10:49:41 +00:00
Mario
b5049651ad Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-04-19 10:41:51 +00:00
Mario
c95a6fe1e5 import_items(): make sure we compare the correct revision and only call item_store_update() if edited timestamp of the received item > stored item timestamp 2021-04-19 10:41:28 +00:00
Max Kostikov
cd97c32444 more PHP 8 fixes 2021-04-18 21:25:32 +02:00
Max Kostikov
70b204cb3f Merge branch 'dev' into 'dev'
PHP 8 fixes

See merge request hubzilla/core!1942
2021-04-18 07:29:41 +00:00
Max Kostikov
d2f1edfad8 PHP 8 fixes 2021-04-18 09:27:25 +02:00
Max Kostikov
2ddfcd5222 PHP 8 fixes 2021-04-18 09:23:14 +02:00
Max Kostikov
787ee411ce PHP 8 fixes 2021-04-17 23:50:19 +02:00
Max Kostikov
200d3577fa Merge branch 'dev' of https://framagit.org/kostikov/core into dev 2021-04-17 23:46:40 +02:00
Max Kostikov
8ab99747f5 Merge branch 'translation-pl' into 'dev'
Next fixes and typos, and new docs translations

See merge request hubzilla/core!1941
2021-04-16 19:31:44 +00:00
Mario
88f7c2041d register: add option to show all register entries 2021-04-16 18:13:20 +00:00
Andrzej Budziński
43cb21329f Next fixes and typos, and new docs translatons 2021-04-16 16:30:03 +02:00
Mario
b8a5f5fbf2 fix regression in mod notifications 2021-04-16 12:41:31 +00:00
nobody
a96345401f Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-04-16 04:42:45 -07:00
Mario
7ccd7b439f floc off google 2021-04-16 09:14:40 +00:00
Mario
f0eceb03ed prepare Activity::follow() for pubcrawl 2021-04-16 08:08:15 +00:00
Mario
c2b9fc1a49 register: add help text to the message field 2021-04-15 13:10:20 +00:00
Mario
4d3a555b53 register: minor fixes and template cleanup 2021-04-15 09:26:47 +00:00
Mario
e35ab97b7e register: provide a possibility to leave a message id registration is by approval 2021-04-14 19:40:51 +00:00
Mario
f9793e870f use protect_sprintf() on query strings 2021-04-14 11:01:34 +00:00
Mario
e48fedd526 most AP projects do not handle an array for person object URL - provide a string 2021-04-14 09:30:19 +00:00
Mario
b899ed3d64 register: change some strings and add new template 2021-04-13 13:04:43 +00:00
Mario
e4adb881cb Merge branch 'dev' into 'dev'
Wfinger - check https from http_x_forwarded_proto

See merge request hubzilla/core!1940
2021-04-12 18:52:37 +00:00
Miłosz Kłosowicz
aa2450fae1 Wfinger - check https from http_x_forwarded_proto 2021-04-12 10:33:21 +00:00
Mario
d9245566f5 register: change some strings and some whitespace fixes 2021-04-11 17:46:06 +00:00
Mario
16cc695115 fix regression finding bookmarks 2021-04-11 15:47:42 +00:00
Mario
f0e5ce7fd1 register: more work on ui/ux 2021-04-10 20:44:04 +00:00
Mario
ea721d380b register: move some html out of the code and provide a basic template 2021-04-10 10:53:27 +00:00
Mario
e193b6d870 feature level is deprecated 2021-04-10 08:00:03 +00:00
Mario
766fc92a3b register: we use default role if auto create is configured 2021-04-09 19:25:31 +00:00
Mario
df6f2abfbe register: if auto create is configured do some more tests against the provided name and nick so it will not fail later in create_identity(); 2021-04-09 19:06:36 +00:00
Mario
684245f24d whitespace 2021-04-09 09:57:22 +00:00
Mario
01b081d809 register: only return verified registrations in get_pending_accounts(), more invite handling fixes 2021-04-09 09:49:36 +00:00
Mario
a34d8852b6 minor revert 2021-04-08 20:01:56 +00:00
Mario
18b6d48944 rgister: fixes for registering with invitecode outside of open hours 2021-04-08 19:55:53 +00:00
Mario
f3fa09fc91 register: more ui/ux 2021-04-08 16:06:43 +00:00
Mario
cb2d8b4ba6 register: minor js cleanup 2021-04-08 15:03:05 +00:00
Mario
a9da370c0b register: cleanup template 2021-04-08 14:57:16 +00:00
Max Kostikov
b5620cb794 Merge branch 'dev' into 'dev'
Dev sync

See merge request kostikov/core!1
2021-04-08 14:19:29 +00:00
Mario
cf62e07bec register: default to auto-create channel and fix auto create channel if register approval is configured 2021-04-08 12:38:38 +00:00
Mario
ec4526b5f4 cloud: instead of asking for a page reload when expiriencing a not implemnented exception just go there right away - issue #1556 2021-04-08 08:25:35 +00:00
Mario
806f50eee3 register: more ui/ux work 2021-04-07 20:50:34 +02:00
Mario
6956eadaad registrations: minor cleanup 2021-04-07 17:19:29 +02:00
Mario
9542c1d63c Merge branch 'dev' into 'dev'
air: Fix site admin registration block styles

See merge request hubzilla/core!1938
2021-04-07 14:12:01 +00:00
Mario
81bb02afb7 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-04-06 12:13:24 +00:00
Mario
b8abf806ca bbcode: escape img and zmg tags so that it will not be messed with before required (e.g. URL in image description) - issue #1554 2021-04-06 12:12:51 +00:00
Max Kostikov
0d10f5ba65 Fix site admin registration block styles 2021-04-06 13:41:33 +02:00
Max Kostikov
89409d0577 Merge branch 'dev' into 'dev'
Fix quotes Russian translation

See merge request hubzilla/core!1937
2021-04-06 11:21:10 +00:00
Max Kostikov
144283ca1c Fix quotes 2021-04-06 11:16:47 +00:00
Max Kostikov
c56e2953cf Fix quotes 2021-04-06 11:16:25 +00:00
Max Kostikov
e1d40348ce Update hstrings.php 2021-04-06 11:09:48 +00:00
Max Kostikov
4def370980 Merge branch 'dev' into 'dev'
Update Russian translation

See merge request hubzilla/core!1936
2021-04-06 11:00:14 +00:00
Max Kostikov
54df52675b Revert "Fix mistake"
This reverts commit 9ac5504377
2021-04-06 12:30:03 +02:00
Max Kostikov
12ebdf27c0 Fix variables 2021-04-06 10:27:19 +00:00
Max Kostikov
de0f7ea5d4 Update register_verify_member.tpl 2021-04-06 10:26:26 +00:00
Max Kostikov
72151bc123 Add new file 2021-04-06 10:21:32 +00:00
Max Kostikov
8889abd5a4 Add new file 2021-04-06 10:20:50 +00:00
Max Kostikov
7f7dcd2f33 Fix missprint 2021-04-06 10:18:12 +00:00
Max Kostikov
95c3b1696e Add new formal invitation subject 2021-04-06 10:17:46 +00:00
Max Kostikov
87cd1f87f4 Add formal invitation 2021-04-06 10:16:22 +00:00
Max Kostikov
21c4976a3a Add new invitation subject 2021-04-06 09:59:40 +00:00
Max Kostikov
ec91e51142 Add friendly invitation 2021-04-06 09:56:11 +00:00
Max Kostikov
f1c798e9ac Update Russian hstrings.php 2021-04-06 09:50:44 +00:00
Max Kostikov
f6996f4999 Update Russian hmessages.po 2021-04-06 09:50:21 +00:00
Max Kostikov
9ac5504377 Fix mistake 2021-04-06 09:33:17 +00:00
Mario
91f3c722d6 bump version 2021-04-06 07:57:35 +00:00
Mario
31cf2c688c Merge branch 'dev' into air 2021-04-06 07:55:30 +00:00
Mario
81d3ba5151 do not expire page cache - it does not make much sense actually. 2021-04-06 07:48:09 +00:00
nobody
9359fc065c Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-04-05 23:15:01 -07:00
Max Kostikov
19daadbfd7 Merge branch 'translation-pl' into 'dev'
Upgrading POT, additional translations and next fixes

See merge request hubzilla/core!1935
2021-04-05 20:55:14 +00:00
Andrzej Budziński
0acb371f62 Upgrading POT, additional translations and next fixes 2021-04-05 16:34:30 +02:00
Mario
18d990a034 air: more ui/ux and provide a possibility to lookup your registration id in mod regate (raw and unfinished) 2021-03-28 20:40:26 +00:00
Mario
85b6e352d4 air: fixes 2021-03-28 10:17:54 +00:00
Mario
c389aee112 Merge branch 'air' of https://framagit.org/hubzilla/core into air 2021-03-26 21:04:26 +01:00
Mario
725e57a27a air: more work on UX during register 2021-03-26 20:54:48 +01:00
Mario
9aab47de07 fix timezone issue in mod cal
(cherry picked from commit 6e7c7771bd)
2021-03-26 20:24:51 +01:00
Mario
e6a6723d1f Merge branch 'air' of https://framagit.org/hubzilla/core into air 2021-03-26 19:21:41 +00:00
Mario
6e7c7771bd fix timezone issue in mod cal 2021-03-26 19:20:38 +00:00
Max Kostikov
c609fc71bd Merge branch 'translation-pl' into 'dev'
Fixes and new translations

See merge request hubzilla/core!1934
2021-03-25 19:36:18 +00:00
Mario
b50f1657c3 Merge branch 'air' of https://framagit.org/hubzilla/core into air 2021-03-25 14:00:49 +01:00
Mario
bc1cc65ff2 air: currently it is allowed to register with non-unique did2 (should this be allowed?) - anyway, for now sort them by reg_created to make sure we always match the latest attempt 2021-03-25 14:00:25 +01:00
Andrzej S. Budziński
697e59f9a4 Update hstrings.php 2021-03-25 12:59:45 +00:00
Andrzej Budziński
61d6239c68 Fixes and new translations
1) Changed translations of "a hub" and "a post" ("a hub" like "a node of
network" and not like "a web-hub" or "an air hub".) The word "a post"
should be translated as Polish "wpis" and not jargon "post".
2) New translation: doc/pl/Widgets.md
2021-03-24 23:30:42 +01:00
Mario
eba69f85c7 more work on mod display
(cherry picked from commit 2d716b74b9)
2021-03-24 20:48:42 +01:00
Mario
19b96e37fb Merge branch 'dev' into air 2021-03-24 19:46:07 +00:00
Mario
14186f5c18 cdav: fix regression - sync code was messing with caldav/carddav discovery 2021-03-24 19:41:20 +00:00
Mario
44593a3c8d cdav: fix regression - sync code was messing with caldav/carddav discovery 2021-03-24 19:27:44 +00:00
Mario
4964a32c55 Revalidate imported profile photo on each request (patch provided by Max)
(cherry picked from commit 3d4ad94dcc)
2021-03-24 12:18:32 +01:00
Mario
3d4ad94dcc Revalidate imported profile photo on each request (patch provided by Max) 2021-03-24 11:16:03 +00:00
Mario
6d5f98072d php8: fix fatal errors
(cherry picked from commit 1a15c775f8)
2021-03-24 11:39:19 +01:00
Mario
1a15c775f8 php8: fix fatal errors 2021-03-24 09:21:58 +00:00
Mario
2d716b74b9 more work on mod display 2021-03-23 11:38:42 +00:00
Mario
cc9fd4f4a4 fix regression in mod display
(cherry picked from commit 43c5b72317)
2021-03-23 12:05:40 +01:00
Mario
43c5b72317 fix regression in mod display 2021-03-23 10:54:27 +00:00
Mario
2856ea6370 Merge branch 'dev' into air 2021-03-23 09:56:46 +00:00
Max Kostikov
67d65d878d Merge branch 'dev' into 'dev'
Fix DAV calendars and addressbooks sync on remote access

See merge request hubzilla/core!1931
2021-03-22 14:21:38 +00:00
Max Kostikov
e19bb63857 Merge branch 'translation-pl' into 'dev'
Translation pl

See merge request hubzilla/core!1930
2021-03-22 14:20:56 +00:00
Max Kostikov
dbc5e54a92 Fix DAV calendars and addressbooks sync on remote access 2021-03-22 14:16:54 +00:00
Mario
b8913335b1 those are not actually needed by the handler
(cherry picked from commit 872ac8846e)
2021-03-22 13:51:44 +01:00
Mario
872ac8846e those are not actually needed by the handler 2021-03-22 13:51:11 +01:00
Mario
8c16171855 sse: make sure to also bootstrap info and notice
(cherry picked from commit 598c3aa336)
2021-03-22 13:43:00 +01:00
Mario
2e47ef38a9 libsync fix from zap: look for hubloc_updated instead of hubloc_connected which would always be true
(cherry picked from commit ccefb99cbe)
2021-03-22 13:42:01 +01:00
Mario
81b4d919e5 do not treat an URL including an @ like a webbie
(cherry picked from commit 35ce7dbeab)
2021-03-22 13:41:39 +01:00
Mario
f6d88f20f3 Merge branch 'air' of https://framagit.org/hubzilla/core into air 2021-03-22 13:37:31 +01:00
Mario
598c3aa336 sse: make sure to also bootstrap info and notice 2021-03-22 13:37:01 +01:00
Mario
ccefb99cbe libsync fix from zap: look for hubloc_updated instead of hubloc_connected which would always be true 2021-03-22 10:12:57 +00:00
Mario
35ce7dbeab do not treat an URL including an @ like a webbie 2021-03-22 10:01:32 +00:00
Mario
74610aca6f Merge branch 'air' of https://framagit.org/hubzilla/core into air 2021-03-22 10:29:54 +01:00
Mario
02d4c5ac90 Merge branch 'air' of https://framagit.org/hubzilla/core into air 2021-03-22 09:29:23 +00:00
Mario
7f35dda5cc Merge branch 'dev' into air 2021-03-22 10:28:08 +01:00
Mario
13355d42f7 air security: saving the password as hex string is not acceptable 2021-03-22 09:50:12 +01:00
Andrzej Budziński
77e82d7475 Fixes (Translation.md, hstrings.php) 2021-03-21 19:54:22 +01:00
Andrzej Budziński
da2df4eb55 Fixes and next translations (doc/pl/Plugins.md) 2021-03-21 18:17:06 +01:00
Mario
62fbdf3f63 Merge branch 'air' into 'air'
adminUI cfg to switch on (default off) register w/o email, Issue Air #1539

See merge request hubzilla/core!1927
2021-03-20 16:01:21 +00:00
Mario
554745a25a air: do not require to verify emailaddress once more after invite code got verified - fixes #1546 but probably still requires some finetuning. 2021-03-20 16:57:11 +01:00
Hilmar R
e12c0ca3dc adminUI cfg to switch on (default off) register w/o email,
accept delay 0 (no delay) and expire defaults to 99years
2021-03-19 21:10:01 +01:00
Mario
a18e297a26 Merge branch 'dev' into air 2021-03-19 20:07:59 +00:00
Mario
2d82e1bd6b Merge branch 'dev' into 'dev'
Implement custom Redis session backend

See merge request hubzilla/core!1926
2021-03-19 20:07:00 +00:00
Max Kostikov
7476d8dccc Implement custom Redis session backend 2021-03-19 20:06:59 +00:00
Mario
04b96e2cdc air: php8 asort() argument cannot be passed by reference 2021-03-19 12:06:38 +01:00
Mario
7375824ed4 air: missing module 2021-03-19 11:45:40 +01:00
Mario
06d47deef8 air: improved UX by changing the registration workflow so that it is not required to go back to registration and post the DID. If no registration delay is configured proceed directly to verification. fixes #1540 2021-03-19 11:43:48 +01:00
Mario
85d000e792 air: revert min_livetime of the form security token - it has had its issues and air can be configured for delayed registration verification 2021-03-18 19:51:30 +00:00
Mario
3ac27d8004 air: display the verification status in the notifications 2021-03-18 19:41:12 +00:00
Mario
854a6e3787 air: only set registration request to expired if it is not yet verified 2021-03-18 14:56:53 +00:00
Mario
a36dd5a8b9 adjust timezone after the expiration check 2021-03-18 14:47:37 +00:00
Mario
7c620cbe24 air: make sure to display the timezone corrected times in the admin ui 2021-03-18 14:42:30 +00:00
Mario
7472b96c95 Merge branch 'air' of https://framagit.org/hubzilla/core into air 2021-03-18 14:55:28 +01:00
Mario
3ba42d3dcf air: deal with timezones when displaying open/close time - this should finally fix issue #1544 2021-03-18 14:55:01 +01:00
Mario
eb3a40b07a use lib/keyutils rsatopem()
(cherry picked from commit f0cce1c902)
2021-03-18 09:37:55 +01:00
Mario
f0cce1c902 use lib/keyutils rsatopem() 2021-03-18 08:35:09 +00:00
Mario
9f26b7aa9c air: convert utc to local in browser (we do not have a client timezone othervise at this point) - issue #1544 2021-03-17 17:49:13 +01:00
Mario
febf766be0 air: make sure we always save date_time in UTC - issue #1544 2021-03-17 14:37:16 +01:00
Mario
35d9fd4860 air: another string 2021-03-17 12:24:19 +01:00
Mario
4581abb6d1 air: some work on ui/ux 2021-03-17 12:14:55 +01:00
Mario
8d3c5114ba use html2plain for summary
(cherry picked from commit 80b6954c29)
2021-03-17 10:13:55 +01:00
Mario
80b6954c29 use html2plain for summary 2021-03-17 09:13:09 +00:00
Mario
da37548e2e also move code comments to the function 2021-03-16 12:33:41 +01:00
Mario
c658bbca24 simplify get_pending_accounts query so that it will work in postgres. this will introduce a regression in rendering the table background color. 2021-03-16 12:32:20 +01:00
Mario
3b9a9db664 fix cover photo image issues on some mobile devices
(cherry picked from commit 4e921cfdcf)
2021-03-16 10:13:55 +01:00
Mario
4e921cfdcf fix cover photo image issues on some mobile devices 2021-03-16 09:09:13 +00:00
Mario
bd24224b76 air: fix register notifications 2021-03-15 12:45:39 +00:00
Mario
a5ac388889 air: fix calculate_adue() to return false if the value is zero and do not hardcode regexpire - adding the max setting (99 years) should be fine. 2021-03-15 10:31:23 +00:00
Mario
4be123dc84 fix default value displayed if value is set to empty or zero. fix #1536 and #1537 2021-03-15 10:10:08 +00:00
Mario
0ebb1f685f version 5.4.2 2021-03-15 08:55:46 +00:00
Mario
805a25eb62 more changelog
(cherry picked from commit 268464ccde)
2021-03-15 08:54:16 +00:00
Mario
4ca12afc9d changelog
(cherry picked from commit cb74de7472)
2021-03-15 08:54:05 +00:00
Mario
6cfa2572a8 do not parse bbcode in summary - issue #1532 2021-03-15 08:50:53 +00:00
Mario
04ec986bf7 cleanup
(cherry picked from commit 0fbd0ca416)
2021-03-15 08:50:29 +00:00
Max Kostikov
ee453c4acc Fix plurals variable 2021-03-15 08:50:13 +00:00
Mario
4d3524ba9d mod subthread issue continued
(cherry picked from commit b6d30f6734)
2021-03-15 08:49:53 +00:00
Mario
29beea28c2 fix mod subthread for zot6
(cherry picked from commit 22d769ecae)
2021-03-15 08:48:40 +00:00
Mario
e2a289d614 truncate too long text
(cherry picked from commit 1582b8bc96)
2021-03-15 09:43:18 +01:00
Mario
59d3483a06 save the rewritten llink
(cherry picked from commit db0e1c9f31)
2021-03-15 09:43:08 +01:00
Mario
a99161abdf if rewriting the mid also rewrite the llink
(cherry picked from commit 260c518562)
2021-03-15 09:42:56 +01:00
Mario
79d48dc92b fix mod display query
(cherry picked from commit b51049227f)
2021-03-15 09:42:41 +01:00
Mario
becb898a51 more changelog
(cherry picked from commit 268464ccde)
2021-03-15 09:36:37 +01:00
Mario
268464ccde more changelog 2021-03-15 08:36:00 +00:00
Mario
57aa96c412 changelog
(cherry picked from commit cb74de7472)
2021-03-15 09:34:00 +01:00
Mario
cb74de7472 changelog 2021-03-15 08:33:26 +00:00
Mario
d35849c418 Merge branch 'dev' into air 2021-03-14 20:29:29 +00:00
Mario
a9a112e063 php8: fix some undefined variables
(cherry picked from commit ed64eba13a)
2021-03-14 21:25:45 +01:00
Mario
1e87fe6b49 cleanup
(cherry picked from commit 0fbd0ca416)
2021-03-14 21:24:56 +01:00
Mario
ed64eba13a php8: fix some undefined variables 2021-03-14 20:23:33 +00:00
Mario
0fbd0ca416 cleanup 2021-03-14 19:23:02 +00:00
Max Kostikov
0a31267b1b Fix plurals variable 2021-03-14 11:43:47 +00:00
Mario
97c7b010ed mod subthread issue continued
(cherry picked from commit b6d30f6734)
2021-03-14 10:03:03 +01:00
Mario
b6d30f6734 mod subthread issue continued 2021-03-14 09:01:12 +00:00
Mario
b9e1c38773 fix mod subthread for zot6
(cherry picked from commit 22d769ecae)
2021-03-13 23:22:08 +01:00
Mario
22d769ecae fix mod subthread for zot6 2021-03-13 22:13:17 +00:00
Mario
45ecd1b127 revert default profile image 2021-03-12 10:50:25 +00:00
Mario
3f053611bd Merge branch 'dev' into air 2021-03-12 10:07:15 +00:00
Mario
1582b8bc96 truncate too long text 2021-03-12 09:54:01 +00:00
Mario
432e7e9714 revert follow_failover hook - there is a cleaner solution 2021-03-12 09:06:20 +00:00
Mario
31e237729c introduce the follow_failover hook 2021-03-11 21:58:45 +00:00
Mario
d2b03f6a9b more add interactive flag 2021-03-11 20:11:05 +00:00
Mario
51fe5ec982 add interactive flag 2021-03-11 19:33:03 +00:00
Mario
ce9b01ce84 Merge branch 'php8fixes' into 'dev'
Stricter item array checks

See merge request hubzilla/core!1925
2021-03-11 17:51:14 +00:00
Max Kostikov
024b489af9 Stricter item array checks 2021-03-11 17:51:13 +00:00
Mario
f980c2e3de php8: daily warning fixes (deriving from mod network) 2021-03-11 13:03:54 +00:00
Mario
db0e1c9f31 save the rewritten llink 2021-03-11 08:25:26 +00:00
Mario
260c518562 if rewriting the mid also rewrite the llink 2021-03-10 20:44:20 +00:00
Mario
689603de82 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-03-10 20:35:13 +00:00
Mario
b51049227f fix mod display query 2021-03-10 20:34:47 +00:00
Max Kostikov
0a86efc631 Merge branch 'php8fixes' into 'dev'
Check for HTTP port use on URL build

See merge request hubzilla/core!1924
2021-03-10 19:52:05 +00:00
Max Kostikov
f8467845d2 Check for HTTP port use 2021-03-10 19:44:54 +00:00
Max Kostikov
9098bb431c Check for HTTP port use 2021-03-10 19:44:17 +00:00
Max Kostikov
86ed4f4f99 Check for HTTP port use 2021-03-10 19:44:02 +00:00
Max Kostikov
7795224e70 Check for HTTP port use 2021-03-10 19:43:42 +00:00
Max Kostikov
b729cee9e4 Merge branch 'dev' into 'dev'
Dev sync

See merge request kostikov/core!1
2021-03-10 19:41:46 +00:00
Mario
15bc5c64f3 php8: isset() returns true if the array key exists but is empty. We need to check with empty() here. 2021-03-10 16:28:05 +00:00
Mario
440a132c6b Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-03-10 13:18:12 +00:00
Mario
f8447521a8 php8: random fixes deriving from mod network 2021-03-10 13:16:08 +00:00
Mario
c8050ea865 Merge branch 'php8fixes' into 'dev'
More PHP 8 fixes

See merge request hubzilla/core!1923
2021-03-10 11:14:03 +00:00
Max Kostikov
11d831e4d7 More PHP 8 fixes 2021-03-10 11:14:02 +00:00
Mario
15faf01ec9 do not parse bbcode in summary - issue #1532 2021-03-10 11:09:49 +00:00
Mario Vavti
82192d1ead a possible fix for issue #1529
(cherry picked from commit 7ee495624e)
2021-03-09 21:40:43 +01:00
Mario Vavti
7ee495624e a possible fix for issue #1529 2021-03-09 21:36:28 +01:00
Mario
64bbbc8053 Version 5.4.1 2021-03-09 19:07:33 +00:00
Mario Vavti
4d3d868d19 changelog
(cherry picked from commit 45cc2d7bd8)
2021-03-09 19:58:40 +01:00
Mario Vavti
45cc2d7bd8 changelog 2021-03-09 19:53:25 +01:00
Max Kostikov
15b45af550 Revert "Check if we have an observer xchan"
This reverts commit 91ebfbc215
2021-03-09 16:59:44 +01:00
Max Kostikov
91ebfbc215 Check if we have an observer xchan 2021-03-09 15:58:26 +00:00
Max Kostikov
011342ac1b Fix undefined page end on non dynamic pages
(cherry picked from commit 182dec3e57)
2021-03-09 12:14:38 +01:00
Max Kostikov
5577383a48 Fix Spanish plural expression
(cherry picked from commit f952d65cfd)
2021-03-09 12:13:22 +01:00
Mario
dc336010db type submit should not be type button
(cherry picked from commit b09cbb72fb)
2021-03-09 12:12:53 +01:00
Mario
88fbeaddb0 fix unexpected trigger of buttons when pressing enter in input field issue #1528
(cherry picked from commit d57f4a9527)
2021-03-09 12:12:20 +01:00
Mario
7612d8246e fix summary not saved in browser autosave draft
(cherry picked from commit 8d26961639)
2021-03-09 12:11:39 +01:00
Mario
53bb16e799 fix summary not reset on cancel
(cherry picked from commit 0932d2a0a6)
2021-03-09 12:11:09 +01:00
Mario
ed04104250 fix profile not found if not logged in
(cherry picked from commit ed981ec8e8)
2021-03-09 12:10:27 +01:00
Mario
ee40cb337a Merge branch 'php8-netstream' into 'dev'
Fix network stream scrolling with PHP 8

See merge request hubzilla/core!1922
2021-03-09 11:05:43 +00:00
Max Kostikov
bdae290ec4 Revert "More checks on note decoding"
This reverts commit 20199f7aee34dbc7a8aebcd459ef6cb84cdb5bd7
2021-03-09 11:05:43 +00:00
Mario
53c3d0d53d Merge branch 'php8' into 'dev'
Stricter parameters checks for PHP 8 support

See merge request hubzilla/core!1921
2021-03-09 11:02:28 +00:00
Mario
ed981ec8e8 fix profile not found if not logged in 2021-03-09 10:47:13 +00:00
Max Kostikov
723d757091 Change set_linkified_perms() arguments order 2021-03-09 09:08:33 +00:00
Max Kostikov
92ada6eb98 Change set_linkified_perms() arguments order 2021-03-09 09:07:47 +00:00
Max Kostikov
975d8ef0c7 Fix deprecated function arguments order 2021-03-09 09:06:16 +00:00
Max Kostikov
65e9ff357b More checks on note decode 2021-03-08 21:16:24 +00:00
Max Kostikov
66495e6838 Check propeties existance on note decode 2021-03-08 21:06:26 +00:00
Max Kostikov
efe65e1ba8 Fix undefined edited and created checks 2021-03-08 20:57:02 +00:00
Max Kostikov
6b500ee3e1 Check if BBcode field exist 2021-03-08 20:52:39 +00:00
Max Kostikov
1ad6308f97 Formatting 2021-03-08 20:43:29 +00:00
Max Kostikov
5d82bf946e Check if properties were provided on taxonomy decode 2021-03-08 20:35:03 +00:00
Max Kostikov
c8fe56e57d Check if oStatus conversation exists 2021-03-08 20:30:14 +00:00
Max Kostikov
88b6353465 More checks on attachments decode 2021-03-08 20:13:08 +00:00
Max Kostikov
4afddabe15 Fix missed tag warning on decode taxonomy 2021-03-08 20:09:49 +00:00
Max Kostikov
360ae9080e Fix actor store warnings on non defined properties 2021-03-08 20:06:36 +00:00
Max Kostikov
956aec1448 Check if item have a mention 2021-03-08 20:00:59 +00:00
Max Kostikov
4bcd093bef Check for attachments in item 2021-03-08 19:50:55 +00:00
Max Kostikov
f62b294a72 Check if terms are defined as array for item 2021-03-08 19:46:27 +00:00
Max Kostikov
c2adf1dcd1 Check if 'attach' and 'iconfig' array are defined 2021-03-08 19:40:40 +00:00
Mario
0932d2a0a6 fix summary not reset on cancel 2021-03-08 19:40:32 +00:00
Max Kostikov
e451284256 Check if port in the site URL provided 2021-03-08 19:35:45 +00:00
Mario
49f12695cf Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-03-08 19:25:12 +00:00
Mario
8d26961639 fix summary not saved in browser autosave draft 2021-03-08 19:25:01 +00:00
Max Kostikov
c9ec5043b9 Check if HTTP port is defined 2021-03-08 19:22:17 +00:00
Max Kostikov
03bfb8a46f Define $sql_extra2 variable before extending 2021-03-08 19:21:38 +00:00
Max Kostikov
0c5a7ab19b Define $sql_extra2 variable before concatenation 2021-03-08 19:16:41 +00:00
Mario
1561e4a89c Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-03-08 19:15:39 +00:00
Mario
b09cbb72fb type submit should not be type button 2021-03-08 19:14:14 +00:00
Mario
d57f4a9527 fix unexpected trigger of buttons when pressing enter in input field issue #1528 2021-03-08 19:12:37 +00:00
Mario
0e015d52a5 Merge branch 'dev' into 'dev'
Fix undefined page end on non dynamic pages

See merge request hubzilla/core!1920
2021-03-08 19:08:50 +00:00
Max Kostikov
7e0416ac97 Remove unusable variable $sql_query 2021-03-08 19:05:03 +00:00
Max Kostikov
98112497ba Fix Spanish plural expression 2021-03-08 15:59:12 +00:00
Max Kostikov
f952d65cfd Fix Spanish plural expression 2021-03-08 15:48:44 +00:00
Max Kostikov
182dec3e57 Fix undefined page end on non dynamic pages 2021-03-08 15:33:26 +00:00
Max Kostikov
8ab6076566 Merge branch 'dev' into 'dev'
# Conflicts:
#   boot.php
2021-03-08 15:20:38 +00:00
mjfriaza
6506cab55b Update Spanish 2021-03-08 10:28:26 +00:00
mjfriaza
97e483d684 Update Spanish 2021-03-08 10:26:38 +00:00
Mario
fe638c88e0 fix dev version 2021-03-08 10:16:00 +00:00
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
Max Kostikov
cf7f380568 Merge branch 'dev' into 'dev'
# Conflicts:
#   boot.php
2021-03-03 20:05:37 +00:00
Max Kostikov
7e36727ce6 Fix frame-src CSP error on video embedding 2021-03-03 20:01:39 +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
Hilmar R
c29261487c a bit more useability for the admin at the beginning 2021-03-03 12:59:19 +01:00
Hilmar R
c3229643d0 embarrassing :-( 2021-03-02 22:23:58 +01:00
Hilmar R
2b03e51bfc did2 chk num 5...10 2021-03-02 18:45:13 +01:00
Hilmar R
4cc72db463 hope not to hurry too fast when saying 5.4RC2. But today & tomorrow is only for the tests 2021-03-02 16:11:18 +01:00
Hilmar R
d434490bdf melt include/account 2021-03-02 15:54:51 +01:00
Hilmar R
2c15efbf48 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-03-01 20:26:44 +01:00
Hilmar R
c26dede97f get dev 2021-03-01 18:48:11 +01:00
Max Kostikov
1d899d387e Merge branch 'dev' into 'dev'
Dev sync

See merge request kostikov/core!2
2021-02-27 19:47:26 +00:00
Hilmar R
ea3390d626 adjust air.5 to be in sync with 5.2.2 2021-02-26 15:10:24 +01:00
Hilmar R
a04ded9cca repair dd tag and set unique vsn 2021-02-26 14:38: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
nobody
878be8fff0 small adjustment (effects export output but is correctly handled by import) 2021-02-24 11:48:28 -08:00
nobody
beb418b093 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-02-24 11:38:38 -08: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
nobody
0f89d2b8e0 some content fields found in the wild are actually arrays 2021-02-23 15:37:58 -08: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
nobody
fc88c306ab some minor issues uncovered during hubzilla->zap export testing 2021-02-22 17:23:08 -08: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
nobody
5664f5e0a2 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-02-18 21:42:15 -08: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
nobody
136bc13ff6 forgot these 2021-02-17 21:50:11 -08:00
nobody
62b738da95 migration testing 2021-02-17 19:42:58 -08:00
nobody
e7c7f91a3f Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-02-17 16:37:19 -08:00
nobody
8a65fc8a43 more work on hz->zap migration stuff 2021-02-17 16:36:27 -08: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
nobody
0b95e061a3 more zap export work 2021-02-17 01:15:07 -08:00
nobody
383917eb0f more zap export compatibility work 2021-02-17 01:05:30 -08:00
nobody
7e3046b85c more work on zap channel export. 2021-02-16 23:38:17 -08: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
f94b046333 changelog
(cherry picked from commit 5e8e6dc458)
2021-02-13 21:23:04 +01:00
Mario
5e8e6dc458 changelog 2021-02-13 20:20:46 +00:00
Mario
9751efb709 version 5.2.2 2021-02-13 21:17:13 +01:00
Mario
7b2f53cc69 fix ping_site() issue
(cherry picked from commit 22e0175ab7)
2021-02-13 21:15:49 +01: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
Andrzej Budziński
f4ecc0dfb9 Fixes:
- view/pl/hmessages.mo
- view/pl/hmessages.po
- view/pl/hstrings.php
2021-02-05 04:11:52 +01:00
Andrzej Budziński
111ae9812c Fixes:
- view/pl/hmessages.mo
- view/pl/hmessages.po
- view/pl/hstrings.php
2021-02-04 23:53:25 +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
Andrzej Budziński
ba73845bad Merge branch 'dev' into translation-pl 2021-02-03 15:00:24 +01:00
Andrzej Budziński
7ece28b981 Fixes:
- view/pl/hmessages.mo
- view/pl/hmessages.po
- view/pl/hstrings.php
2021-02-03 14:58:06 +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
Andrzej Budziński
5799a073fe Fixes:
- doc/pl/admin/administrator_guide.md
- doc/pl/about/project.bb
- doc/pl/TermsOfService.md
2021-02-03 02:19:27 +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
Andrzej Budziński
85b1bc7929 Fixes:
- doc/pl/feature/additional/overview.md
2021-02-02 03:17:25 +01:00
Andrzej Budziński
de36172af3 Fixes:
- doc/pl/feature/additional/overview.md
2021-02-02 03:09:04 +01:00
Andrzej Budziński
f5fba51f5c Fixes:
- doc/context/pl/settings/features/help.html: fixes
2021-02-02 03:00:19 +01:00
Andrzej Budziński
a2185c7886 Polish translatons - fixes, typos, and new translation
1) view/pl/messages.po: fixes & typos
2) doc/pl/admin/administrator_guide.md: fixes & typs
3) doc/pl/feature/*: new translations (needed work yet)
4) doc/pl/Features.md: fixes
5) doc/context/pl/cards/help.html: fixes
6) doc/context/pl/settings/features/help.html: fixes
7) doc/context/pl/settings/tokens/help.html: fixes
8) view/pl/register_verify_member.tpl: fixes
2021-02-02 02:50:13 +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
Hilmar R
fae5515350 forgotten docs 2021-01-30 23:19:03 +01:00
Hilmar R
68d5969d33 validate,invite 2021-01-30 23:15:13 +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
Hilmar R
3773bceb46 context help register en,de 2021-01-29 23:25:47 +01:00
Mario
7686b48723 code format only 2021-01-29 07:36:56 +00:00
Hilmar R
4ecb4189b8 Register panel interaction consistence usage 2021-01-28 22:08:38 +01: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
Hilmar R
d0d6170a71 login panel, reg limits. 2021-01-27 00:20:18 +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
Hilmar R
cd98e75a42 Two field positions 2021-01-24 23:53:28 +01: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
Hilmar R
3f031399cb auto channel create adjustments 2021-01-24 20:59:11 +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
Hilmar R
0a16674f6e auto channel create adjustments, zar log reg msgs 2021-01-24 16:44:58 +01:00
Mario
4fbedb6750 extra check for item_private in fetch_and_store_parents() 2021-01-24 15:00:01 +00:00
Hilmar R
9365b8691e 2 fields dups removed 2021-01-23 23:58:20 +01: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
Hilmar R
33825ba0b4 typo 2021-01-23 16:08:16 +01:00
Hilmar R
67db1c6e9b melt diff prod fork 4.6.2 air onto 5.2.1 to 5.2.2 DB 1241 2021-01-23 15:24:24 +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
Hilmar R
abdf6f40a2 at end of day, some files probably without conflicts so far 2021-01-23 00:08:25 +01: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
Hilmar R
523765b968 Merge branch 'master' into air.5 2021-01-22 01:38:43 +01: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
254e30bea1 version 5.2.1 2021-01-16 10:33:46 +01:00
Mario
a16692eeb0 changelog
(cherry picked from commit 485a232ae6)
2021-01-16 10:33:13 +01:00
Mario
485a232ae6 changelog 2021-01-16 09:31:51 +00:00
Mario
d3f8118874 wrong logic
(cherry picked from commit 0d544e2294)
2021-01-16 10:18:29 +01:00
Mario
0d544e2294 wrong logic 2021-01-16 09:17:45 +00:00
Mario
cb3131a166 also check for zot6
(cherry picked from commit 3bcb322156)
2021-01-16 10:14:16 +01:00
Mario
3105f514e4 make attach_upgrade() catch entries where only display_path is missing
(cherry picked from commit 42812078c5)
2021-01-16 10:13:43 +01: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
Mario
5eefdc6485 Merge branch '5.2RC' 2021-01-13 09:50:53 +00:00
Mario
4d2bcbc583 release 5.2 2021-01-13 09:48:47 +00:00
Mario
299c4bda1b update changelog 2021-01-13 09:47:44 +00:00
Mario
f4b9291d42 Merge branch 'dev' into 5.2RC 2021-01-13 09:39:55 +00:00
Mario
b7afc905ec Revert "keyid adapt for backward compatibility to current release part 2"
This reverts commit efb8a29b5f.
2021-01-13 09:34:38 +00:00
Mario
01bd846433 Revert "keyid adapt for backward compatibility to current release"
This reverts commit ff100a499a.
2021-01-13 09:34:03 +00:00
Mario
08f717d4fc Merge branch 'dev' into 5.2RC 2021-01-13 09:01:31 +00:00
Mario
b9fd87b004 do not turn the groups own direkt messages into group items - fixes #1510 2021-01-13 08:54:58 +00:00
Mario
1615f2c79a Merge branch 'dev' into 5.2RC 2021-01-12 09:08:28 +00:00
Mario
f430db0de7 changelog 2021-01-12 09:04:32 +00:00
Mario
32eb603643 lukasreschke/id3parser is not maintained anymore. fix it so that composer dump-autoload will not complain 2021-01-12 08:52:08 +00:00
Mario
c3f387f22a more changelog 2021-01-12 08:35:22 +00:00
Mario
8703caff5f restrict length of short profile title/description to 190characters to omit sql warnings about too long string data 2021-01-12 08:25:09 +00:00
Mario
c5d50c9e47 Ãupdate changelog 2021-01-11 20:33:17 +00:00
Mario
fed4e3e03a Ãupdate changelog 2021-01-11 20:32:33 +00:00
Mario
9d1f73e179 5.2RC4 2021-01-11 19:02:26 +00:00
Mario
ba164d9488 Merge branch 'dev' into 5.2RC 2021-01-11 19:01:02 +00:00
Mario
3fe67eb646 more libzotdir
(cherry picked from commit e339e897ff)
2021-01-11 19:55:07 +01:00
Mario
12ba2c30b9 can not access global from statc method 2021-01-11 08:59:16 +00:00
Mario Vavti
7c1b41019e missing constant definition 2021-01-10 22:42:57 +01:00
Mario Vavti
707110e5a7 sync_directories() omit known dead sites 2021-01-10 21:46:31 +01:00
Mario Vavti
ba9a9cb016 undefined variable 2021-01-10 21:32:42 +01:00
Mario
c1c75c4b67 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-01-10 00:32:45 +00:00
Mario
0446349b89 missing use statement 2021-01-10 00:32:34 +00:00
Mario Vavti
915cb44601 typo 2021-01-09 23:06:56 +01:00
Mario
17a153fb6d Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-01-09 21:54:55 +00:00
Mario
e339e897ff more libzotdir 2021-01-09 21:54:41 +00:00
Mario
6b57f163bd fix markup
(cherry picked from commit 4ace4819ff)
2021-01-09 22:05:40 +01:00
Mario
4ace4819ff fix markup 2021-01-09 22:04:47 +01:00
mjfriaza
ce893122af Update Spanish translation
(cherry picked from commit c90d1fc8ef)
2021-01-09 22:02:35 +01:00
Mario
fb5188a8c6 Merge remote-tracking branch 'codeberg/dev' into dev 2021-01-09 21:01:24 +00:00
hubzilla
c17f452fc7 Merge pull request 'Update Spanish translation' (#2) from mjfriaza/hubzilla:dev into dev
Reviewed-on: https://codeberg.org/hubzilla/hubzilla/pulls/2
2021-01-09 21:59:22 +01:00
Mario
71b0f54b7a update sbom 2021-01-09 20:55:40 +00:00
Mario
d387d021fe update sbom 2021-01-09 20:54:48 +00:00
Mario
d6fefc3603 5.2RC3 2021-01-09 20:34:21 +00:00
Mario
efb8a29b5f keyid adapt for backward compatibility to current release part 2 2021-01-09 20:20:48 +00:00
Mario
ff100a499a keyid adapt for backward compatibility to current release 2021-01-09 19:57:55 +00:00
Mario
d89dc65330 remove redundant mail.apd
(cherry picked from commit 898df6287a)
2021-01-09 20:33:12 +01:00
Mario
fa41527f85 fix some php8 fatal errors
(cherry picked from commit 2522d42c71)
2021-01-09 20:32:40 +01:00
Mario
f48d844e42 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-01-09 19:27:46 +00:00
Mario
898df6287a remove redundant mail.apd 2021-01-09 19:27:32 +00:00
Mario
2522d42c71 fix some php8 fatal errors 2021-01-09 20:22:47 +01:00
Mario
39c5e85564 RC2 2021-01-09 15:50:57 +01:00
Mario
1294c05a91 version 2021-01-09 13:27:57 +00:00
Mario
64f802d4f6 fix error in sql query
(cherry picked from commit 0e2af40329)
2021-01-09 14:25:41 +01:00
Mario
61e782389c more streamline keyid 2021-01-09 13:24:32 +00:00
Mario
7cfb230a5e streamline keyid 2021-01-09 13:22:43 +00:00
Mario
0e2af40329 fix error in sql query 2021-01-09 13:05:31 +00:00
Mario
7f51ff0a8d set resource_type = group_item and resource_id = original mid for forum items so we do not need to query the body for the original mid on edit. 2021-01-08 21:27:06 +00:00
Mario Vavti
d1a61c6dce allow deletes for e.g. w2w posts where we are the author but item wall is not set. ownership is checked at the receiving side anyway 2021-01-08 13:12:01 +01:00
mjfriaza
c90d1fc8ef Update Spanish translation 2021-01-08 11:29:32 +01:00
Mario
42cd046e90 RC1 2021-01-06 20:37:04 +01:00
Mario
52fa350138 error in logic
(cherry picked from commit 16082456df)
2021-01-06 20:35:16 +01:00
Mario
4ea8357c6a remove logging
(cherry picked from commit 49cc69ecc5)
2021-01-06 20:35:03 +01:00
Mario
dd0da70b06 filter out self and child folders from the folder list
(cherry picked from commit a0c8e1959a)
2021-01-06 20:34:49 +01:00
Mario
d80f2a621d simplify attach_folder_select_list()
(cherry picked from commit c7010dac3c)
2021-01-06 20:33:59 +01:00
Mario
16082456df error in logic 2021-01-06 19:32:36 +00:00
Mario
49cc69ecc5 remove logging 2021-01-06 19:27:26 +00:00
Mario
a0c8e1959a filter out self and child folders from the folder list 2021-01-06 19:26:40 +00:00
Mario
c7010dac3c simplify attach_folder_select_list() 2021-01-06 19:22:29 +00:00
Mario
99bfc3aaa0 version 5.3 2021-01-05 08:48:30 +00:00
Mario
43b3922803 dump autoload 2021-01-05 08:45:23 +00:00
Mario
ca70ad1a9f version and strings 2021-01-05 08:44:10 +00:00
Mario Vavti
a250419b59 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-01-04 20:36:37 +01:00
Mario Vavti
291644f29d fix issue where categories were not saved on forum wall post 2021-01-04 20:36:24 +01:00
Mario
d4e97ab64c more work on tiles 2021-01-04 13:43:46 +00:00
Mario
e92f98d3c6 rounded corners 2021-01-04 11:14:01 +00:00
Mario
999aac19de missing translateable string and adapt icons 2021-01-04 11:09:12 +00:00
Mario
b2f6e5673d some work on the tiles view 2021-01-04 10:58:41 +00:00
Mario
f0d1c962a7 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-01-03 20:18:05 +00:00
Mario
6999b8d9b4 fix no channel_id provided for contact_remove() in reply_purge(). fix wrong notifier command 2021-01-03 20:17:45 +00:00
Max Kostikov
46e704d507 Merge branch 'dev' into 'dev'
Update Russian translation

See merge request hubzilla/core!1892
2021-01-03 17:05:03 +01:00
Max Kostikov
308e94ea79 Update hstrings.php 2021-01-03 16:43:45 +01:00
Max Kostikov
0c839b2738 Update hmessages.po 2021-01-03 16:43:22 +01:00
Mario
cff5859c59 mod cloud strings 2021-01-03 14:28:02 +00:00
Mario
6d95f5fc98 files_ng: slightly change the way we display link bbcode 2021-01-03 10:07:54 +00:00
Mario
7684861249 do not check against undefined variable 2021-01-02 21:37:06 +00:00
Mario
9759cb7075 fix typo 2021-01-02 21:18:49 +00:00
Mario
b3a5f9bef4 wrong variable 2021-01-02 21:10:47 +00:00
Mario
3e3b6cc1e1 wrong variable 2021-01-02 21:01:42 +00:00
Mario
474103dc82 remove unused code and fix width and height not defined 2021-01-02 20:56:18 +00:00
Mario
092a8f2d05 fix wrong variable 2021-01-02 20:39:58 +00:00
Mario
2bcf0c354a fix wrong variable 2021-01-02 20:39:47 +00:00
Mario
73cc756cac fix wrong variable 2021-01-02 20:38:56 +00:00
Mario
6091c2dba0 fix wrong variable 2021-01-02 20:38:44 +00:00
Mario
2862a73253 fix typo 2021-01-02 20:38:11 +00:00
Mario
850c3f2b6a fix typos 2021-01-02 18:58:20 +00:00
Mario
98f3e4cbd3 set is_owner does not need to be a per item flag. fix post button visible for collections 2021-01-02 18:53:23 +00:00
Mario
efc8ed4845 make share title h3 2021-01-02 11:20:03 +00:00
Mario
0bc4c7d1a0 version 5.0.8 2020-12-30 15:01:17 +00:00
Mario
be2e754d78 changelog
(cherry picked from commit 817e72846e)
2020-12-30 15:59:13 +01:00
Mario
817e72846e changelog 2020-12-30 14:55:00 +00:00
Mario
220768bffc escape both single and double quotes for the notifications title. fixes issue #1503
(cherry picked from commit 11d61a744d)
2020-12-30 15:40:15 +01:00
Mario Vavti
3cd64bcb22 random_profile: return zot6 entries
(cherry picked from commit 5cefdbf985)
2020-12-30 15:40:03 +01:00
Mario Vavti
86bfb07c29 dirserach: return zot6 entries
(cherry picked from commit 5485f96625)
2020-12-30 15:39:48 +01:00
Max Kostikov
ad08bd62aa Revert "Fix sync item with Zot connections"
This reverts commit 3db4aa69440553788d8f46cf4bbfb38ca4f09130


(cherry picked from commit c063fe0720)
2020-12-30 15:39:33 +01:00
Max Kostikov
d79cab0680 Deduplicate contacts list on autocomplete
(cherry picked from commit d889547b26)
2020-12-30 15:38:26 +01:00
Mario
d1d6f7d838 sse: fix issue with direct message notificationss
(cherry picked from commit d5eeb948d5)
2020-12-30 15:38:09 +01:00
Max Kostikov
e31a7e5c9d Do not revalidate cached photos
(cherry picked from commit ca051e943f)
2020-12-30 15:37:47 +01:00
Max Kostikov
e6f0d9887c Implement Imagemagick resources consumption limiting
(cherry picked from commit 36d89d02e1)
2020-12-30 15:37:28 +01:00
Mario
2855d84fba owa specify key
(cherry picked from commit f2258d4202)
2020-12-30 15:36:25 +01:00
Mario
3c19648a56 fix issue where an array was passed to get_key() instead of a string
(cherry picked from commit 81a1aedeb9)
2020-12-30 15:35:38 +01:00
Mario
8db367c743 remove fallback code - it will not be required if compression is dismissed 2020-12-30 14:30:39 +00:00
Mario
2c4fabba35 store zip files without compression 2020-12-30 14:12:08 +00:00
Mario
dff42ffb41 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-12-29 20:16:35 +00:00
Mario
11d61a744d escape both single and double quotes for the notifications title. fixes issue #1503 2020-12-29 20:16:23 +00:00
Mario Vavti
5cefdbf985 random_profile: return zot6 entries 2020-12-29 20:37:23 +01:00
Mario Vavti
5485f96625 dirserach: return zot6 entries 2020-12-29 20:36:41 +01:00
Mario
af0f46d23d Merge branch 'cloneissue' into 'dev'
Fix sync comments with clones

See merge request hubzilla/core!1889
2020-12-29 15:50:33 +01:00
Max Kostikov
c063fe0720 Revert "Fix sync item with Zot connections"
This reverts commit 3db4aa69440553788d8f46cf4bbfb38ca4f09130
2020-12-29 15:50:32 +01:00
Mario
203ba7343c Merge branch 'autocomplete' into 'dev'
Deduplicate contacts list on autocomplete

See merge request hubzilla/core!1891
2020-12-29 11:49:52 +01:00
Max Kostikov
d889547b26 Deduplicate contacts list on autocomplete 2020-12-29 11:49:52 +01:00
Mario
b66e19dc43 Merge branch 'photocache' into 'dev'
Do not revalidate cached photos

See merge request hubzilla/core!1890
2020-12-29 11:49:33 +01:00
Mario
c84e3334bf Merge branch 'tuneimagick' into 'dev'
Implement Imagemagick resources consumption limiting

See merge request hubzilla/core!1888
2020-12-29 11:49:11 +01:00
Mario
d5eeb948d5 sse: fix issue with direct message notificationss 2020-12-28 13:19:40 +00:00
Mario
9670833a5d files_ng: provide a fallback in case the server timed out on compressing the zip file 2020-12-28 10:12:25 +00:00
Max Kostikov
ca051e943f Do not revalidate cached photos 2020-12-26 14:24:04 +01:00
Max Kostikov
36d89d02e1 Implement Imagemagick resources consumption limiting 2020-12-26 14:10:56 +01:00
Mario
f4bfa77942 version bump 2020-12-23 09:16:45 +00:00
Mario
f2258d4202 owa specify key 2020-12-23 08:32:59 +00:00
Mario
d56bf34326 fix javascript warning 2020-12-23 08:22:31 +00:00
Mario
9fa3dee522 remove deprecated forum autocomplete code 2020-12-23 08:19:11 +00:00
Mario
7ee2192c29 provide some info and remove unused code 2020-12-22 13:33:54 +00:00
Mario
3a38292bab files_ng: improve download handlÃing 2020-12-22 13:23:20 +00:00
Mario
60cbb65d84 files_ng: omit parent folders of a download 2020-12-22 09:01:52 +00:00
Mario
d118ab71e6 files_ng: implement directory and bulk file download 2020-12-21 21:37:10 +00:00
Mario
81a1aedeb9 fix issue where an array was passed to get_key() instead of a string 2020-12-21 21:31:52 +00:00
Mario
1fd576436b changelog
(cherry picked from commit 638f7a1c89)
2020-12-21 09:44:38 +01:00
Mario
fac05e7dcd version 5.0.7 2020-12-21 09:05:29 +01:00
Max Kostikov
eef3126f0b Fix CardDAV address book ID
(cherry picked from commit 6579007ca0)
2020-12-21 09:04:36 +01:00
Max Kostikov
2df5a2a66d Use Zot6 for CardDAV and CalDAV sync between clones
(cherry picked from commit c596fb14bb)
2020-12-21 09:04:26 +01:00
Mario Vavti
01e7e3c24a handle owa with hubloc_id_url only
(cherry picked from commit ed4bf1c13d)
2020-12-21 09:04:04 +01:00
Mario
8112dee91e do not json_encode the attach array - fixes #1499
(cherry picked from commit 5b24225251)
2020-12-21 09:03:46 +01:00
Mario
638f7a1c89 changelog 2020-12-21 08:03:17 +00:00
Max Kostikov
5de4c3cc3f Merge branch 'dev' into 'dev'
Use Zot6 for CardDAV and CalDAV sync between clones

See merge request hubzilla/core!1886
2020-12-20 00:01:50 +01:00
Max Kostikov
6579007ca0 Fix CardDAV address book ID 2020-12-19 23:57:14 +01:00
Max Kostikov
c596fb14bb Use Zot6 for CardDAV and CalDAV sync between clones 2020-12-19 22:58:17 +01:00
Max Kostikov
116fc4e00d Merge branch 'dev' into 'dev'
Dev sync

See merge request kostikov/core!4
2020-12-19 22:02:51 +01:00
Mario
57f6f54f29 refresh_all will be called from the notifier in Daemon/Directory 2020-12-19 15:21:34 +00:00
Mario
8640e6d1df deprecate ! and !! forum tags 2020-12-18 13:26:51 +00:00
Mario
801583fd07 flag forums where we do not have post permissions and filter them from the acl selector 2020-12-18 12:40:36 +00:00
Mario Vavti
4987534eba Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-12-18 10:02:43 +01:00
Mario Vavti
ed4bf1c13d handle owa with hubloc_id_url only 2020-12-18 10:02:13 +01:00
Mario
5b24225251 do not json_encode the attach array - fixes #1499 2020-12-17 18:57:04 +00:00
Mario
886be8c452 changelog for version 5.0.6
(cherry picked from commit 269efb9c1e)
2020-12-17 14:46:08 +01:00
Mario
269efb9c1e changelog for version 5.0.6 2020-12-17 13:45:14 +00:00
Mario Vavti
612448e4ae update to fix empty hubloc_id_url caused by clone import bug for zot hublocs which was fixed in 4693069a06 2020-12-17 13:29:15 +00:00
Mario Vavti
82db19d54c restrict owa to zot6 and zot network until the hubloc madness with activitypub and possibly also diaspora will be solved
(cherry picked from commit 7ebba75fa2)
2020-12-17 14:26:32 +01:00
Mario
06aa3e6b8c fix issue with abconfig when cloning a channel
(cherry picked from commit f13bff2a76)
2020-12-17 14:26:00 +01:00
Mario
abf985c69e owa: dismiss deleted hublocs
(cherry picked from commit 006a409eb8)
2020-12-17 14:25:06 +01:00
Mario
c176b54f6b use refresh_all in mod import
(cherry picked from commit 59f1c038fe)
2020-12-17 14:24:49 +01:00
Mario
b24e691e7e try to fix more hubloc anomalies: use refresh_all in remove_obsolete_hublocs() and use Libzot::encode_locations() instead of zot_encode_locations() in notifier
(cherry picked from commit dec4ceabb5)
2020-12-17 14:24:16 +01:00
Mario
c2e43dc1b0 fix missing hubloc_id_url for zot hubloc when importing a channel
(cherry picked from commit 4693069a06)
2020-12-17 14:23:09 +01:00
Mario
7b7739c32c try to prevent hubloc confusion in some places
(cherry picked from commit 61cfeb5bdb749319357912d958cd13304b895bce)

(cherry picked from commit 634ace552d)
2020-12-17 14:22:44 +01:00
Mario
269172406f make gprobe look for zot6 only
(cherry picked from commit 1d3437aa419adde319d2a3f5d98e7f8fe4418f27)

(cherry picked from commit 751a1ba969)
2020-12-17 14:20:58 +01:00
Mario
4c054d6de9 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-12-17 12:27:49 +00:00
Mario Vavti
34a58369f2 update to fix empty hubloc_id_url caused by clone import bug for zot hublocs which was fixed in 4693069a06 2020-12-17 13:27:11 +01:00
Mario Vavti
59b4764a15 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-12-17 12:46:33 +01:00
Mario Vavti
7ebba75fa2 restrict owa to zot6 and zot network until the hubloc madness with activitypub and possibly also diaspora will be solved 2020-12-17 12:46:22 +01:00
Mario
b2e80efe3f files_ng: provide bbcode snippets in the info panel 2020-12-17 10:04:24 +00:00
Mario
b4b566318a files_ng: fix regression in finding the right path in certain situations and add a info panel with attach and zrl bbcode 2020-12-16 16:57:56 +00:00
Mario
27df896a9c files_ng: implement lockview 2020-12-16 08:26:19 +00:00
Mario
8188a551f3 fix regression in files aclselect 2020-12-15 12:12:38 +00:00
Mario
f13bff2a76 fix issue with abconfig when cloning a channel 2020-12-15 11:29:45 +00:00
Mario
59f1c038fe use refresh_all in mod import 2020-12-15 10:04:22 +00:00
Mario
006a409eb8 owa: dismiss deleted hublocs 2020-12-15 08:40:02 +00:00
Mario
dec4ceabb5 try to fix more hubloc anomalies: use refresh_all in remove_obsolete_hublocs() and use Libzot::encode_locations() instead of zot_encode_locations() in notifier 2020-12-15 08:36:14 +00:00
Mario
4a902dbbbe fix file sync issues 2020-12-14 22:06:47 +00:00
Mario
8e488e2913 handle removal of terms in attach_delete() when deleting a ressource 2020-12-14 21:56:19 +00:00
Mario
e58e27ce22 sync categories 2020-12-14 21:38:49 +00:00
Mario
78c0926a64 improve when to show link to parent path 2020-12-14 20:22:13 +00:00
Mario
4693069a06 fix missing hubloc_id_url for zot hubloc when importing a channel 2020-12-14 14:06:07 +00:00
Mario
70e529ef5d add another parent element to wrap the tools 2020-12-14 11:17:36 +00:00
Mario
2a154f8c9a merge branch files_ng into dev 2020-12-14 11:02:20 +00:00
Mario
634ace552d try to prevent hubloc confusion in some places
(cherry picked from commit 61cfeb5bdb749319357912d958cd13304b895bce)
2020-12-12 22:41:38 +01:00
Mario
751a1ba969 make gprobe look for zot6 only
(cherry picked from commit 1d3437aa419adde319d2a3f5d98e7f8fe4418f27)
2020-12-12 22:41:11 +01:00
Mario
d95573741d changelog 2020-12-12 19:02:28 +00:00
Max Kostikov
faf4bcdd62 Remove duplicate delete terms query
(cherry picked from commit a27c593a2a)
2020-12-12 19:56:24 +01:00
Mario
badae90051 Merge branch 'dev' into 'dev'
Remove duplicate delete terms query

See merge request hubzilla/core!1885
2020-12-12 19:44:01 +01:00
Max Kostikov
a27c593a2a Remove duplicate delete terms query 2020-12-12 19:43:57 +01:00
Mario
f699442bec bump version 2020-12-12 19:40:49 +01:00
Mario
8720931a53 fix hubloc issue in mod getfile
(cherry picked from commit b0b9b9f28974f9016e47491e81876224c57a7e3b)

(cherry picked from commit 8c1c49a45e)
2020-12-12 19:36:42 +01:00
Max Kostikov
600dcdfc58 Remove duplicate delete terms query 2020-12-12 10:10:32 +01:00
Max Kostikov
a4b83327c2 Merge branch 'dev' into 'dev'
Dev sync

See merge request kostikov/core!3
2020-12-12 10:07:39 +01:00
Mario
8c1c49a45e fix hubloc issue in mod getfile
(cherry picked from commit b0b9b9f28974f9016e47491e81876224c57a7e3b)
2020-12-11 12:35:54 +01:00
Mario
b1f0014429 Merge branch 'dev' into 'dev'
Skip profile photo query from addons for undefined channel id

See merge request hubzilla/core!1884
2020-12-07 11:08:41 +01:00
Max Kostikov
d984918c75 Skip profile photo query from addons for undefined channel id 2020-12-07 11:08:41 +01:00
Mario
21ac4b5139 remove announce activity from response activites array
(cherry picked from commit 52c78c757ae73082ed29e48707b2313e65020db3)
2020-12-07 11:03:03 +01:00
Max Kostikov
92eb7a0be4 Formatting 2020-12-04 14:45:27 +01:00
Max Kostikov
b26b1c0820 Skip profile photo query from addons for undefined channel id 2020-12-04 14:36:29 +01:00
Max Kostikov
a9dd6d6bdb Merge branch 'dev' into 'dev'
Dev sync

See merge request kostikov/core!2
2020-12-04 14:33:34 +01:00
Mario
d60c53cd12 version 5.0.4 2020-12-01 08:46:22 +00:00
Mario
6b0fe6e0a0 changelog
(cherry picked from commit 9c7ec55b40)
2020-12-01 09:45:09 +01:00
Mario
9c7ec55b40 changelog 2020-12-01 08:43:59 +00:00
Mario
28f1f4cbdc missing parenthesis
(cherry picked from commit 45b41f0787)
2020-12-01 09:38:59 +01:00
Mario
508b3ce730 Ãfix regerssion in updating the primary
(cherry picked from commit c47434634d)
2020-12-01 09:38:48 +01:00
Mario
87ecc61fb4 dismiss title in response activity
(cherry picked from commit eb2ad3fc438544192cda95d88a4c2a54ec1e0014)

(cherry picked from commit b89355b9d8)
2020-12-01 09:38:17 +01:00
Mario
ce4d664abc Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-12-01 08:31:50 +00:00
Mario
45b41f0787 missing parenthesis 2020-12-01 08:31:27 +00:00
Mario
c47434634d Ãfix regerssion in updating the primary 2020-12-01 08:31:15 +00:00
Mario
b89355b9d8 dismiss title in response activity
(cherry picked from commit eb2ad3fc438544192cda95d88a4c2a54ec1e0014)
2020-11-28 11:40:03 +01:00
Mario
3f40d6f7b7 run composer install --no-dev 2020-11-27 11:09:48 +00:00
Mario
155daac8ad run composer install --no-dev 2020-11-27 11:08:45 +00:00
Mario
f9d24d07dd composer autoload dump 2020-11-27 10:50:46 +00:00
Mario
d91e35e197 bring back require but with the correct path 2020-11-27 10:47:24 +00:00
Mario
a967dd9d13 fix languagedetect warnming 2020-11-27 08:04:41 +00:00
Mario
f4bb7bcbff update composer libs 2020-11-27 08:04:00 +00:00
me
78f150cfbc air.s1: field templates checkbox/input/select and one new 2020-11-14 23:37:18 +01:00
2904 changed files with 320712 additions and 140869 deletions

7
.gitignore vendored Executable file → Normal file
View File

@@ -33,8 +33,10 @@ apps/
home.html
# page header plugin
pageheader.html
# Ignore site TOS
# Ignore site TOS & gddpr
doc/SiteTOS.md
doc/*/SiteTOS.md
doc/*/gdpr.md
# themes except for redbasic
view/theme/*
!view/theme/redbasic
@@ -55,6 +57,7 @@ tests/results/
.buildpath
.externalToolBuilders
.settings/
.pydevproject
# NetBeans project folder
nbproject/
# Kdevelop project files
@@ -75,3 +78,5 @@ composer.phar
vendor/**/tests/
vendor/**/Test/
vendor/sabre/*/examples/
# /info is a directory containing site-specific HTML documents
/info/

View File

@@ -115,16 +115,16 @@ php7.3_mariadb10.3:
# PHP7.3 with PostgreSQL latest (11)
php7.3_postgres11:
<<: *job_definition_postgres
artifacts: *artifacts_template
#php7.3_postgres11:
# <<: *job_definition_postgres
# artifacts: *artifacts_template
# PHP7.3 with PostgreSQL latest (11)
php7.3_postgres11:
<<: *job_definition_postgres
image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.3
artifacts: *artifacts_template
#php7.3_postgres11:
# <<: *job_definition_postgres
# image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.3
# artifacts: *artifacts_template
# Generate Doxygen API Documentation and deploy it as GitLab pages

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

627
CHANGELOG
View File

@@ -1,3 +1,522 @@
Hubzilla 7.0 (2022-01-21)
- Provide theme_color and background_color in App::$theme_info for usage in page meta and manifest
- PWA improvements according to lighthouse
- Refactor mod profile_photo
- Remove core legacy mail code
- Set session samesite cookie flag
- Improve toc bbcode for more flexible usecases
- Deprecate include/group in favor of Lib/AccessList
- Deprecate AccessList::widget()
- Mark forum channel profile images with a small icon in the timelines
- Improve privacy groups UI/UX
- Do not show connections widget if there are no connections
- Remove suggestions widget from various modules
- Provide guest access links for private resources in lockview
- Improve pconfig syncing
- deprecate include/group in favor of Lib/AccessList
- Implement background deleting of items in contact_remove()
- Refactor guest access tokens for better usability and provide quick access
- Refactor permissions handling
- Improved poll rendering
Bugfixes
- Fix items not deleted on remote channel purge
- Fix plink in post_activity_item()
- Fix multiple update_poll() calls dismissed in queueworker
- Fix blocked or ignored contacts displayed in connections
- Fix polls for forum channels
Addons:
- Legacy mail: remove
- Deprecate include/group in favor of Lib/AccessList
- Pubcrawl: support pleroma end time for polls
- Pubcrawl: slightly adjust the way we check mastodon direct messages
- Socialauth: scope support and improvements
Hubzilla 6.4.2 (2021-12-14)
- Fix issue in mod sse_bs where returning message id's were assumed to be base64 encoded
- Fix announce activity type not registered as response activity
Hubzilla 6.4.1 (2021-12-03)
- Fix hubloc_site_id in fix_system_urls() on detected site rename events
- Fix duplicate deliveries if duplicate hublocs available
- Redesign profile vcard for improved responsive handling
- Fix profile photos not stored in profile photo folder
- Maximum width of content region is now calculated in rem for improved responsive handling
- Fix likes notices emited allthough they are disabled
- Fix page not reloaded after comment/like in mod photos - issue #1651
- Port improved Lib/HttpMeta from zap
- Improved responsive aside
Hubzilla 6.4 (2021-11-09)
- Automatically connect the invitee with the inviting channel
- Use the composer version of urlify
- Implement zip file import of exported items from mod uexport
- Start sending supported protocols with the actor object
- Split up manual item export to separate sections
- Serve w3.org jsonld documents locally - issue #1637
- Support IDNA URL embedding
- Improve handling of re-installed hubs in lib HTTPSig
- BBcode support for notes widget/app
- Implement a force flag for HTTPSig::get_key()
- Update composer libs
- Use Libzot::fetch_conversation for manual content import
- Implement optional force argument in Libzot::process_delivery
- Improve german doco
- Move sync logic for apps to mod appman
- Provide sync for system apps
- Update certificates
- Return status code 410 if a channel is deleted
- Add optional argument to channelx_by_* functions to allow inclusion of removed channels
- Improve file upload performance
- Introduce progress tracking for channel cloning via network (not compatible with cloning from older versions)
- Improve channel delete performance by moving some actions to background tasks
- Introduce all in one channel cloning via network (not compatible with cloning from older versions)
- Rename zotfeed to outbox but keep an alias for compatibility
- Implement apps un-starring from the app bin via drag and drop
- Re-implement the externals daemon
- Add zot6 specific handling to onepoll
- Implement the top option in items_fetch() which will only return top level items
- Add notices tab to HQ widget
- Improve mod manage performance
- Add option to mark all notices of a thread read if a notice of the thread is clicked (default true)
- Provide a get_cached_actor_provider hook and improve the author/owner handling in Libzot::import()
Bugfixes
- Fix issue where remote channels could not create wiki pages due to wron permission check - issue #1640
- Fix dutch registration email template
- Fix selection of invite template
- Fix too restrictive email check in mod invite
- Fix photos and albums ActivityStreams 2 representation
- Fix keys always fetched from network in lib HTTPSig for some AP implementations
- Fix album display of root directory
- Fix onepoll importing to deleted channels
- Fix rendering of image tags in codeblocks
- Fix webfinger and xrd providing results for removed channels
- Fix alt_pager() providing too many arguments
- Fix drop_query_params() if no query params are provided
- Fix duplicate entries for dead hubs in delivery report
- Fix site lookup
- Fix mod locs displaying drop icons for local channels
- Fix multiple issues with propagating deletes of cloned channels
- Fix apps can be draged outsite of drop areas
- Fix removed channels counted in max id check
- Fix api_auth not fetching the id if it was not cached
- Fix public stream unseen notifications displayed allthough the app is not installed
- Fix possible storage conversion stuck on file save error
- Fix notification panel collapsed state not saved if closed manually
- Fix find_best_identity() dismissing AP hublocs
- Fix likes and commments on direct messages mixed up in notices
- Fix rewrite of links to resources in body fails if nicknames of clones differ - issue #1507
- Fix syncing outdated data due to profile sync done before the fields were updated
- Fix $desturl set to wrong value (null)
Addons
- Cart: add settings URL to the apd file
- Diaspora: remove deprecated included
- Cart: remove deprecated include
- Openid: remove library/urlify in favor of composer installed versions
- Pubcrawl: provide tags indicating the supported protocols
- Pubcrawl: if we do not get an uuid, create a v5 uuid from the mid
- Cart: fix rendering regressions from bootstrap5 upgrade
- Upgrade_info: fix dismiss button
- Pubcrawl: move fetch_provider from core to addon
- Diaspora: fix regression in fetch_provider
- Content_import: fix syntax error
- Queueworker: update priorities
- Pubcrawl: only lookup announce author if we actually deal with an announce
- Pubcrawl: make sure we have the best identity before we make the abook lookup
- Pubcrawl: outbox moved to core
- Diaspora: implement the get_cached_actor_provider hook
Hubzilla 6.2.2 (2021-10-03)
- Fix an issue which could lead to loss of photos under certain conditions
Hubzilla 6.2.1 (2021-09-16)
- Fix regression introduced in 6.2 where Diaspora comments on Hubzilla posts were not relayed
- Fix wrong variable used for refresh under certain conditions
- Fix issue where summary tag was processed in cleanup_bbcode() while it shoud not
- Fix issue where profile name change was not applied if done from non primary location
- Fix spacing issue for collapsed pinned apps with an image
- Fix language selector reloading the page if not clicking exactly the icon
- Fix regression displaying bootstrap modals introduced in 6.2
Hubzilla 6.2 (2021-09-08)
- Deprecate the custom highlight [hl] bbcode in favor of [mark] which is a html5 standard
- Check post_mail permission when receiving a direct message
- Refactor actor store and cache mechanism
- Add optional strict flag (false) to base64url_decode() which is passed on to base64_decode()
- Update russian translations
- Add optional force flag (false) to Activity::actor_store()
- Improved icon lookup for actor objects
- Improved desktop notifications
- Make Hubzilla installable as PWA in supported browsers
- Capitalized widget titles (redbasic)
- Make images loaded counter showing % loaded instead of actual image count
- Deprecate optional channel menu in favor of extended app bin
- Implement infrastructure to provide an app install widget for modules
- Implement app descriptions
- Implement app drag and drop sorting
- Implement app drag and drop pinning/starring
- Update polish translations
- Update to bootstrap 5 and adjust templates
Bugfixes
- Fix anonymous comments for cards and articles
- Resolve regex interference between contact and channel autocomplete
- Fix files stored in wrong directory when uploaded in the photo module
- Fix records with empty public key selected for OWA
- Fix import_author_zot failing if primary is both dead and unknown - issue #1599
- Fix regression with bookmarks
- Fix pubstream notifications link redirecting to mod hq when not local
- Cleanup legacy mail leftovers - issue #1595
- Fix getimagesize() called with empty path
- Fix display issue caused by redundant closing div tag
Addons
- Pubcrawl: fix post to forum - issue #159
- Diaspora: implement post_mail permissions for direct messages
- Pubcrawl: implement post_mail permissions for direct messages
- Pubcrawl: deprecate asencode_person() in favor of Activity::encode_person()
- Pubcrawl: implement Activity::get_actor_collections() to reflect core actor store changes
- Diaspora: fix use of deprecated function
- Twitter: prevent re-retweeting of a post from a clone if it has already been sent
- Totp: use platform name instead of banner text
- Pubcrawl: use force flag when updating an actor
- Sse: do not process possible empty hashes
- Implement app descriptions for addons that already support the apps infrastructure
Hubzilla 6.0.1 (2021-07-27)
- Fix regression in notification handling introduced in 6.0
- Fix regression in regard to unified session page load times introduced in 6.0
- Fix photo description textarea only available if create status post enabled
- Fix item not found by message id at clone locations
- Dismiss deleted xchans in mod chanview
Hubzilla 6.0 (2021-07-09)
- Implement swipe to right for bringing in left aside
- DB update 1247 to clean up bogus entries in updates
- DB update 1246 to mark legacy zot xchans and hublocs deleted
- Implement desktop notifications
- Emit a warning if the calendar for the created event is disabled
- Add an option to drop media for bbcode processing
- Make mod HQ the default landing page after login
- Implement direct messages view for mod HQ
- Implement public/restricted messages view for mod HQ
- Implement starred messages view for mod HQ (only available if the Star Posts feature is enabled)
- Update composer libs
- Remove deprecated mod ping
- Remove legacy zot libs and functions - major cleanup
Bugfixes
- Fix deleting and starring in unthreaded view
- Fix issue where incomplete datasets were stored into updates
- Fix photo item tags not stored and propagated
- Fix notifications not loading if a filter was applied
- Fix in browser email validation for registrations
- Fix directory sync issues
- Fix issue where the original rawmsg iconfig got overwritten
- Fix unmaintained id3 pareser for PHP8
- Fix item_private state for imported items
- Random PHP8 fixes (ongoing)
Addons
- Pubcrawl: fix ld-signature for profile updates
- Pubcrawl: deprecate as_actor_store() in favor of Activity::actor_store()
- Twitter: prevent duplicated tweets
- Remove legacy zot dpendencies and deprecated functions
- Pubcrawl: fix remote reply for peertube
- Pubcrawl: fix issue where we could end up with an xchan but without hubloc
- Diaspora: implement the direct_message_recipients hook
- Queueworker: add a simple priority mechanism to prevent not so important janitor tasks (e.g. onedirsync) stuffing up the queue and delaying delivery of items
- Pubcrawl: implement direct message recognision for activities coming from Mastodon
- Pubcrawl: always show complete threads (complete as in all the messages we have received) in public stream
- Twitter_api: remove the mail endpoint
- Mail: make interface read only with the possibility to download and delete mails (this addon will be removed in a future version)
- Pubsubhubbub: move to addons-unmaintained
- GNU-Social: move to addons-unmaintained
- Fixes to reflect core notifier changes
- Diaspora: refactor conversations a.k.a mail to implement direct messages infrastructure
- Pubcrawl: allow hublocs to be upgraded from ostatus
- Diaspora: fix issue where we could end up with an xchan but without hubloc
Hubzilla 5.6.1 (2021-06-04)
- Update spanish translations
- Fix login name label if register email verification is disabled
- Fix zotinfo issue with deleted channels
- Make pubstream ordering configurable
- Fix article summary duplicated when editing
- Update polish translations
- Fix admin setting for invitations not displayed correctly
- Fix registration in invite only mode
- Fix notifications not returning offset -1 when returning early
- Fix direct messages for items imported via sync
- Bring back the channel protocols hooks
- Fix security headers switching
- Fix magic auth for delegated channels
- Introduce drop_query_params() for secure query parameter removal
- PHP8 fixes (ongoing)
- Fix menu wrapping regression
Addons
- LDAPauth: fix regression creating an account
- Twitter: allow feeds crossposting
- Twitter: fix posting when post by default is disabled
- Pubcrawl: add litepub directMessage attribute
- Pubcrawl: allow xchan/hubloc upgrades from e.g. ostatus
- Diaspora: fix possible issue with missing hublocs
- Diaspora: refine dispatching of public of public items
Hubzilla 5.6 (2021-05-11)
- Improve postgres hubloc queries
- Implement automatic duplicate singleton hubloc removal
- Send author id, id_sig and key fields along with author/owner
- Implement custom redis session backend
- Improved registration workflow
- Complete rewrite of the registration backend with many new features
- Complete rewrite of the invite app
- Update Spanish, Russian and Polish translations
- Improved PHP8 compatibiliy (work in progress)
Bugfixes
- Fix manual fetching of non-ascii domains
- Fix revision not compared when importing items
- Fix events not transformed to UTC when importing calendar
- Fix timezone issue in mod cal
- Fix profile photos not revalidated
- Fix regression in caldav/carddav discovery
- Fix caldav/carddav sync on remote access
- Fix info and notice messages not bootstraped when using SSE
- Fix URL including an @ treated like a webbie
- Fix cover photo image issues on some mobile devices
Addons
- Diaspora: improve performance when delivering public items
- Diaspora: make sure to not process same contact more than once
- Pubcrawl: make sure to not process same contact more than once
- Pubcrawl: do not relay Like and Dislike activity
- Pubcrawl: deprecate as_follow() in favour of core Activity::follow()
- Pubcrawl: improved compatibility with mobilizon and xwiki
- Pubcrawl: do not process follow/unfollw thread in as_create_note()
- Diaspora: do not relay comments/likes of strangers if the thread-owner is local and does not allow comments/likes by strangers in the diaspora app settings
Hubzilla 5.4.3 (2021-04-20)
- Fix regression in mod notifications (only the last was visible)
- Set Permissions-Policy: interest-cohort=() header by default
- Fix xchans containing a % breaking get_forum_channels()
- Fix webfinger if using a reverse proxy
- Fix regression finding bookmarks
- Fix zot6 hublocs import on channel import
- Fix revision not checked in import_items()
Hubzilla 5.4.2 (2021-03-15)
- Fix translation plural variable
- Fix issue with following/unfollowing a thread
- Fix rendering of long text in xchan vcard
- Fix local link for rss content if rewrite author is sets
- Fix regression in mod display
Addons
- Pubcrawl: fix issue with following/unfollowing a thread
- Pubcrawl: more robust implementation of mastodon remote reply
- Photocache: remove suffix from the cached photo URL
Hubzilla 5.4.1 (2021-03-09)
- Fix profile not found if not logged in
- Fix summary not reset on cancel
- Fix summary not saved with aoutosave draft
- Fix unexpected trigger of buttons when pressing enter in input fields
- Fix spanish plural expression
- Fix undefined page-end on non dynamic pages
Addons
- Pubcrawl: fix regression in pubcrawl_follow_mod_init()
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()
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
Hubzilla 5.2 (2021-01-13)
- Use libzotdir for directory
- Streamline usage of channel url for keyId
- Basic work on PHP8 compatibility
- Improve performance for forum post edit action
- Improve File App tiles view
- Update es strings
- Update ru strings
- Implement directory download via zip files in Files App
- Implement bulk file download via zip files in Files App
- Deprecate ! and !! forum tags - use direct messages to post to forums
- Do not show forums where we do not have permission to post in ACL selector
- Implement lockview for Files App
- Implement file and directory rename functionality Files App
- Implement file and directory copy functionality in Files App
- Implement file and directory move functionality in Files App
- Implement categories for files and directories in Files App
- Implement drag and drop move action for files and directories in Files App
- Implement bulk file actions for move, copy, categories and permissions
- Implement a files categories widget
- Implement a breadcrumb view for file paths
- Rewrite xchan_vcard template
- Update composer libs
Bugfixes
- Fix direct messages by forum channel turned into group item
- Fix ID3Parser composer autoload
- Fix issue where directory_fallback_servers were not accessible from static function
- Fix missing constant defenition for HUBLOC_OFFLINE
- Fix sync_directories() including known dead sites
- Fix undefined variable in poller preventing Onedirsync from running
- Fix w2w posts not editable/deletable from local server
- Fix issue where categories were not saved on forum wall posts
- Fix no channel_id provided for contact_remove() in reply_purge()
- Fix typo in notifier command
- Fix profile title/description allowed more than 191 characters
Addons
- Queueworker: cleanup whitespace
- Queueworker: add some tweaks to prevent deadlocks for postgresql
- Flashcards: compatibility for the changes in the Files App
- Openstreemap: fix hostname parsing from URL
- Openstreemap: fix content security policy
- Pubcrawl: fix peertube video display
- Pubcrawl: deliver updates to anyone owning the item
Hubzilla 5.0.8 (2020-12-30)
- Fix single quotes not escaped in the notifications title (issue 1503)
- Return zot6 xchans for random_profile()
- Return zot6 entries in dirsearch
- Fix comment sync issue
- Fix duplicate entries in contact autocomplete
- Fix issue where direct message notifications where not displayed for wall items
- Do not revalidate cached photos
- Implement imagemagic resource consumption limiting
- Specify key in mod owa
- Fix issue where array was passed to get_key()
Hubzilla 5.0.7 (2020-12-21)
- Fix CardDAV addressbook ID
- Use Zot6 for CardDAV and CalDAV sync between clones
- Handle owa with hubloc_id_url only
- Fix attachment in comment not visible after commenting - issue #1499
Hubzilla 5.0.6 (2020-12-17)
- Fix zot hublocs with empty hubloc_id_url in DB caused by clone import bug
- Only look for zot6 and zot hublocs in mod owa
- Fix abconfig issue when cloning a channel
- Call notifier with refresh_all instead of location when importing a clone
- Use Libzot::encode_locations() instead of zot_encode_locations() in notifier
- Fix missing zot hubloc hubloc_id_url when importing a clone
- Implement Libzot::zot_record_preferred() in various places to prevent hubloc confusion
Addons
- Fix wrong redirect path for check_form_security_token_redirectOnErr() in various addons
Hubzilla 5.0.5 (2020-12-12)
- Fix hubloc issue in mod getfile
- Remove duplicate SQL query
Hubzilla 5.0.4 (2020-12-01)
- Fix regression updating the primary
- Dismiss title in response activities
Hubzilla 5.0.3 (2020-11-26)
- Upgrade phpunit to version 9
- Remove dbunit because its not maintained anymore
@@ -29,7 +548,7 @@ Hubzilla 5.0.2 (2020-11-16)
Hubzilla 5.0.1 (2020-11-12)
- Fix share title size
- Fix share title size
- Fix issue where hublocs could get mixed up between different protocols
Addons
@@ -345,7 +864,7 @@ Hubzilla 4.2 (2019-06-04)
Hubzilla 4.0.3 (2019-04-26)
- Add attachments to zot6 event objects
- Add zot6 to federated transports
- Add zot6 to federated transports
- Update import/export to handle zot6 hublocs and xchans
- Update fix_system_urls() to handle zot6 hublocs
- Fix infinite loop using postgres as backend
@@ -398,7 +917,7 @@ Hubzilla 4.0.1 (2019-03-21)
- Perform zot6 discovery in import_author_xchan
- Fix authenticated fetches
- Port zot_record_preferred() from zap
Addons:
- Pubcrawl: deliver comments to abook contacts and thread participants
- Pubcrawl: fix can_comment_on_post()
@@ -612,7 +1131,7 @@ Hubzilla 3.8.3 (2018-11-05)
- Fix forum notifications count not correct
- Fix gallery addon which broke mod apps in some situations
- Fix wiki_list widget not working on every page respectively level
Hubzilla 3.8.2 (2018-10-29)
- Merge unmerged changes from dev into master
@@ -628,7 +1147,7 @@ Hubzilla 3.8.2 (2018-10-29)
- Look for for matches in the entire string when suggesting emojis
- Add [summary] bbcode to autocomplete list
- Update blueimp_upload to version 9.23
- Update spanish strings
- Update spanish strings
Addons
- Cart: don't allow items to be added unless user is logged into the Grid.
@@ -686,7 +1205,7 @@ Hubzilla 3.8 (2018-10-19)
- Sanitise vcard fields
- Don't sync system apps
Bugfixes
- Fix issue with timeago plurals
- Fix issue with HTTP signatures
@@ -745,7 +1264,7 @@ Hubzilla 3.8 (2018-10-19)
Hubzilla 3.6 (2018-07-25)
- Update jquery.timeago library
- Implement Hookable CSP
- ActivityStreams: accept header changes to support plume
- ActivityStreams: accept header changes to support plume
- Streamline inconsistencies in addon naming
- SECURITY: hash the session_id in logs
- Update justified gallery library
@@ -758,9 +1277,9 @@ Hubzilla 3.6 (2018-07-25)
- Make droping posts of removed connections more memory efficient
- Refactor getOutainfo() for DAV storage
- Optionally report total available space when uploading
- SECURITY: provide option to disable the cloud 'root' directory and make the cloud module require a target channel nickname
- SECURITY: provide option to disable the cloud 'root' directory and make the cloud module require a target channel nickname
- Add plink and llink to viewsource
- Add new 'filter by name' feature
- Add new 'filter by name' feature
- Remove network tabs
- New activity filter widget
- New activity order widget
@@ -802,8 +1321,8 @@ Hubzilla 3.6 (2018-07-25)
- Fix sys channels visible in dirsearch
- Fix remote_self not working correctly
- Fix photos not syncing properly if destination is a postgres site
- Fix wrong hubloc_url for activitypub hublocs
- Fix z_check_dns() for BSD
- Fix wrong hubloc_url for activitypub hublocs
- Fix z_check_dns() for BSD
- Fix not null violation in oauth1
- Fix DB issues with oauth2 on postgresql
- Fix 'anybody authenticated' not correctly handled in can_comment_on_post()
@@ -1365,10 +1884,10 @@ Hubzilla 2.6.2 (2017-08-31)
Hubzilla 2.6.1 (2017-08-18)
- Fix a regression with dav clients
- Raise install requirements
Plugins/Addon
- Diaspora: fix PHP warning
- GNU-Social: fix PHP warning
- GNU-Social: fix PHP warning
Hubzilla 2.6 (2017-08-16)
@@ -1376,18 +1895,18 @@ Hubzilla 2.6 (2017-08-16)
- Consolidate disable_discover_tab config
- Fix some bbcode to markdown conversion issues
- Improved finding of recursive attachment permissions
- Smaller line-height for notification badges
- Smaller line-height for notification badges
- Bluegrid schema removed - will be added again if someone is willing to maintain it
- Improved file_activity()
- DB - add index for item.obj_type
- Add options flag to bb_to_markdown() so we can distinguish between diaspora use and other use and therefore filter and adjust content selectively
- Close the apps-menu if the notifications-menu is open and vice versa
- Close the apps-menu if the notifications-menu is open and vice versa
- Remove redundant call to jquery ready function in photo albums view
- Remove borders from navbar toggler in mobile view
- Improve the formatting of shares when converting from bbcode to markdown
- Suppress fopen errors from dav
- Make local channel (not our own) nav menus appear similar to what we are used from remote channels
- Indicate the selected channel in the dropdown menu if the feature is enabled
- Indicate the selected channel in the dropdown menu if the feature is enabled
- Provide a mechanism to mark apps active in the app tray
- Allow wildcard tag and category searches
- Improved installer
@@ -1399,7 +1918,7 @@ Hubzilla 2.6 (2017-08-16)
- Update htmlpurifier to version 4.9.3
- Update sabre/http to version 4.2.3
- Add optimize-autoloader to composer config
- Missing abook_{my,their}_perms in pg schema and missing keys in mysql schema
- Missing abook_{my,their}_perms in pg schema and missing keys in mysql schema
- Provide a gender icon on the profile sidebar within reason
- Provide more comprehensible information on the admin summary page
- Upgrade blueimp from 9.8 to 9.18
@@ -1465,7 +1984,7 @@ Hubzilla 2.6 (2017-08-16)
Cdav addon moved to core
head_add_css() needs a preceding '/' to find files in the addons dir
New addon code syntax highlighting (moved from core to addon)
Pubsubhubbub: specify a minimum number of records - otherwise it defaults to zero
Pubsubhubbub: specify a minimum number of records - otherwise it defaults to zero
Hubzilla 2.4 (2017-05-31)
@@ -1819,10 +2338,10 @@ Hubzilla 1.14 (2016-10-13)
- Start grouping addons by server_role
Hubzilla 1.12
- extensible permissions so you can create a new permission rule such as "can write to my wiki" or "can see me naked".
- guest access tokens can do anything you let them, including create posts and administer your channel
- extensible permissions so you can create a new permission rule such as "can write to my wiki" or "can see me naked".
- guest access tokens can do anything you let them, including create posts and administer your channel
- ACLs can be set on files and directories prior to creation.
- ACL tool can now be used in multiple forms within a page
- ACL tool can now be used in multiple forms within a page
- a myriad of new drag/drop features (drop files or photos into /cloud or a post, or drop link into a post or comment, etc.)
- multiple file uploads
- improvements to website import
@@ -1847,7 +2366,7 @@ Hubzilla 1.10
Wiki:
Lots of enhanced functionality, usability improvements, and bugfixes from v1.8
Turned into an optional feature (default on) but disabled in UNO
Sync:
Sync:
Items are now relocated (links patched) when syncing to clones
Access Tokens:
New feature - allows members to create access controlled guest logins and create/share 'dropbox' style links to protected resources.
@@ -1855,7 +2374,7 @@ Hubzilla 1.10
Use icons instead of iconic text constructs
Only request geolocation permission when creating a post, not on page load
provide 'redeliver' option on Delivery Report page for when things really stuff up
CalDAV/CardDAV management pages with heaps of functionality
CalDAV/CardDAV management pages with heaps of functionality
Lib:
z_fetch_url() updated to accept different request methods and request bodies
item_store(), item_store_update() now return the stored items
@@ -1879,7 +2398,7 @@ Hubzilla 1.10
issues with 'use existing photo' for profile photo
layout editor "list all layouts" returned empty
oembed - better detect video file URLs so they aren't loaded into memory.
handcrafted bbcode tables could end up with way too much whitespace due to CRLF translation
handcrafted bbcode tables could end up with way too much whitespace due to CRLF translation
refresh permissions whitescreen in 1.8
force immediate profile photo update on local site
regression: 'save bookmarks' post action missing
@@ -1904,7 +2423,7 @@ Hubzilla 1.8
Documentation:
Clarify privacy rights of commenters w/r/t conversation owners, as this policy is network dependent.
Wiki (Git backed):
Brand new feature. We'll call it experimental until it has undergone a bit more testing.
Brand new feature. We'll call it experimental until it has undergone a bit more testing.
Account Cloning:
Regression on clone channel creation created a new channel name each time.
New issue (fixed) with directory creation on cloned file content
@@ -1927,7 +2446,7 @@ Hubzilla 1.8
Experimental PDO database driver
Creation of Daemon Master class and port all daemon (background task) interfaces to use it
Create separate class for each of 'Cron', 'Cron daily', and 'Cron weekly'.
Always run a Cron maintenance task if not run in the last four hours
Always run a Cron maintenance task if not run in the last four hours
Refactor the template classes
Refactor the ConversationItem mess into ThreadItem and ThreadStream
Refactor Apps, Enotify, and Chat library code
@@ -1935,7 +2454,7 @@ Hubzilla 1.8
Created WebServer class for top level
Remove mcrypt dependencies (deprecated in PHP 7.1)
Remove all reserved (including merely 'not recommended') words as DB table column names
Provide mutex lock on DB logging to prevent recursion under rare failure modes.
Provide mutex lock on DB logging to prevent recursion under rare failure modes.
Bugfixes:
Remove db_close function on page end - not needed and will not work with persistent DB connections.
Undefined ref_session_write
@@ -1955,7 +2474,7 @@ Hubzilla 1.8
CalDAV/CardDAV plugin provided
Issue sending Diaspora 'like' activities from sources that did not propagate the DCV
Allow 'superblock' to work across API calls from third party clients
statistics.json: use 'zot' as protocol
statistics.json: use 'zot' as protocol
Issues fixed during testing of ability to follow Diaspora tags
Parse issue with Diaspora reshare content
Chess: moved to main repo, ported to 1.8
@@ -1967,7 +2486,7 @@ Hubzilla 1.6
Plugin hook interface adapted to call static class methods
Context help improved dramatically with content for the most accessed pages.
Reverted a compatibility change to support GNU-social events. We copied their feed format and their feed format is wrong (XML namespace collisions).
Provide a querystring attribute to CSS/JS resources to avoid caching issues when our code changes (which is often).
Provide a querystring attribute to CSS/JS resources to avoid caching issues when our code changes (which is often).
Fix javascript detection and allow either positive or negative detection.
Refactor the plugin hook registration procedure, provide 'unregister all' ability.
Fix RSD (Real Simple Discovery) which has been broken for some time.
@@ -1976,7 +2495,7 @@ Hubzilla 1.6
Update font-awesome to 4.6.1
Update SabreDAV to 3.0 (PHP version requirements prevent us from pushing it further at this time)
Help text added to cmdline utilities config and pconfig
Reworking of the database logging facility to avoid the rare but troublesome recursion when the log facility needed to query the DB internally to obtain config parameters.
Reworking of the database logging facility to avoid the rare but troublesome recursion when the log facility needed to query the DB internally to obtain config parameters.
Implement singleton delivery (emulate nomadic identity to singleton networks and services)
Fix empty album name in photo activities when photo is stored in top level folder.
Allow engineering units to be used in service class data size restrictions (400M, 1G, etc.)
@@ -1984,7 +2503,7 @@ Hubzilla 1.6
Admin interface provided to manage external resource repositories
Oembed security reworked. Now all sources are filtered by default unless blocked.
Remove the date-string version and use only STD_VERSION
Add categories and categorisation filtering and the ability to edit all apps (including system apps) for a given channel
Add categories and categorisation filtering and the ability to edit all apps (including system apps) for a given channel
Ensure the ability to translate names of all system apps (except those provided in addons)
Provide ability to add categories to content from channel sources
Lots of work on the presentation of the ACL widget to enhance usability and intuitiveness
@@ -1998,24 +2517,24 @@ Hubzilla 1.6
Provide some extra security checks to import data and files to prevent mischief
Block CalDAV/CardDAV namespace reserved words from being used as a channel nickname/redress since Sabre is somewhat inflexible in this regard
Plugins:
Diaspora
markdown translator work needed to eradicate the Diaspora Comment Virus.
Diaspora
markdown translator work needed to eradicate the Diaspora Comment Virus.
upgrade all inbound paths with the most recent protocol changes (several of these)
convert 'diaspora_meta' (Diaspora Comment Virus) to iconfig and eradicate from sites with Diaspora disabled
implement social relay and allow following tags
upgrade statistics.json to NodeInfo. Currently hubzilla sites are tagged as 'redmatrix' because the NodeInfo schema lacks extensibility and project names are used to designate protocol compatibility rather than protocol names.
Std-embeds
New addon to allow a handful of corporate providers to run unfiltered embed code (youtube, vimeo, soundcloud)
New addon to allow a handful of corporate providers to run unfiltered embed code (youtube, vimeo, soundcloud)
Various:
upgrade font-awesome icons and adapt a few addons to Objects and the new hook interface and new controller interface
Hubzilla 1.4
[This list may appear brief, but encompasses a huge amount of re-writing and re-factoring
of the internal code structure to gain long-term performance and stability and provide a standard
interface to alternate protocol federation plugins which were made possible by the UNO configuration.
UNO is a configuration of hubzilla introduced in 1.3 with reduced complexity and which provides
improved protocol federation potential to other networks by virtue of removing nomadic identity
(which is not possible to model or work around using other network protocols).]
UNO is a configuration of hubzilla introduced in 1.3 with reduced complexity and which provides
improved protocol federation potential to other networks by virtue of removing nomadic identity
(which is not possible to model or work around using other network protocols).]
Implement channel move operation for UNO configuration
Remove bookmark references in UNO (which has no bookmarks by default)
@@ -2038,10 +2557,10 @@ Hubzilla 1.4
Rework detection of JavaScript to avoid reload penalty under normal operation
Changed primary directory server to a hubzilla server
Plugins:
Diaspora - switch to alternate XML parser to avoid storing compound objects
Diaspora - switch to alternate XML parser to avoid storing compound objects
GNU-Social - Huge amounts of work, federation somewhat working now, several issues remain
Friendica - Initial federation work (not yet published)
Hubzilla 1.3
Admin Security configuration page created which consolidates several previously hidden settings:
Communication white/black lists
@@ -2057,26 +2576,26 @@ Hubzilla 1.3
"pubsites" module UI reworked
item-meta ("iconfig") created which implements arbitrary storage for item metadata for plugins
abook-meta ("abconfig") created which implements arbitrary storage for connection metadata for plugins
"Strict transport security header" made optional as it conflicts with some existing Apache/nginx configurations
"Hubzilla UNO" (Hubzilla with radically simplified and locked site settings) implemented as an install configuration.
"Strict transport security header" made optional as it conflicts with some existing Apache/nginx configurations
"Hubzilla UNO" (Hubzilla with radically simplified and locked site settings) implemented as an install configuration.
.well-known directory conflict worked out to support LetsEncrypt cert ownership checks without disrupting webfinger and other internal uses of .well-known
Lots of work on 'zcards' which are self-contained HTML representations of a channel including cover photos, profile photos, and some text information
Long standing bug uncovered which failed to properly restrict the lower time limit for public feed requests
A number of fixes to "readmore" to fix page jumping
Bugfix: persons other than the channel owner who have permission to upload photos to a channel could not do so if the js_upload plugin/addon was enabled
Siteinfo incorrectly identifying secondary directory servers
Allow admin to set and lock features when UNO is configured
Allow admin to set and lock features when UNO is configured
Atom feeds: alter how events are formatted to be compatible with GNU-social
Allow guest/visitor access to view personal calendar
Moved several more classes to "composer format" and provided an autoloader.
Bugfix: require existing password to change password
Bugfix: allow relative_date() to be translated to Polish which has more than two plural forms.
Bugfix: allow relative_date() to be translated to Polish which has more than two plural forms.
Plugin API: add "requires" keyword to module header to indicate dependent addons
ActivityStreams improvements and cleanup: photo and file activities
UI cleanup for editing profile when multiple profiles enabled
Removed the "markdown" feature as there are numerous issues and no maintainer.
Provide "footer" bbcode to ease theming of post footer content
Bugfix: install issues caused by composer code refactor and typo in postgres load file
Bugfix: install issues caused by composer code refactor and typo in postgres load file
Plugins:
keepout - "block public on steroids"
pubsubhubbub - provides PuSH support to Atom feeds, required for GNU-social federation
@@ -2084,7 +2603,7 @@ Hubzilla 1.3
Diaspora protocol - some work to ease migration to the new signing format
Diaspost - disabled; numerous issues and no maintainer
smileybutton - theme work and fixed compatibility with other jot-tools plugins
Hubzilla 1.2
Provide extra HTTP security headers (several of them).
@@ -2094,7 +2613,7 @@ Hubzilla 1.2
Add locked features to siteinfo report to aid remote debugging
Provide version compatibility checking to plugins (minversion, maxversion, and minphpversion)
Account config storage
Provide optional integrated registration and channel create form
Provide optional integrated registration and channel create form
cli utility for managing addons
issue with sharing photo "items"
cover photo manager: upload, crop, and store
@@ -2116,7 +2635,7 @@ Hubzilla 1.2
proc_run modified to use exec() instead of proc_open() - causing issues on some PHP installations
remote delegation failure under a specific set of circumstances which we were finally able to duplicate
Delegation section of Channel Manager was missing names and contained useless notification icons.
Change "expire" channel setting to show system limit if there is one.
Change "expire" channel setting to show system limit if there is one.
Regression: provide a one-click ignore of pending connection
Config to control directory keyword generation on client and server.
"Collections" renamed to "Privacy Groups", documentation improved
@@ -2169,11 +2688,11 @@ Hubzilla 1.1
Addons/Plugins:
Pageheader addon ported from Friendica
Hubwall (allow admin to send email to all accounts on this hub) created
GNU-social - queueing added
Diaspora - fixes for various failures to update profile photos, updates to queue API
GNU-social - queueing added
Diaspora - fixes for various failures to update profile photos, updates to queue API
Cross Domain Authenticated Chess (Andrew Manning's repository)
And... the normal "lots of bugs fixed, translations updated, and documentation improved"
And... the normal "lots of bugs fixed, translations updated, and documentation improved"

48
CHANGELOG.air Normal file
View File

@@ -0,0 +1,48 @@
"air" is a branch name for revision of Account-Invite-Register at the Hubzilla project
Invite:
* Rewritten and now language template driven
* Selectable templates for the invite mails
* Invitor may add personal notes in the mailtext
+ Invite codes are bound to the recipients email address
* Invite mod never more creates accounts
* new db scheme for table register
* existing register table will be migrated to the new schema even when detected at runtime
* Bugfix: creating invite codes when admin only calls Invite w/o any further action
* account library revision also together with invite mod
* Depending on config: Users may send invitations also
* Invitations expires, controlled by the invitor
* Changed and new configs:
* * invitation_only As usual before
* * invitation_also Beside other registration policies, invitations may be used also
* * invitation_max_per_day defaults 50, may be changed in adminUI admin>site
* * invitation_max_per_user defaults 4
* Requirements:
* * Addon language has to be installed
Register:
* Register panel (form) and js interaction changed
* Unused registrations expire
* Depending on config, anonymous registrations (w/o email) are supported
* :... dont't panic, that may let grow security
* Even anonymous users have to confirm their registration
* Registrations may be enabled / disabled time driven for each day in the week (dudy)
* Unsoliced registration floods may be blocked
* Limited registrations from one single source ip
* Using one additional log file, to easy interfare with f2b
Account:
* An user account always becomes created only if all depending conditions are satisfied
* AdminUI for site configuration, accounts and registrations enhancements
* Still untouched, but accountUI needs enhanced async control in case for mass delete
with deep level of recursion cascade of the dependencies (channels etc). An open TODO
since years for instances with many much users and channels.
History:
2020.03 Hubzilla Prod version 4.6 (master branch) of hubzilla/core was the base for AIR
that was assigned Version 4.6.2 at sn/core
2021.02 Hubzilla Prod version 5.2.1 (master branch) of hubzilla/core was new base for AIR
that was assigned version 5.2.2 at sn/core (air.5)
plus adjustment of hubzilla 5.2.2 (master) to sn/core (air.5) version 5.2.9

42
SBOM.md
View File

@@ -2,31 +2,37 @@
|Name|Version|License|Source|
|----|-------|-------|------|
|blueimp/jquery-file-upload|10.31.0.0|MIT|https://github.com/vkhramtsov/jQuery-File-Upload.git|
|blueimp/jquery-file-upload|10.32.0.0|MIT|https://github.com/vkhramtsov/jQuery-File-Upload.git|
|brick/math|0.9.3.0|MIT|https://github.com/brick/math.git|
|bshaffer/oauth2-server-php|1.11.1.0|MIT|https://github.com/bshaffer/oauth2-server-php.git|
|commerceguys/intl|1.0.5.0|MIT|https://github.com/commerceguys/intl.git|
|commerceguys/intl|1.1.0.0|MIT|https://github.com/commerceguys/intl.git|
|desandro/imagesloaded|4.1.4.0|MIT|https://github.com/desandro/imagesloaded.git|
|ezyang/htmlpurifier|4.13.0.0|LGPL-2.1-or-later|https://github.com/ezyang/htmlpurifier.git|
|league/html-to-markdown|4.10.0.0|MIT|https://github.com/thephpleague/html-to-markdown.git|
|jbroadway/urlify|1.2.2.0|BSD-3-Clause-Clear|https://github.com/jbroadway/urlify.git|
|league/html-to-markdown|5.0.1.0|MIT|https://github.com/thephpleague/html-to-markdown.git|
|lukasreschke/id3parser|0.0.3.0|GPL|https://github.com/LukasReschke/ID3Parser.git|
|michelf/php-markdown|1.9.0.0|BSD-3-Clause|https://github.com/michelf/php-markdown.git|
|paragonie/random_compat|9.99.99.0|MIT|https://github.com/paragonie/random_compat.git|
|pear/text_languagedetect|1.0.0.0|BSD-2-Clause|https://github.com/pear/Text_LanguageDetect.git|
|psr/log|1.1.3.0|MIT|https://github.com/php-fig/log.git|
|ramsey/uuid|3.9.3.0|MIT|https://github.com/ramsey/uuid.git|
|sabre/dav|4.1.1.0|BSD-3-Clause|https://github.com/sabre-io/dav.git|
|sabre/event|5.1.0.0|BSD-3-Clause|https://github.com/sabre-io/event.git|
|sabre/http|5.1.0.0|BSD-3-Clause|https://github.com/sabre-io/http.git|
|sabre/uri|2.2.0.0|BSD-3-Clause|https://github.com/sabre-io/uri.git|
|sabre/vobject|4.3.1.0|BSD-3-Clause|https://github.com/sabre-io/vobject.git|
|sabre/xml|2.2.1.0|BSD-3-Clause|https://github.com/sabre-io/xml.git|
|simplepie/simplepie|1.5.5.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.13.1.0|MIT|https://github.com/symfony/polyfill-ctype.git|
|twbs/bootstrap|4.5.2.0|MIT|https://github.com/twbs/bootstrap.git|
|pear/text_languagedetect|1.0.1.0|BSD-2-Clause|https://github.com/pear/Text_LanguageDetect.git|
|phpseclib/phpseclib|2.0.33.0|MIT|https://github.com/phpseclib/phpseclib.git|
|psr/log|1.1.4.0|MIT|https://github.com/php-fig/log.git|
|ramsey/collection|1.2.2.0|MIT|https://github.com/ramsey/collection.git|
|ramsey/uuid|4.2.3.0|MIT|https://github.com/ramsey/uuid.git|
|sabre/dav|4.1.5.0|BSD-3-Clause|https://github.com/sabre-io/dav.git|
|sabre/event|5.1.2.0|BSD-3-Clause|https://github.com/sabre-io/event.git|
|sabre/http|5.1.1.0|BSD-3-Clause|https://github.com/sabre-io/http.git|
|sabre/uri|2.2.1.0|BSD-3-Clause|https://github.com/sabre-io/uri.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.39.0|LGPL-3.0|https://github.com/smarty-php/smarty.git|
|symfony/polyfill-ctype|1.23.0.0|MIT|https://github.com/symfony/polyfill-ctype.git|
|symfony/polyfill-php80|1.23.1.0|MIT|https://github.com/symfony/polyfill-php80.git|
|symfony/polyfill-php81|1.23.0.0|MIT|https://github.com/symfony/polyfill-php81.git|
|twbs/bootstrap|5.1.3.0|MIT|https://github.com/twbs/bootstrap.git|
|voku/portable-ascii|1.5.6.0|MIT|https://github.com/voku/portable-ascii.git|
|voku/stop-words|2.0.1.0|MIT|https://github.com/voku/stop-words.git|
|fullcalendar/fullcalendar|4.4.2.0|MIT|https://github.com/fullcalendar/fullcalendar.git|
|miromannino/Justified-Gallery|3.8.1.0|MIT|https://github.com/miromannino/Justified-Gallery.git|
|fengyuanchen/cropperjs|1.5.7.0|MIT|https://github.com/fengyuanchen/cropperjs.git|
|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|

10
ServiceWorker.js Normal file
View File

@@ -0,0 +1,10 @@
// This file should be served from the web root to avoid scope and cookie related issues with some browsers
self.addEventListener('install', function(e) {
console.log('install event');
});
self.addEventListener('fetch', function(e) {
// nothing here yet
return;
});

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,15 +78,15 @@ 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

@@ -17,7 +17,7 @@ class PermissionRoles {
* @return number
*/
static public function version() {
return 2;
return 3;
}
static function role_perms($role) {
@@ -27,6 +27,54 @@ class PermissionRoles {
$ret['role'] = $role;
switch($role) {
case 'public':
$ret['default_collection'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage', 'view_pages', 'view_wiki',
'send_stream', 'post_comments', 'post_mail', 'post_wall', 'chat', 'post_like', 'republish'
];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['limits']['post_comments'] = PERMS_AUTHED;
$ret['limits']['post_mail'] = PERMS_AUTHED;
$ret['limits']['post_like'] = PERMS_AUTHED;
$ret['limits']['chat'] = PERMS_AUTHED;
break;
// Hubzilla default role
case 'personal':
$ret['default_collection'] = true;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage', 'view_pages', 'view_wiki',
'send_stream', 'post_comments', 'post_mail', 'chat', 'post_like'
];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
break;
case 'group':
$ret['default_collection'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'view_wiki', 'post_wall', 'post_comments',
'post_mail', 'post_like', 'chat'
];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['channel_type'] = 'group';
break;
// Provide some defaults for the custom role so that we do not start
// with no permissions at all if we create a new channel with this role
case 'custom':
$ret['default_collection'] = true;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage', 'view_pages', 'view_wiki',
'send_stream', 'post_comments', 'post_mail', 'chat', 'post_like'
];
$ret['limits'] = PermissionLimits::Std_Limits();
break;
/*
case 'social':
$ret['perms_auto'] = false;
$ret['default_collection'] = false;
@@ -193,13 +241,14 @@ class PermissionRoles {
$ret['channel_type'] = 'group';
break;
*/
case 'custom':
default:
break;
}
$x = get_config('system','role_perms');
// let system settings over-ride any or all
if($x && is_array($x) && array_key_exists($role,$x))
$ret = array_merge($ret,$x[$role]);
@@ -218,13 +267,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 +311,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;
}
@@ -284,6 +333,7 @@ class PermissionRoles {
*/
static public function roles() {
$roles = [
t('Social Networking') => [
'social_federation' => t('Social - Federation'),
'social' => t('Social - Mostly Public'),
@@ -317,4 +367,29 @@ class PermissionRoles {
return $roles;
}
}
/**
* @brief Array with translated role names and grouping.
*
* Return an associative array with role names that can be used
* to create select groups like in \e field_select_grouped.tpl.
*
* @return array
*/
static public function channel_roles() {
$channel_roles = [
//'public' => [t('Public'), t('A very permissive role suited for participation in the fediverse')],
//'personal' => [t('Personal'), t('The $Projectname default role suited for a personal channel')],
//'forum' => [t('Community forum'), t('This role configures your channel to act as an community forum')],
//'custom' => [t('Custom'), t('This role comes with the presets of the personal role but allows you to configure it to your needs')]
'public' => t('Public'),
'personal' => t('Personal'),
'group' => t('Community forum'),
'custom' => t('Custom')
];
call_hooks('list_channel_roles', $channel_roles);
return $channel_roles;
}
}

View File

@@ -41,7 +41,7 @@ class Permissions {
* @return number
*/
static public function version() {
return 2;
return 3;
}
/**
@@ -65,17 +65,17 @@ class Permissions {
'write_wiki' => t('Can write to my wiki pages'),
'post_wall' => t('Can post on my channel (wall) page'),
'post_comments' => t('Can comment on or like my posts'),
'post_mail' => t('Can send me private mail messages'),
'post_mail' => t('Can send me direct messages'),
'post_like' => t('Can like/dislike profiles and profile things'),
'tag_deliver' => t('Can forward to all my channel connections via ! mentions in posts'),
'chat' => t('Can chat with me'),
'republish' => t('Can source my public posts in derived channels'),
'republish' => t('Can source/mirror my public posts in derived channels'),
//'tag_deliver' => t('Can forward to my contacts via direct messages (forum)'),
'delegate' => t('Can administer my channel')
];
$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,84 +215,85 @@ class Permissions {
*/
static public function connect_perms($channel_id) {
$my_perms = [];
$permcat = null;
$automatic = 0;
$my_perms = [];
$permcat = null;
$automatic = get_pconfig($channel_id, 'system', 'autoperms');
// If a default permcat exists, use that
$pc = ((feature_enabled($channel_id,'permcats')) ? get_pconfig($channel_id,'system','default_permcat') : 'default');
if(! in_array($pc, [ '','default' ])) {
$pcp = new Zlib\Permcat($channel_id);
$permcat = $pcp->fetch($pc);
if($permcat && $permcat['perms']) {
foreach($permcat['perms'] as $p) {
$my_perms[$p['name']] = $p['value'];
}
$pc = get_pconfig($channel_id, 'system', 'default_permcat', 'default');
$pcp = new Zlib\Permcat($channel_id);
$permcat = $pcp->fetch($pc);
if ($permcat && $permcat['perms']) {
foreach ($permcat['perms'] as $p) {
$my_perms[$p['name']] = $p['value'];
}
}
// look up the permission role to see if it specified auto-connect
// and if there was no permcat or a default permcat, set the perms
// from the role
$role = get_pconfig($channel_id,'system','permissions_role');
if($role) {
/*
$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);
}
}
*/
// If we reached this point without having any permission information,
// it is likely a custom permissions role. First see if there are any
// automatic permissions.
if(! $my_perms) {
/*
if (!$my_perms) {
$m = Permissions::FilledAutoperms($channel_id);
if($m) {
if ($m) {
$automatic = 1;
$my_perms = $m;
$my_perms = $m;
}
}
*/
// If we reached this point with no permissions, the channel is using
// custom perms but they are not automatic. They will be stored in abconfig with
// the channel's channel_hash (the 'self' connection).
if(! $my_perms) {
/*
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, 'role' => $pc]);
}
/*
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

@@ -0,0 +1,34 @@
<?php
namespace Zotlabs\Daemon;
class Channel_purge {
static public function run($argc,$argv) {
cli_startup();
$channel_id = intval($argv[1]);
$channel = q("select * from channel where channel_id = %d and channel_removed = 1",
intval($channel_id)
);
if (! $channel) {
return;
}
do {
$r = q("select id from item where uid = %d and item_deleted = 0 limit 1000",
intval($channel_id)
);
if ($r) {
foreach ($r as $rv) {
drop_item($rv['id'], false);
}
}
} while ($r);
return;
}
}

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()),

View File

@@ -0,0 +1,77 @@
<?php
namespace Zotlabs\Daemon;
use Zotlabs\Web\HTTPSig;
use Zotlabs\Lib\PConfig;
require_once('include/cli_startup.php');
require_once('include/attach.php');
require_once('include/import.php');
class Content_importer {
static public function run($argc,$argv) {
cli_startup();
$page = $argv[1];
$since = $argv[2];
$until = $argv[3];
$channel_address = $argv[4];
$hz_server = urldecode($argv[5]);
$m = parse_url($hz_server);
$channel = channelx_by_nick($channel_address);
if(! $channel) {
logger('channel not found');
return;
}
$headers = [
'X-API-Token' => random_string(),
'X-API-Request' => $hz_server . '/api/z/1.0/item/export_page?f=&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page ,
'Host' => $m['host'],
'(request-target)' => 'get /api/z/1.0/item/export_page?f=&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page ,
];
$headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'], channel_url($channel),true,'sha512');
$x = z_fetch_url($hz_server . '/api/z/1.0/item/export_page?f=&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page,false,$redirects,[ 'headers' => $headers ]);
// logger('item fetch: ' . print_r($x,true));
if(! $x['success']) {
logger('no API response',LOGGER_DEBUG);
killme();
}
$j = json_decode($x['body'],true);
if(! is_array($j['item']) || ! count($j['item'])) {
PConfig::Set($channel['channel_id'], 'import', 'content_completed', 1);
return;
}
$saved_notification_flags = notifications_off($channel['channel_id']);
import_items($channel,$j['item'],false,((array_key_exists('relocate',$j)) ? $j['relocate'] : null));
notifications_on($channel['channel_id'], $saved_notification_flags);
PConfig::Set($channel['channel_id'], 'import', 'content_progress', [
'items_total' => $j['items_total'],
'items_page' => $j['items_page'],
'items_current_page' => count($j['item']),
'last_page' => $page,
'next_cmd' => ['Content_importer', sprintf('%d',$page + 1), $since, $until, $channel['channel_address'], urlencode($hz_server)]
]);
$page++;
Master::Summon([ 'Content_importer', sprintf('%d',$page), $since, $until, $channel['channel_address'], urlencode($hz_server) ]);
return;
}
}

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,21 +21,21 @@ 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'));
Master::Summon(array('Poller'));
/**
@@ -46,27 +46,27 @@ class Cron {
db_utcnow(),
db_quoteinterval('3 MINUTE')
);
// expire any expired mail
q("delete from mail where expires > '%s' and expires < %s ",
dbesc(NULL_DATE),
db_utcnow()
);
require_once('include/account.php');
remove_expired_registrations();
$interval = get_config('system', 'delivery_interval', 3);
// expire any expired items
$r = q("select id,item_wall from item where expires > '2001-01-01 00:00:00' and expires < %s
$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 +78,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 +90,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);
@@ -126,80 +126,72 @@ class Cron {
// publish any applicable items that were set to be published in the future
// (time travel posts). Restrict to items that have come of age in the last
// couple of days to limit the query to something reasonable.
// couple of days to limit the query to something reasonable.
$r = q("select id from item where item_delayed = 1 and created <= %s and created > '%s' ",
db_utcnow(),
dbesc(datetime_convert('UTC','UTC','now - 2 days'))
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);
}
}
}
// check if any connections transitioned to zot6 and upgrade the connections to zot6 at this hub if so.
require_once('include/connections.php');
z6trans_connections();
require_once('include/attach.php');
attach_upgrade();
$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'));
}
// update any photos which didn't get imported properly
// This should be rare
$r = q("select xchan_photo_l, xchan_hash from xchan where xchan_photo_l != '' and xchan_photo_m = ''
$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,33 +205,29 @@ 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)
Master::Summon(array('Externals'));
$disable_discover_tab = get_config('system', 'disable_discover_tab') || get_config('system', 'disable_discover_tab') === false;
if (!$disable_discover_tab)
Master::Summon(['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
//All done - clear the lockfile
@unlink($lockfile);
return;

View File

@@ -2,9 +2,11 @@
namespace Zotlabs\Daemon;
use Zotlabs\Lib\Libzotdir;
class Cron_daily {
static public function run($argc,$argv) {
static public function run($argc, $argv) {
logger('cron_daily: start');
@@ -13,15 +15,12 @@ class Cron_daily {
*
*/
require_once('include/dir_fns.php');
check_upstream_directory();
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'));
}
@@ -52,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
@@ -67,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",
@@ -80,28 +79,26 @@ class Cron_daily {
downgrade_accounts();
// If this is a directory server, request a sync with an upstream
// directory at least once a day, up to once every poll interval.
// directory at least once a day, up to once every poll interval.
// Pull remote changes and push local changes.
// potential issue: how do we keep from creating an endless update loop?
// 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) {
require_once('include/dir_fns.php');
sync_directories($dirmode);
if ($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) {
Libzotdir::sync_directories($dirmode);
}
Master::Summon(array('Expire'));
Master::Summon(array('Cli_suggest'));
remove_obsolete_hublocs();
remove_duplicate_singleton_hublocs();
z6_discover();
$date = datetime_convert();
call_hooks('cron_daily', $date);
call_hooks('cron_daily',datetime_convert());
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

@@ -2,28 +2,28 @@
namespace Zotlabs\Daemon;
require_once('include/queue_fn.php');
use Zotlabs\Lib\Queue;
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

@@ -0,0 +1,25 @@
<?php
namespace Zotlabs\Daemon;
require_once('include/connections.php');
/*
* Daemon to remove 'item' resources in the background from a removed connection
*/
class Delxitems {
static public function run($argc, $argv) {
cli_startup();
if($argc != 3) {
return;
}
remove_abook_items($argv[1], $argv[2]);
return;
}
}

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,9 @@ 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,20 +64,18 @@ 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.
*/
$hash = random_string();
$hash = new_uuid();
Queue::insert(array(
'hash' => $hash,
@@ -95,8 +94,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

@@ -2,26 +2,28 @@
namespace Zotlabs\Daemon;
require_once('include/items.php');
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 +34,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 +65,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 +95,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,153 @@
namespace Zotlabs\Daemon;
require_once('include/zot.php');
use Zotlabs\Lib\Activity;
use Zotlabs\Lib\Libzot;
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 {
$networks = ['zot6'];
if (plugin_is_installed('pubcrawl')) {
$networks[] = 'activitypub';
}
stringify_array_elms($networks);
$networks_str = implode(',', $networks);
$randfunc = db_getfunc('RAND');
// fixme this query does not deal with directory realms.
// fixme this query does not deal with directory realms.
//$r = q("select site_url, site_pull from site where site_url != '%s'
//and site_flags != %d and site_type = %d
//and site_dead = 0 and site_project like '%s' and site_version > '5.3.1' order by $randfunc limit 1",
//dbesc(z_root()),
//intval(DIRECTORY_MODE_STANDALONE),
//intval(SITE_TYPE_ZOT),
//dbesc('hubzilla%')
//);
$r = q("select site_url, site_pull from site where site_url != '%s' and site_flags != %d and site_type = %d and site_dead = 0 order by $randfunc limit 1",
$r = q("SELECT * FROM hubloc
LEFT JOIN abook ON abook_xchan = hubloc_hash
LEFT JOIN site ON site_url = hubloc_url WHERE
hubloc_network IN ( $networks_str ) AND
abook_xchan IS NULL AND
hubloc_url != '%s' AND
hubloc_updated > '%s' AND
hubloc_primary = 1 AND hubloc_deleted = 0 AND
site_dead = 0
ORDER BY $randfunc LIMIT 1",
dbesc(z_root()),
intval(DIRECTORY_MODE_STANDALONE),
intval(SITE_TYPE_ZOT)
datetime_convert('UTC', 'UTC', 'now - 30 days')
);
if($r)
$url = $r[0]['site_url'];
$contact = $r[0];
if ($contact) {
$url = $contact['hubloc_id_url'];
}
}
if (!$url) {
continue;
}
$blacklisted = false;
if(! check_siteallowed($url)) {
if (!check_siteallowed($contact['hubloc_url'])) {
logger('blacklisted site: ' . $url);
$blacklisted = true;
}
$attempts ++;
$attempts++;
// make sure we can eventually break out if somebody blacklists all known sites
if($blacklisted) {
if($attempts > 20)
if ($blacklisted) {
if ($attempts > 5)
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'));
}
$cl = Activity::get_actor_collections($contact['hubloc_hash']);
if(empty($cl)) {
$cl = get_xconfig($contact['hubloc_hash'], 'activitypub', 'collections');
}
$feedurl = $url . '/zotfeed?f=&mindate=' . $mindate;
logger('externals: pulling public content from ' . $feedurl, LOGGER_DEBUG);
$x = z_fetch_url($feedurl);
if(($x) && ($x['success'])) {
q("update site set site_pull = '%s' where site_url = '%s'",
dbesc(datetime_convert()),
dbesc($url)
);
$j = json_decode($x['body'],true);
if($j['success'] && $j['messages']) {
$sys = get_sys_channel();
foreach($j['messages'] as $message) {
// on these posts, clear any route info.
$message['route'] = '';
$results = process_delivery(array('hash' => 'undefined'), get_item_elements($message),
array(array('hash' => $sys['xchan_hash'])), false, true);
$total ++;
}
logger('externals: import_public_posts: ' . $total . ' messages imported', LOGGER_DEBUG);
}
if (is_array($cl) && array_key_exists('outbox', $cl)) {
$url = $cl['outbox'];
}
else {
$url = str_replace('/channel/', '/outbox/', $contact['hubloc_id_url']);
if ($url) {
$url .= '?top=1';
}
}
if ($url) {
logger('fetching outbox: ' . $url);
$obj = new ASCollection($url, $importer, 0, 10);
$messages = $obj->get();
if ($messages) {
foreach ($messages as $message) {
if (is_string($message)) {
$message = Activity::fetch($message, $importer);
}
if ($message['type'] !== 'Create') {
continue;
}
if ($contact['hubloc_network'] === 'zot6') {
// make sure we only fetch top level items
if (isset($message['object']['inReplyTo'])) {
continue;
}
Libzot::fetch_conversation($importer, $message['object']['id']);
$total++;
continue;
}
$AS = new ActivityStreams($message);
if ($AS->is_valid() && is_array($AS->obj)) {
$item = Activity::decode_note($AS);
Activity::store($importer, $contact['abook_xchan'], $AS, $item);
$total++;
}
}
}
logger('fetched messages count: ' . $total);
}
}
return;
}
}

View File

@@ -0,0 +1,71 @@
<?php
namespace Zotlabs\Daemon;
use Zotlabs\Web\HTTPSig;
use Zotlabs\Lib\PConfig;
require_once('include/cli_startup.php');
require_once('include/attach.php');
require_once('include/import.php');
class File_importer {
static public function run($argc,$argv) {
cli_startup();
$page = $argv[1];
$channel_address = $argv[2];
$hz_server = urldecode($argv[3]);
$m = parse_url($hz_server);
$channel = channelx_by_nick($channel_address);
if(! $channel) {
logger('channel not found');
return;
}
$headers = [
'X-API-Token' => random_string(),
'X-API-Request' => $hz_server . '/api/z/1.0/file/export_page?f=records=1&page=' . $page,
'Host' => $m['host'],
'(request-target)' => 'get /api/z/1.0/file/export_page?f=records=1&page=' . $page,
];
$headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),true,'sha512');
// TODO: implement total count
$x = z_fetch_url($hz_server . '/api/z/1.0/file/export_page?f=records=1&page=' . $page, false, $redirects, [ 'headers' => $headers ]);
// logger('file fetch: ' . print_r($x,true));
if(! $x['success']) {
logger('no API response',LOGGER_DEBUG);
killme();
}
$j = json_decode($x['body'],true);
if(! is_array($j['results'][0]['attach']) || ! count($j['results'][0]['attach'])) {
PConfig::Set($channel['channel_id'], 'import', 'files_completed', 1);
return;
}
$r = sync_files($channel, $j['results']);
PConfig::Set($channel['channel_id'], 'import', 'files_progress', [
'files_total' => $j['total'],
'files_page' => 1, // export page atm returns just one file
'last_page' => $page,
'next_cmd' => ['File_importer',sprintf('%d',$page + 1), $channel['channel_address'], urlencode($hz_server)]
]);
$page++;
Master::Summon([ 'File_importer',sprintf('%d',$page), $channel['channel_address'], urlencode($hz_server) ]);
return;
}
}

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' limit 1",
$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);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,31 +2,31 @@
namespace Zotlabs\Daemon;
require_once('include/zot.php');
require_once('include/dir_fns.php');
use Zotlabs\Lib\Libzot;
use Zotlabs\Lib\Libzotdir;
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;
}
$r = q("select * from updates where ud_id = %d limit 1",
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
@@ -38,8 +38,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),
@@ -50,26 +50,28 @@ class Onedirsync {
// ignore doing an update if this ud_addr refers to a known dead hubloc
$h = q("select * from hubloc where hubloc_addr = '%s' limit 1",
dbesc($r[0]['ud_addr'])
$h = q("select * from hubloc where hubloc_addr = '%s'",
dbesc($r[0]['ud_addr']),
);
if(($h) && ($h[0]['hubloc_status'] & HUBLOC_OFFLINE)) {
$y = q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 ",
intval(UPDATE_FLAGS_UPDATED),
$h = Libzot::zot_record_preferred($h);
if (($h) && (($h['hubloc_status'] & HUBLOC_OFFLINE) || $h['hubloc_deleted'] || $h['hubloc_error'])) {
q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 ",
intval(UPDATE_FLAGS_DELETED),
dbesc($r[0]['ud_addr']),
intval(UPDATE_FLAGS_UPDATED)
);
return;
}
// we might have to pull this out some day, but for now update_directory_entry()
// we might have to pull this out some day, but for now update_directory_entry()
// runs zot_finger() and is kind of zot specific
if($h && $h[0]['hubloc_network'] !== 'zot')
if ($h && $h['hubloc_network'] !== 'zot6')
return;
update_directory_entry($r[0]);
Libzotdir::update_directory_entry($r[0]);
return;
}

View File

@@ -2,68 +2,67 @@
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');
require_once('include/feedutils.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 = $contacts[0];
$importer_uid = $contact['abook_channel'];
$r = q("SELECT * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1",
intval($importer_uid)
);
if(! $r)
$importer = channelx_by_n($importer_uid);
if (!$importer)
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 +71,18 @@ class Onepoll {
}
return;
}
if(! in_array($contact['xchan_network'],['zot','zot6']))
if ($contact['xchan_network'] !== 'zot6')
return;
// update permissions
if($contact['xchan_network'] === 'zot6')
$x = Libzot::refresh($contact,$importer);
if($contact['xchan_network'] === 'zot')
$x = zot_refresh($contact,$importer);
$x = Libzot::refresh($contact, $importer);
$responded = false;
$updated = datetime_convert();
$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 +98,87 @@ class Onepoll {
$responded = true;
}
if(! $responded)
if (!$responded)
return;
if($contact['xchan_connurl']) {
$fetch_feed = true;
$x = null;
$fetch_feed = true;
// 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
$can_send_stream = intval(get_abconfig($importer_uid, $contact['abook_xchan'], 'my_perms', 'send_stream'));
// we haven't given them permission to send us their stream
if (!$can_send_stream) {
$fetch_feed = false;
}
$can_send_stream = intval(get_abconfig($importer_uid,$contact['abook_xchan'],'my_perms','send_stream'));
if(! $can_send_stream)
$fetch_feed = false;
if ($fetch_feed) {
if($fetch_feed) {
$max = intval(get_config('system', 'max_imported_posts', 30));
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 (intval($max)) {
$cl = Activity::get_actor_collections($contact['abook_xchan']);
if(empty($cl)) {
$cl = get_xconfig($contact['abook_xchan'], 'activitypub', 'collections');
}
if (is_array($cl) && array_key_exists('outbox', $cl)) {
$url = $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/', '/outbox/', $contact['xchan_connurl']);
}
logger('feed_update: ' . print_r($x,true), LOGGER_DATA);
}
if ($url) {
logger('fetching outbox');
$url = $url . '?date_begin=' . urlencode($last_update);
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($contact['xchan_network'] === 'zot6') {
$url = $url . '&top=1';
}
$obj = new ASCollection($url, $importer, 0, $max);
$messages = $obj->get();
if ($messages) {
foreach ($messages as $message) {
if (is_string($message)) {
$message = Activity::fetch($message, $importer);
}
if ($contact['xchan_network'] === 'zot6') {
// make sure we only fetch top level items
if ($message['type'] === 'Create' && !isset($message['object']['inReplyTo'])) {
Libzot::fetch_conversation($importer, $message['object']['id']);
}
continue;
}
$AS = new ActivityStreams($message);
if ($AS->is_valid() && is_array($AS->obj)) {
$item = Activity::decode_note($AS);
Activity::store($importer, $contact['abook_xchan'], $AS, $item);
}
}
}
logger("onepoll: $total messages processed");
}
}
}
// update the poco details for this connection
$r = q("SELECT xlink_id from xlink where xlink_xchan = '%s' and xlink_updated > %s - INTERVAL %s and xlink_static = 0 limit 1",
intval($contact['xchan_hash']),
db_utcnow(),
db_quoteinterval('1 DAY')
);
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']);
}
if (!$r) {
poco_load($contact['xchan_hash'], $contact['xchan_connurl']);
}
return;

View File

@@ -4,201 +4,193 @@ 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;
}
$sql_extra = (($manual_id) ? " AND abook_id = " . intval($manual_id) . " " : "");
reload_plugins();
$d = datetime_convert();
// Only poll from those with suitable relationships
$abandon_sql = (($abandon_days)
? sprintf(" AND account_lastlog > %s - INTERVAL %s ", db_utcnow(), db_quoteinterval(intval($abandon_days).' DAY'))
: ''
$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,
xchan.xchan_network,
account.account_lastlog, account.account_flags
FROM abook LEFT JOIN xchan on abook_xchan = xchan_hash
account.account_lastlog, account.account_flags
FROM abook LEFT JOIN xchan on abook_xchan = xchan_hash
LEFT JOIN account on abook_account = account_id
where abook_self = 0
$sql_extra
$sql_extra
AND (( account_flags = %d ) OR ( account_flags = %d )) $abandon_sql ORDER BY $randfunc",
intval(ACCOUNT_OK),
intval(ACCOUNT_UNVERIFIED) // FIXME
);
if($contacts) {
if ($contacts) {
foreach ($contacts as $contact) {
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 ($contact['xchan_network'] !== '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);
}
}
if($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) {
$dirmode = intval(get_config('system', 'directory_mode'));
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
//All done - clear the lockfile
@unlink($lockfile);

View File

@@ -2,17 +2,16 @@
namespace Zotlabs\Daemon;
require_once('include/queue_fn.php');
require_once('include/zot.php');
use Zotlabs\Lib\Queue as LibQueue;
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,11 +24,10 @@ 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']);
$desturl = $h['scheme'] . '://' . $h['host'] . (($h['port']) ? ':' . $h['port'] : '');
if ($r) {
foreach ($r as $rr) {
$h = parse_url($rr['outq_posturl']);
$desturl = $h['scheme'] . '://' . $h['host'] . (isset($h['port']) ? ':' . $h['port'] : '');
q("update site set site_dead = 1 where site_dead = 0 and site_url = '%s' and site_update < %s - INTERVAL %s",
dbesc($desturl),
db_utcnow(), db_quoteinterval('1 MONTH')
@@ -37,11 +35,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)
);
@@ -49,17 +47,17 @@ class Queue {
else {
// For the first 12 hours we'll try to deliver every 15 minutes
// After that, we'll only attempt delivery once per hour.
// This currently only handles the default queue drivers ('zot' or '') which we will group by posturl
// After that, we'll only attempt delivery once per hour.
// This currently only handles the default queue drivers ('zot' or '') which we will group by posturl
// so that we don't start off a thousand deliveries for a couple of dead hubs.
// The zot driver will deliver everything destined for a single hub once contact is made (*if* contact is made).
// Other drivers will have to do something different here and may need their own query.
// Note: this requires some tweaking as new posts to long dead hubs once a day will keep them in the
// Note: this requires some tweaking as new posts to long dead hubs once a day will keep them in the
// "every 15 minutes" category. We probably need to prioritise them when inserted into the queue
// or just prior to this query based on recent and long-term delivery history. If we have good reason to believe
// the site is permanently down, there's no reason to attempt delivery at all, or at most not more than once
// or twice a day.
// the site is permanently down, there's no reason to attempt delivery at all, or at most not more than once
// or twice a day.
$sqlrandfunc = db_getfunc('rand');
@@ -67,19 +65,19 @@ class Queue {
db_utcnow()
);
while ($r) {
foreach($r as $rv) {
queue_deliver($rv);
foreach ($r as $rv) {
LibQueue::deliver($rv);
}
$r = q("SELECT *,$sqlrandfunc as rn FROM outq WHERE outq_delivered = 0 and outq_scheduled < %s order by rn limit 1",
db_utcnow()
);
}
}
if(! $r)
if (!$r)
return;
foreach($r as $rv) {
queue_deliver($rv);
foreach ($r as $rv) {
LibQueue::deliver($rv);
}
}
}

View File

@@ -1,126 +0,0 @@
<?php
namespace Zotlabs\Daemon;
require_once('include/zot.php');
require_once('include/queue_fn.php');
class Ratenotif {
static public function run($argc,$argv) {
// Deprecated
return;
require_once("datetime.php");
require_once('include/items.php');
if($argc < 3)
return;
logger('ratenotif: invoked: ' . print_r($argv,true), LOGGER_DEBUG);
$cmd = $argv[1];
$item_id = $argv[2];
if($cmd === 'rating') {
$r = q("select * from xlink where xlink_id = %d and xlink_static = 1 limit 1",
intval($item_id)
);
if(! $r) {
logger('rating not found');
return;
}
$encoded_item = array(
'type' => 'rating',
'encoding' => 'zot',
'target' => $r[0]['xlink_link'],
'rating' => intval($r[0]['xlink_rating']),
'rating_text' => $r[0]['xlink_rating_text'],
'signature' => $r[0]['xlink_sig'],
'edited' => $r[0]['xlink_updated']
);
}
$channel = channelx_by_hash($r[0]['xlink_xchan']);
if(! $channel) {
logger('no channel');
return;
}
$primary = get_directory_primary();
if(! $primary)
return;
$interval = ((get_config('system','delivery_interval') !== false)
? intval(get_config('system','delivery_interval')) : 2 );
$deliveries_per_process = intval(get_config('system','delivery_batch_count'));
if($deliveries_per_process <= 0)
$deliveries_per_process = 1;
$deliver = array();
$x = z_fetch_url($primary . '/regdir');
if($x['success']) {
$j = json_decode($x['body'],true);
if($j && $j['success'] && is_array($j['directories'])) {
foreach($j['directories'] as $h) {
if($h == z_root())
continue;
$hash = random_string();
$n = zot_build_packet($channel,'notify',null,null,'',$hash);
queue_insert(array(
'hash' => $hash,
'account_id' => $channel['channel_account_id'],
'channel_id' => $channel['channel_id'],
'posturl' => $h . '/post',
'notify' => $n,
'msg' => json_encode($encoded_item)
));
$x = q("select count(outq_hash) as total from outq where outq_delivered = 0");
if(intval($x[0]['total']) > intval(get_config('system','force_queue_threshold',300))) {
logger('immediate delivery deferred.', LOGGER_DEBUG, LOG_INFO);
update_queue_item($hash);
continue;
}
$deliver[] = $hash;
if(count($deliver) >= $deliveries_per_process) {
Master::Summon(array('Deliver',$deliver));
$deliver = array();
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
}
}
// catch any stragglers
if(count($deliver)) {
Master::Summon(array('Deliver',$deliver));
}
}
}
logger('ratenotif: complete.');
return;
}
}

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,38 @@ 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);
}
}

View File

@@ -1,38 +1,37 @@
<?php
<?php
namespace Zotlabs\Lib;
use Zotlabs\Lib\Libsync;
class AccessList {
static function add($uid,$name,$public = 0) {
$ret = false;
static function add($uid, $name, $public = 0) {
$ret = false;
$hash = '';
if ($uid && $name) {
$r = self::byname($uid,$name); // check for dups
$r = self::by_name($uid, $name); // check for dups
if ($r !== false) {
// This could be a problem.
// This could be a problem.
// Let's assume we've just created a list which we once deleted
// all the old members are gone, but the list remains so we don't break any security
// access lists. What we're doing here is reviving the dead list, but old content which
// was restricted to this list may now be seen by the new list members.
// was restricted to this list may now be seen by the new list members.
$z = q("SELECT * FROM pgrp WHERE id = %d LIMIT 1",
intval($r)
);
if(($z) && $z[0]['deleted']) {
if (($z) && $z[0]['deleted']) {
q('UPDATE pgrp SET deleted = 0 WHERE id = %d', intval($z[0]['id']));
notice( t('A deleted list with this name was revived. Existing item permissions <strong>may</strong> apply to this list and any future members. If this is not what you intended, please create another list with a different name.') . EOL);
notice(t('A deleted privacy group with this name was revived. Existing item permissions <strong>may</strong> apply to this privacy group and any future members. If this is not what you intended, please create another privacy group with a different name.') . EOL);
}
return true;
$hash = self::by_id($uid, $r);
return $hash;
}
$hash = new_uuid();
$r = q("INSERT INTO pgrp ( hash, uid, visible, gname )
$r = q("INSERT INTO pgrp ( hash, uid, visible, gname )
VALUES( '%s', %d, %d, '%s' ) ",
dbesc($hash),
intval($uid),
@@ -42,12 +41,12 @@ class AccessList {
$ret = $r;
}
Libsync::build_sync_packet($uid,null,true);
return $ret;
Libsync::build_sync_packet($uid, null, true);
return (($ret) ? $hash : $ret);
}
static function remove($uid,$name) {
static function remove($uid, $name) {
$ret = false;
if ($uid && $name) {
$r = q("SELECT id, hash FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1",
@@ -55,36 +54,36 @@ class AccessList {
dbesc($name)
);
if ($r) {
$group_id = $r[0]['id'];
$group_id = $r[0]['id'];
$group_hash = $r[0]['hash'];
}
else {
return false;
}
// remove group from default posting lists
$r = q("SELECT channel_default_group, channel_allow_gid, channel_deny_gid FROM channel WHERE channel_id = %d LIMIT 1",
intval($uid)
intval($uid)
);
if ($r) {
$user_info = array_shift($r);
$change = false;
$change = false;
if ($user_info['channel_default_group'] == $group_hash) {
$user_info['channel_default_group'] = '';
$change = true;
$change = true;
}
if (strpos($user_info['channel_allow_gid'], '<' . $group_hash . '>') !== false) {
$user_info['channel_allow_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_allow_gid']);
$change = true;
$change = true;
}
if (strpos($user_info['channel_deny_gid'], '<' . $group_hash . '>') !== false) {
$user_info['channel_deny_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_deny_gid']);
$change = true;
$change = true;
}
if ($change) {
q("UPDATE channel SET channel_default_group = '%s', channel_allow_gid = '%s', channel_deny_gid = '%s'
q("UPDATE channel SET channel_default_group = '%s', channel_allow_gid = '%s', channel_deny_gid = '%s'
WHERE channel_id = %d",
intval($user_info['channel_default_group']),
dbesc($user_info['channel_allow_gid']),
@@ -110,16 +109,16 @@ class AccessList {
}
Libsync::build_sync_packet($uid,null,true);
Libsync::build_sync_packet($uid, null, true);
return $ret;
}
// returns the integer id of an access group owned by $uid and named $name
// or false.
static function byname($uid,$name) {
if (! ($uid && $name)) {
static function by_name($uid, $name) {
if (!($uid && $name)) {
return false;
}
$r = q("SELECT id FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1",
@@ -132,11 +131,11 @@ class AccessList {
return false;
}
static function by_id($uid,$id) {
if (! ($uid && $id)) {
static function by_id($uid, $id) {
if (!($uid && $id)) {
return false;
}
$r = q("SELECT * FROM pgrp WHERE uid = %d AND id = %d and deleted = 0",
intval($uid),
intval($id)
@@ -147,10 +146,8 @@ class AccessList {
return false;
}
static function rec_byhash($uid,$hash) {
if (! ( $uid && $hash)) {
static function by_hash($uid, $hash) {
if (!($uid && $hash)) {
return false;
}
$r = q("SELECT * FROM pgrp WHERE uid = %d AND hash = '%s' LIMIT 1",
@@ -163,46 +160,43 @@ class AccessList {
return false;
}
static function member_remove($uid, $name, $member) {
$gid = self::by_name($uid, $name);
static function member_remove($uid,$name,$member) {
$gid = self::byname($uid,$name);
if (! $gid) {
return false;
}
if (! ($uid && $gid && $member)) {
if (!($uid && $gid && $member)) {
return false;
}
$r = q("DELETE FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' ",
intval($uid),
intval($gid),
dbesc($member)
);
Libsync::build_sync_packet($uid,null,true);
Libsync::build_sync_packet($uid, null, true);
return $r;
}
static function member_add($uid,$name,$member,$gid = 0) {
if (! $gid) {
$gid = self::byname($uid,$name);
static function member_add($uid, $name, $member, $gid = 0) {
if (!$gid) {
$gid = self::by_name($uid, $name);
}
if (! ($gid && $uid && $member)) {
if (!($gid && $uid && $member)) {
return false;
}
$r = q("SELECT * FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' LIMIT 1",
$r = q("SELECT * FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' LIMIT 1",
intval($uid),
intval($gid),
dbesc($member)
);
if ($r) {
return true; // You might question this, but
// we indicate success because the group member was in fact created
// -- It was just created at another time
return true; // You might question this, but
// we indicate success because the group member was in fact created
// -- It was just created at another time
}
else {
else {
$r = q("INSERT INTO pgrp_member (uid, gid, xchan)
VALUES( %d, %d, '%s' ) ",
intval($uid),
@@ -210,15 +204,14 @@ class AccessList {
dbesc($member)
);
}
Libsync::build_sync_packet($uid,null,true);
Libsync::build_sync_packet($uid, null, true);
return $r;
}
static function members($uid, $gid) {
$ret = [];
if (intval($gid)) {
$r = q("SELECT * FROM pgrp_member
$r = q("SELECT * FROM pgrp_member
LEFT JOIN abook ON abook_xchan = pgrp_member.xchan left join xchan on xchan_hash = abook_xchan
WHERE gid = %d AND abook_channel = %d and pgrp_member.uid = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 ORDER BY xchan_name ASC ",
intval($gid),
@@ -232,7 +225,7 @@ class AccessList {
return $ret;
}
static function members_xchan($uid,$gid) {
static function members_xchan($uid, $gid) {
$ret = [];
if (intval($gid)) {
$r = q("SELECT xchan FROM pgrp_member WHERE gid = %d AND uid = %d",
@@ -248,99 +241,124 @@ class AccessList {
return $ret;
}
static function members_profile_xchan($uid,$gid) {
static function profile_members_xchan($uid,$gid) {
$ret = [];
if (intval($gid)) {
if(intval($gid)) {
$r = q("SELECT abook_xchan as xchan from abook left join profile on abook_profile = profile_guid where profile.id = %d and profile.uid = %d",
intval($gid),
intval($uid)
);
if ($r) {
foreach($r as $rv) {
$ret[] = $rv['xchan'];
if($r) {
foreach($r as $rr) {
$ret[] = $rr['xchan'];
}
}
}
return $ret;
}
static function select($uid, $options) {
$selected = $options['selected'] ?? '';
$form_id = $options['form_id'] ?? 'accesslist_select';
$label = $options['label'] ?? t('Select a privacy group');
$before = $options['before'] ?? [];
$after = $options['after'] ?? [];
static function select($uid,$group = '') {
$grps = [];
$o = '';
$grps[] = [
'name' => '',
'id' => '0',
'selected' => false
];
if ($before) {
$grps[] = $before;
}
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
intval($uid)
);
$grps[] = [ 'name' => '', 'hash' => '0', 'selected' => '' ];
if ($r) {
foreach ($r as $rr) {
$grps[] = [ 'name' => $rr['gname'], 'id' => $rr['hash'], 'selected' => (($group == $rr['hash']) ? 'true' : '') ];
}
if($r) {
foreach($r as $rr) {
$grps[] = [
'name' => $rr['gname'],
'id' => $rr['hash'],
'selected' => ($selected == $rr['hash'])
];
}
}
return replace_macros(get_markup_template('group_selection.tpl'), [
'$label' => t('Add new connections to this access list'),
'$groups' => $grps
]);
if ($after) {
$grps[] = $after;
}
logger('select: ' . print_r($grps,true), LOGGER_DATA);
$o = replace_macros(get_markup_template('group_selection.tpl'), array(
'$label' => $label,
'$form_id' => $form_id,
'$groups' => $grps
));
return $o;
}
static function widget($every="connections",$each="lists",$edit = false, $group_id = 0, $cid = '',$mode = 1) {
$o = '';
/* deprecated
static function widget($every = "connections", $each = "lists", $edit = false, $group_id = 0, $cid = '', $mode = 1) {
$groups = [];
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
intval($_SESSION['uid'])
);
$member_of = [];
if ($cid) {
$member_of = self::containing(local_channel(),$cid);
}
$member_of = self::containing(local_channel(), $cid);
}
if ($r) {
foreach ($r as $rr) {
$selected = (($group_id == $rr['id']) ? ' group-selected' : '');
if ($edit) {
$groupedit = [ 'href' => "lists/".$rr['id'], 'title' => t('edit') ];
}
$groupedit = ['href' => "lists/" . $rr['id'], 'title' => t('edit')];
}
else {
$groupedit = null;
}
$groups[] = [
'id' => $rr['id'],
'enc_cid' => base64url_encode($cid),
'cid' => $cid,
'text' => $rr['gname'],
'selected' => $selected,
'href' => (($mode == 0) ? $each.'?f=&gid='.$rr['id'] : $each."/".$rr['id']) . ((x($_GET,'new')) ? '&new=' . $_GET['new'] : '') . ((x($_GET,'order')) ? '&order=' . $_GET['order'] : ''),
'edit' => $groupedit,
'ismember' => in_array($rr['id'],$member_of),
'id' => $rr['id'],
'enc_cid' => base64url_encode($cid),
'cid' => $cid,
'text' => $rr['gname'],
'selected' => $selected,
'href' => (($mode == 0) ? $each . '?f=&gid=' . $rr['id'] : $each . "/" . $rr['id']) . ((x($_GET, 'new')) ? '&new=' . $_GET['new'] : '') . ((x($_GET, 'order')) ? '&order=' . $_GET['order'] : ''),
'edit' => $groupedit,
'ismember' => in_array($rr['id'], $member_of),
];
}
}
return replace_macros(get_markup_template('group_side.tpl'), [
'$title' => t('Lists'),
'$edittext' => t('Edit list'),
'$createtext' => t('Create new list'),
'$ungrouped' => (($every === 'contacts') ? t('Channels not in any access list') : ''),
'$groups' => $groups,
'$add' => t('add'),
'$title' => t('Privacy Groups'),
'$edittext' => t('Edit group'),
'$createtext' => t('Create new group'),
'$ungrouped' => (($every === 'contacts') ? t('Channels not in any privacy group') : ''),
'$groups' => $groups,
'$add' => t('Add'),
]);
}
*/
static function expand($g) {
if (! (is_array($g) && count($g))) {
if (!(is_array($g) && count($g))) {
return [];
}
@@ -350,8 +368,8 @@ class AccessList {
// private profile linked virtual groups
foreach ($g as $gv) {
if (substr($gv,0,3) === 'vp.') {
$profile_hash = substr($gv,3);
if (substr($gv, 0, 3) === 'vp.') {
$profile_hash = substr($gv, 3);
if ($profile_hash) {
$r = q("select abook_xchan from abook where abook_profile = '%s'",
dbesc($profile_hash)
@@ -366,10 +384,10 @@ class AccessList {
else {
$x[] = $gv;
}
}
}
if ($x) {
stringify_array_elms($x,true);
stringify_array_elms($x, true);
$groups = implode(',', $x);
if ($groups) {
$r = q("SELECT xchan FROM pgrp_member WHERE gid IN ( select id from pgrp where hash in ( $groups ))");
@@ -383,9 +401,8 @@ class AccessList {
return $ret;
}
static function member_of($c) {
$r = q("SELECT pgrp.gname, pgrp.id FROM pgrp LEFT JOIN pgrp_member ON pgrp_member.gid = pgrp.id
$r = q("SELECT pgrp.gname, pgrp.id FROM pgrp LEFT JOIN pgrp_member ON pgrp_member.gid = pgrp.id
WHERE pgrp_member.xchan = '%s' AND pgrp.deleted = 0 ORDER BY pgrp.gname ASC ",
dbesc($c)
);
@@ -393,7 +410,7 @@ class AccessList {
return $r;
}
static function containing($uid,$c) {
static function containing($uid, $c) {
$r = q("SELECT gid FROM pgrp_member WHERE uid = %d AND pgrp_member.xchan = '%s' ",
intval($uid),
@@ -405,7 +422,8 @@ class AccessList {
foreach ($r as $rv)
$ret[] = $rv['gid'];
}
return $ret;
}
}
}

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', 'Announce', 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject', 'emojiReaction', 'EmojiReaction', 'EmojiReact' ]));
return (in_array($s, ['Like', 'Dislike', 'Flag', 'Block', 'Announce', 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject', 'emojiReaction', 'EmojiReaction', 'EmojiReact']));
}
/**
@@ -298,25 +297,17 @@ 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)) {
// SECURITY: If we have already stored the actor profile, re-generate it
// from cached data - don't refetch it from the network
$r = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_id_url = '%s' limit 1",
dbesc($x)
);
if($r) {
$y = Activity::encode_person($r[0]);
$y['cached'] = true;
if ($this->is_url($x)) {
$y = Activity::get_cached_actor($x);
if ($y) {
return $y;
}
}
$actor = $this->get_compound_property($property,$base,$namespace,true);
if(is_array($actor) && self::is_an_actor($actor['type'])) {
if(array_key_exists('id',$actor) && (! array_key_exists('inbox',$actor))) {
$actor = $this->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 +327,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;
@@ -344,23 +335,23 @@ 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 +365,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 +380,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 +400,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

@@ -2,7 +2,7 @@
namespace Zotlabs\Lib;
use Zotlabs\Lib\Libsync;
use App;
require_once('include/plugin.php');
require_once('include/channel.php');
@@ -21,9 +21,10 @@ class Apps {
* @brief
*
* @param boolean $translate (optional) default true
* @param boolean $sync (optional) default false used if called from sync_sysapps()
* @return array
*/
static public function get_system_apps($translate = true) {
static public function get_system_apps($translate = true, $sync = false) {
$ret = [];
if(is_dir('apps'))
@@ -33,7 +34,7 @@ class Apps {
if($files) {
foreach($files as $f) {
$x = self::parse_app_description($f,$translate);
$x = self::parse_app_description($f, $translate, $sync);
if($x) {
$ret[] = $x;
}
@@ -45,7 +46,7 @@ class Apps {
$path = explode('/',$f);
$plugin = trim($path[1]);
if(plugin_is_installed($plugin)) {
$x = self::parse_app_description($f,$translate);
$x = self::parse_app_description($f, $translate, $sync);
if($x) {
$x['plugin'] = $plugin;
$ret[] = $x;
@@ -66,17 +67,17 @@ class Apps {
static public function get_base_apps() {
$x = get_config('system','base_apps',[
'Connections',
'Contact Roles',
'Network',
'Settings',
'Files',
'Channel Home',
'View Profile',
'Channel',
'Photos',
'Calendar',
'Directory',
'Search',
'Help',
'Profile Photo'
'HQ',
'Post'
]);
/**
@@ -207,9 +208,10 @@ class Apps {
*
* @param string $f filename
* @param boolean $translate (optional) default true
* @param boolean $sync (optional) default false
* @return boolean|array
*/
static public function parse_app_description($f, $translate = true) {
static public function parse_app_description($f, $translate = true, $sync = false) {
$ret = [];
$matches = [];
@@ -255,7 +257,7 @@ class Apps {
if(array_key_exists('categories',$ret))
$ret['categories'] = str_replace(array('\'','"'),array('&#39;','&dquot;'),$ret['categories']);
if(array_key_exists('requires',$ret)) {
if(array_key_exists('requires',$ret) && !$sync) {
$requires = explode(',',$ret['requires']);
foreach($requires as $require) {
$require = trim(strtolower($require));
@@ -307,14 +309,16 @@ class Apps {
}
}
}
if($ret) {
if($translate)
self::translate_system_apps($ret);
return $ret;
if(empty($ret)) {
return false;
}
return false;
if($translate) {
self::translate_system_apps($ret);
}
return $ret;
}
@@ -340,7 +344,7 @@ class Apps {
'Files' => t('Files'),
'Webpages' => t('Webpages'),
'Wiki' => t('Wiki'),
'Channel Home' => t('Channel Home'),
'Channel' => t('Channel'),
'View Profile' => t('View Profile'),
'Photos' => t('Photos'),
'Calendar' => t('Calendar'),
@@ -371,7 +375,7 @@ class Apps {
'OAuth Apps Manager' => t('OAuth Apps Manager'),
'OAuth2 Apps Manager' => t('OAuth2 Apps Manager'),
'PDL Editor' => t('PDL Editor'),
'Permission Categories' => t('Permission Categories'),
'Contact Roles' => t('Contact Roles'),
'Public Stream' => t('Public Stream'),
'My Chatrooms' => t('My Chatrooms'),
'Channel Export' => t('Channel Export')
@@ -524,7 +528,7 @@ class Apps {
}
elseif(remote_channel()) {
$observer = \App::get_observer();
if($observer && $observer['xchan_network'] === 'zot') {
if($observer && $observer['xchan_network'] === 'zot6') {
// some folks might have xchan_url redirected offsite, use the connurl
$x = parse_url($observer['xchan_connurl']);
if($x) {
@@ -536,13 +540,47 @@ class Apps {
$install_action = (($installed) ? t('Update') : t('Install'));
$icon = ((strpos($papp['photo'],'icon:') === 0) ? substr($papp['photo'],5) : '');
if (!$installed && $mode === 'module') {
$_SESSION['return_url'] = App::$query_string;
return replace_macros(get_markup_template('app_install.tpl'), [
'$papp' => $papp,
'$install' => $install_action
]);
}
if($mode === 'navbar') {
return replace_macros(get_markup_template('app_nav_pinned.tpl'),array(
'$app' => $papp,
'$icon' => $icon,
));
}
if($mode === 'nav') {
return replace_macros(get_markup_template('app_nav.tpl'),array(
'$app' => $papp,
'$icon' => $icon,
));
}
if($mode === 'inline') {
return replace_macros(get_markup_template('app_inline.tpl'),array(
'$app' => $papp,
'$icon' => $icon,
'$installed' => $installed,
'$purchase' => ((isset($papp['page']) && (! $installed)) ? t('Purchase') : ''),
'$action_label' => $install_action
));
}
if(in_array($mode, ['nav-order', 'nav-order-pinned'])) {
return replace_macros(get_markup_template('app_order.tpl'),array(
'$app' => $papp,
'$icon' => $icon,
'$hosturl' => $hosturl,
'$mode' => $mode
));
}
if($mode === 'install') {
$papp['embed'] = true;
}
@@ -551,7 +589,7 @@ class Apps {
'$app' => $papp,
'$icon' => $icon,
'$hosturl' => $hosturl,
'$purchase' => (($papp['page'] && (! $installed)) ? t('Purchase') : ''),
'$purchase' => ((isset($papp['page']) && (! $installed)) ? t('Purchase') : ''),
'$installed' => $installed,
'$action_label' => (($hosturl && in_array($mode, ['view','install'])) ? $install_action : ''),
'$edit' => ((local_channel() && $installed && $mode == 'edit') ? t('Edit') : ''),
@@ -559,12 +597,10 @@ class Apps {
'$undelete' => ((local_channel() && $mode == 'edit') ? t('Undelete') : ''),
'$settings_url' => ((local_channel() && $installed && $mode == 'list') ? $papp['settings_url'] : ''),
'$deleted' => $papp['deleted'],
'$feature' => (($papp['embed'] || $mode == 'edit') ? false : true),
'$pin' => (($papp['embed'] || $mode == 'edit') ? false : true),
'$feature' => ((isset($papp['embed']) || $mode == 'edit') ? false : true),
'$pin' => ((isset($papp['embed']) || $mode == 'edit') ? false : true),
'$featured' => ((strpos($papp['categories'], 'nav_featured_app') === false) ? false : true),
'$pinned' => ((strpos($papp['categories'], 'nav_pinned_app') === false) ? false : true),
'$navapps' => (($mode == 'nav') ? true : false),
'$order' => (($mode === 'nav-order' || $mode === 'nav-order-pinned') ? true : false),
'$mode' => $mode,
'$add' => t('Add to app-tray'),
'$remove' => t('Remove from app-tray'),
@@ -574,6 +610,7 @@ class Apps {
));
}
static public function app_install($uid,$app) {
if(! is_array($app)) {
@@ -588,10 +625,12 @@ class Apps {
$app['uid'] = $uid;
if(self::app_installed($uid,$app,true))
if(self::app_installed($uid,$app,true)) {
$x = self::app_update($app);
else
}
else {
$x = self::app_store($app);
}
if($x['success']) {
$r = q("select * from app where app_id = '%s' and app_channel = %d limit 1",
@@ -599,13 +638,12 @@ class Apps {
intval($uid)
);
if($r) {
if(($app['uid']) && (! $r[0]['app_system'])) {
if($app['uid']) {
if($app['categories'] && (! $app['term'])) {
$r[0]['term'] = q("select * from term where otype = %d and oid = %d",
intval(TERM_OBJ_APP),
intval($r[0]['id'])
);
Libsync::build_sync_packet($uid,array('app' => $r[0]));
}
}
}
@@ -634,6 +672,7 @@ class Apps {
}
}
}
return true;
}
@@ -645,38 +684,35 @@ class Apps {
dbesc($app['guid']),
intval($uid)
);
if($x) {
if(! intval($x[0]['app_deleted'])) {
$x[0]['app_deleted'] = 1;
if(self::can_delete($uid,$app)) {
q("delete from app where app_id = '%s' and app_channel = %d",
dbesc($app['guid']),
intval($uid)
);
q("delete from term where otype = %d and oid = %d",
intval(TERM_OBJ_APP),
intval($x[0]['id'])
);
/**
* @hooks app_destroy
* Called after app entry got removed from database
* and provide app array from database.
*/
call_hooks('app_destroy', $x[0]);
}
else {
q("update app set app_deleted = 1 where app_id = '%s' and app_channel = %d",
dbesc($app['guid']),
intval($uid)
);
}
if(! intval($x[0]['app_system'])) {
Libsync::build_sync_packet($uid,array('app' => $x));
}
}
else {
self::app_undestroy($uid,$app);
}
if($x && intval($x[0]['app_deleted'])) {
self::app_undestroy($uid, $app);
return;
}
if(self::can_delete($uid,$app)) {
q("delete from app where app_id = '%s' and app_channel = %d",
dbesc($app['guid']),
intval($uid)
);
q("delete from term where otype = %d and oid = %d",
intval(TERM_OBJ_APP),
intval($x[0]['id'])
);
/**
* @hooks app_destroy
* Called after app entry got removed from database
* and provide app array from database.
*/
call_hooks('app_destroy', $x[0]);
}
else {
q("update app set app_deleted = 1 where app_id = '%s' and app_channel = %d",
dbesc($app['guid']),
intval($uid)
);
}
}
}
@@ -693,13 +729,11 @@ class Apps {
dbesc($app['guid']),
intval($uid)
);
if($x) {
if($x[0]['app_system']) {
q("update app set app_deleted = 0 where app_id = '%s' and app_channel = %d",
dbesc($app['guid']),
intval($uid)
);
}
if($x && intval($x[0]['app_deleted']) && $x[0]['app_system']) {
q("update app set app_deleted = 0 where app_id = '%s' and app_channel = %d",
dbesc($app['guid']),
intval($uid)
);
}
}
}
@@ -1158,9 +1192,9 @@ class Apps {
$y = explode(',',$arr['categories']);
if($y) {
foreach($y as $t) {
$t = trim($t);
$t = escape_tags(trim($t));
if($t) {
store_item_tag($darray['app_channel'],$x[0]['id'],TERM_OBJ_APP,TERM_CATEGORY,escape_tags($t),escape_tags(z_root() . '/apps/?f=&cat=' . escape_tags($t)));
store_item_tag($darray['app_channel'], $x[0]['id'], TERM_OBJ_APP, TERM_CATEGORY, $t, z_root() . '/apps/?f=&cat=' . $t);
}
}
}
@@ -1276,58 +1310,58 @@ class Apps {
$ret['type'] = 'personal';
if($app['app_id'])
if(!empty($app['app_id']))
$ret['guid'] = $app['app_id'];
if($app['app_sig'])
if(!empty($app['app_sig']))
$ret['sig'] = $app['app_sig'];
if($app['app_author'])
if(!empty($app['app_author']))
$ret['author'] = $app['app_author'];
if($app['app_name'])
if(!empty($app['app_name']))
$ret['name'] = $app['app_name'];
if($app['app_desc'])
if(!empty($app['app_desc']))
$ret['desc'] = $app['app_desc'];
if($app['app_url'])
if(!empty($app['app_url']))
$ret['url'] = $app['app_url'];
if($app['app_photo'])
if(!empty($app['app_photo']))
$ret['photo'] = $app['app_photo'];
if($app['app_icon'])
if(!empty($app['app_icon']))
$ret['icon'] = $app['app_icon'];
if($app['app_version'])
if(!empty($app['app_version']))
$ret['version'] = $app['app_version'];
if($app['app_addr'])
if(!empty($app['app_addr']))
$ret['addr'] = $app['app_addr'];
if($app['app_price'])
if(!empty($app['app_price']))
$ret['price'] = $app['app_price'];
if($app['app_page'])
if(!empty($app['app_page']))
$ret['page'] = $app['app_page'];
if($app['app_requires'])
if(!empty($app['app_requires']))
$ret['requires'] = $app['app_requires'];
if($app['app_system'])
if(!empty($app['app_system']))
$ret['system'] = $app['app_system'];
if($app['app_options'])
if(!empty($app['app_options']))
$ret['options'] = $app['app_options'];
if($app['app_plugin'])
if(!empty($app['app_plugin']))
$ret['plugin'] = trim($app['app_plugin']);
if($app['app_deleted'])
if(!empty($app['app_deleted']))
$ret['deleted'] = $app['app_deleted'];
if($app['term']) {
if(!empty($app['term']) && is_array($app['term'])) {
$s = '';
foreach($app['term'] as $t) {
if($s)
@@ -1356,4 +1390,17 @@ class Apps {
return chunk_split(base64_encode(json_encode($papp)),72,"\n");
}
static public function get_papp($app) {
$r = q("select * from app where app_id = '%s' and app_channel = 0 limit 1",
dbesc(hash('whirlpool', $app))
);
if ($r) {
$papp = self::app_encode($r[0]);
return $papp;
}
return false;
}
}

View File

@@ -146,7 +146,7 @@ class Connect {
}
$allowed = ((in_array($xchan['xchan_network'],['rss','zot','zot6'])) ? 1 : 0);
$allowed = ((in_array($xchan['xchan_network'],['rss', 'zot6'])) ? 1 : 0);
$hookdata = ['channel_id' => $uid, 'follow_address' => $url, 'xchan' => $xchan, 'allowed' => $allowed, 'singleton' => 0];
call_hooks('follow_allow',$hookdata);
@@ -207,13 +207,13 @@ class Connect {
}
$my_perms = $p['perms'];
$profile_assign = get_pconfig($uid,'system','profile_assign','');
// See if we are already connected by virtue of having an abook record
$r = q("select abook_id, abook_xchan, abook_pending, abook_instance from abook
$r = q("select abook_id, abook_xchan, abook_pending, abook_instance from abook
where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($xchan_hash),
intval($uid)
@@ -261,7 +261,8 @@ class Connect {
'abook_feed' => intval(($xchan['xchan_network'] === 'rss') ? 1 : 0),
'abook_created' => datetime_convert(),
'abook_updated' => datetime_convert(),
'abook_instance' => (($singleton) ? z_root() : '')
'abook_instance' => (($singleton) ? z_root() : ''),
'abook_role' => get_pconfig($uid, 'system', 'default_permcat', 'default')
]
);
}
@@ -282,7 +283,7 @@ class Connect {
// fetch the entire record
$r = q("select abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash
$r = q("select abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash
where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($xchan_hash),
intval($uid)
@@ -300,7 +301,7 @@ class Connect {
/** If there is a default group for this channel, add this connection to it */
if ($default_group) {
$g = AccessList::rec_byhash($uid,$default_group);
$g = AccessList::by_hash($uid,$default_group);
if ($g) {
AccessList::member_add($uid,'',$xchan_hash,$g['id']);
}

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

@@ -87,8 +87,7 @@ class DReport {
// Is the sender one of our channels?
$c = q("select channel_id from channel where channel_hash = '%s' or channel_portable_id = '%s' limit 1",
dbesc($dr['sender']),
$c = q("select channel_id from channel where channel_hash = '%s' limit 1",
dbesc($dr['sender'])
);

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 {
@@ -64,29 +64,29 @@ class Enotify {
$sitename = get_config('system','sitename');
$site_admin = sprintf( t('%s Administrator'), $sitename);
$opt_out1 = sprintf( t('This email was sent by %1$s at %2$s.'), t('$Projectname'), \App::get_hostname());
$opt_out2 = sprintf( t('To stop receiving these messages, please adjust your Notification Settings at %s'), z_root() . '/settings');
$opt_out2 = sprintf( t('To stop receiving these messages, please adjust your Notification Settings at %s'), z_root() . '/settings');
$hopt_out2 = sprintf( t('To stop receiving these messages, please adjust your %s.'), '<a href="' . z_root() . '/settings' . '">' . t('Notification Settings') . '</a>');
$sender_name = $product;
$hostname = \App::get_hostname();
if(strpos($hostname,':'))
$hostname = substr($hostname,0,strpos($hostname,':'));
$hostname = substr($hostname, 0, strpos($hostname,':'));
// Do not translate 'noreply' as it must be a legal 7-bit email address
$reply_email = get_config('system','reply_address');
$reply_email = get_config('system', 'reply_address');
if(! $reply_email)
$reply_email = 'noreply' . '@' . $hostname;
$sender_email = get_config('system','from_email');
$sender_email = get_config('system', 'from_email');
if(! $sender_email)
$sender_email = 'Administrator' . '@' . $hostname;
$sender_name = get_config('system','from_email_name');
$sender_name = get_config('system', 'from_email_name');
if(! $sender_name)
$sender_name = \Zotlabs\Lib\System::get_site_name();
$additional_mail_header = "";
$additional_mail_header = '';
if(array_key_exists('item', $params)) {
require_once('include/conversation.php');
@@ -108,33 +108,34 @@ class Enotify {
logger('notification invoked for an old item which may have been refetched.',LOGGER_DEBUG,LOG_INFO);
return;
}
}
}
else {
$title = $body = '';
}
$always_show_in_notices = get_pconfig($recip['channel_id'],'system','always_show_in_notices');
$vnotify = get_pconfig($recip['channel_id'],'system','vnotify');
$always_show_in_notices = get_pconfig($recip['channel_id'], 'system', 'always_show_in_notices');
$vnotify = get_pconfig($recip['channel_id'], 'system', 'vnotify');
$salutation = $recip['channel_name'];
// e.g. "your post", "David's photo", etc.
$possess_desc = t('%s <!item_type!>');
// @@TODO: consider using switch instead of those elseif
if ($params['type'] == NOTIFY_MAIL) {
logger('notification: mail');
$subject = sprintf( t('[$Projectname:Notify] New mail received at %s'),$sitename);
$subject = sprintf( t('[$Projectname:Notify] New direct message received at %s'), $sitename);
$preamble = sprintf( t('%1$s sent you a new private message at %2$s.'), $sender['xchan_name'],$sitename);
$epreamble = sprintf( t('%1$s sent you %2$s.'),'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', '[zrl=$itemlink]' . t('a private message') . '[/zrl]');
$sitelink = t('Please visit %s to view and/or reply to your private messages.');
$tsitelink = sprintf( $sitelink, $siteurl . '/mail/' . $params['item']['id'] );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '/mail/' . $params['item']['id'] . '">' . $sitename . '</a>');
$itemlink = $siteurl . '/mail/' . $params['item']['id'];
$preamble = sprintf( t('%1$s sent you a new direct message at %2$s'), $sender['xchan_name'], $sitename);
$epreamble = sprintf( t('%1$s sent you %2$s.'), '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', '[zrl=$itemlink]' . t('a direct message') . '[/zrl]');
$sitelink = t('Please visit %s to view and/or reply to your direct messages.');
$tsitelink = sprintf( $sitelink, $siteurl . '/hq/' . gen_link_id($params['item']['mid']));
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '/hq/' . gen_link_id($params['item']['mid']) . '">' . $sitename . '</a>');
$itemlink = $siteurl . '/hq/' . gen_link_id($params['item']['mid']);
}
if ($params['type'] == NOTIFY_COMMENT) {
elseif ($params['type'] === NOTIFY_COMMENT) {
//logger("notification: params = " . print_r($params, true), LOGGER_DEBUG);
$moderated = (($params['item']['item_blocked'] == ITEM_MODERATED) ? true : false);
@@ -171,7 +172,6 @@ class Enotify {
// Check to see if there was already a notify for this post.
// If so don't create a second notification
$p = null;
$p = q("select id from notify where link = '%s' and uid = %d limit 1",
dbesc($params['link']),
intval($recip['channel_id'])
@@ -181,7 +181,7 @@ class Enotify {
pop_lang();
return;
}
// if it's a post figure out who's post it is.
@@ -196,6 +196,7 @@ class Enotify {
xchan_query($p);
//@@FIXME $p can be null (line 188)
$item_post_type = item_post_type($p[0]);
// $private = $p[0]['item_private'];
$parent_id = $p[0]['id'];
@@ -219,7 +220,7 @@ class Enotify {
$itemlink,
$p[0]['author']['xchan_name'],
$item_post_type);
// "your post"
if($p[0]['owner']['xchan_name'] == $p[0]['author']['xchan_name'] && intval($p[0]['item_wall']))
$dest_str = sprintf(t('%1$s %2$s [zrl=%3$s]your %4$s[/zrl]'),
@@ -230,15 +231,15 @@ class Enotify {
// Some mail softwares relies on subject field for threading.
// So, we cannot have different subjects for notifications of the same thread.
// Before this we have the name of the replier on the subject rendering
// Before this we have the name of the replier on the subject rendering
// differents subjects for messages on the same thread.
if($moderated)
$subject = sprintf( t('[$Projectname:Notify] Moderated Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
else
$subject = sprintf( t('[$Projectname:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
$preamble = sprintf( t('%1$s commented on an item/conversation you have been following.'), $sender['xchan_name']);
$epreamble = $dest_str;
$preamble = sprintf( t('%1$s commented on an item/conversation you have been following'), $sender['xchan_name']);
$epreamble = $dest_str;
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
$tsitelink = sprintf( $sitelink, $siteurl );
@@ -247,15 +248,15 @@ class Enotify {
$tsitelink .= "\n\n" . sprintf( t('Please visit %s to approve or reject this comment.'), z_root() . '/moderate' );
$hsitelink .= "<br><br>" . sprintf( t('Please visit %s to approve or reject this comment.'), '<a href="' . z_root() . '/moderate">' . z_root() . '/moderate</a>' );
}
}
if ($params['type'] == NOTIFY_LIKE) {
elseif ($params['type'] === NOTIFY_LIKE) {
// logger("notification: params = " . print_r($params, true), LOGGER_DEBUG);
$itemlink = $params['link'];
if (array_key_exists('item',$params) && (! activity_match($params['item']['verb'],ACTIVITY_LIKE))) {
if (array_key_exists('item',$params) && activity_match($params['item']['verb'],ACTIVITY_LIKE)) {
if(! $always_show_in_notices || !($vnotify & VNOTIFY_LIKE)) {
logger('notification: not a visible activity. Ignoring.');
pop_lang();
@@ -268,7 +269,6 @@ class Enotify {
// Check to see if there was already a notify for this post.
// If so don't create a second notification
$p = null;
$p = q("select id from notify where link = '%s' and uid = %d limit 1",
dbesc($params['link']),
intval($recip['channel_id'])
@@ -278,7 +278,7 @@ class Enotify {
pop_lang();
return;
}
// if it's a post figure out who's post it is.
@@ -293,7 +293,7 @@ class Enotify {
xchan_query($p);
//@@FIXME $p can be null (line 285)
$item_post_type = item_post_type($p[0]);
// $private = $p[0]['item_private'];
$parent_id = $p[0]['id'];
@@ -302,7 +302,7 @@ class Enotify {
// "your post"
if($p[0]['owner']['xchan_name'] == $p[0]['author']['xchan_name'] && intval($p[0]['item_wall']))
if($p[0]['owner']['xchan_name'] === $p[0]['author']['xchan_name'] && intval($p[0]['item_wall']))
$dest_str = sprintf(t('%1$s liked [zrl=%2$s]your %3$s[/zrl]'),
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
$itemlink,
@@ -314,12 +314,12 @@ class Enotify {
// Some mail softwares relies on subject field for threading.
// So, we cannot have different subjects for notifications of the same thread.
// Before this we have the name of the replier on the subject rendering
// Before this we have the name of the replier on the subject rendering
// differents subjects for messages on the same thread.
$subject = sprintf( t('[$Projectname:Notify] Like received to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
$preamble = sprintf( t('%1$s liked an item/conversation you created.'), $sender['xchan_name']);
$epreamble = $dest_str;
$preamble = sprintf( t('%1$s liked an item/conversation you created'), $sender['xchan_name']);
$epreamble = $dest_str;
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
$tsitelink = sprintf( $sitelink, $siteurl );
@@ -328,14 +328,14 @@ class Enotify {
if($params['type'] == NOTIFY_WALL) {
elseif($params['type'] === NOTIFY_WALL) {
$subject = sprintf( t('[$Projectname:Notify] %s posted to your profile wall') , $sender['xchan_name']);
$preamble = sprintf( t('%1$s posted to your profile wall at %2$s') , $sender['xchan_name'], $sitename);
$epreamble = sprintf( t('%1$s posted to [zrl=%2$s]your wall[/zrl]') ,
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
$params['link']);
$params['link']);
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
$tsitelink = sprintf( $sitelink, $siteurl );
@@ -343,9 +343,8 @@ class Enotify {
$itemlink = $params['link'];
}
if ($params['type'] == NOTIFY_TAGSELF) {
elseif ($params['type'] === NOTIFY_TAGSELF) {
$p = null;
$p = q("select id from notify where link = '%s' and uid = %d limit 1",
dbesc($params['link']),
intval($recip['channel_id'])
@@ -355,12 +354,12 @@ class Enotify {
pop_lang();
return;
}
$subject = sprintf( t('[$Projectname:Notify] %s tagged you') , $sender['xchan_name']);
$preamble = sprintf( t('%1$s tagged you at %2$s') , $sender['xchan_name'], $sitename);
$epreamble = sprintf( t('%1$s [zrl=%2$s]tagged you[/zrl].') ,
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
$params['link']);
$params['link']);
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
$tsitelink = sprintf( $sitelink, $siteurl );
@@ -368,12 +367,12 @@ class Enotify {
$itemlink = $params['link'];
}
if ($params['type'] == NOTIFY_POKE) {
elseif ($params['type'] === NOTIFY_POKE) {
$subject = sprintf( t('[$Projectname:Notify] %1$s poked you') , $sender['xchan_name']);
$preamble = sprintf( t('%1$s poked you at %2$s') , $sender['xchan_name'], $sitename);
$epreamble = sprintf( t('%1$s [zrl=%2$s]poked you[/zrl].') ,
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
$params['link']);
$params['link']);
$subject = str_replace('poked', t($params['activity']), $subject);
$preamble = str_replace('poked', t($params['activity']), $preamble);
@@ -385,12 +384,12 @@ class Enotify {
$itemlink = $params['link'];
}
if ($params['type'] == NOTIFY_TAGSHARE) {
elseif ($params['type'] === NOTIFY_TAGSHARE) {
$subject = sprintf( t('[$Projectname:Notify] %s tagged your post') , $sender['xchan_name']);
$preamble = sprintf( t('%1$s tagged your post at %2$s'),$sender['xchan_name'], $sitename);
$epreamble = sprintf( t('%1$s tagged [zrl=%2$s]your post[/zrl]') ,
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
$itemlink);
$itemlink);
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
$tsitelink = sprintf( $sitelink, $siteurl );
@@ -398,12 +397,12 @@ class Enotify {
$itemlink = $params['link'];
}
if ($params['type'] == NOTIFY_INTRO) {
elseif ($params['type'] === NOTIFY_INTRO) {
$subject = sprintf( t('[$Projectname:Notify] Introduction received'));
$preamble = sprintf( t('You\'ve received an new connection request from \'%1$s\' at %2$s'), $sender['xchan_name'], $sitename);
$preamble = sprintf( t('You\'ve received an new connection request from \'%1$s\' at %2$s'), $sender['xchan_name'], $sitename);
$epreamble = sprintf( t('You\'ve received [zrl=%1$s]a new connection request[/zrl] from %2$s.'),
$siteurl . '/connections/ifpending',
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]');
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]');
$body = sprintf( t('You may visit their profile at %s'),$sender['xchan_url']);
$sitelink = t('Please visit %s to approve or reject the connection request.');
@@ -412,13 +411,13 @@ class Enotify {
$itemlink = $params['link'];
}
if ($params['type'] == NOTIFY_SUGGEST) {
elseif ($params['type'] === NOTIFY_SUGGEST) {
$subject = sprintf( t('[$Projectname:Notify] Friend suggestion received'));
$preamble = sprintf( t('You\'ve received a friend suggestion from \'%1$s\' at %2$s'), $sender['xchan_name'], $sitename);
$preamble = sprintf( t('You\'ve received a friend suggestion from \'%1$s\' at %2$s'), $sender['xchan_name'], $sitename);
$epreamble = sprintf( t('You\'ve received [zrl=%1$s]a friend suggestion[/zrl] for %2$s from %3$s.'),
$itemlink,
'[zrl=' . $params['item']['url'] . ']' . $params['item']['name'] . '[/zrl]',
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]');
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]');
$body = t('Name:') . ' ' . $params['item']['name'] . "\n";
$body .= t('Photo:') . ' ' . $params['item']['photo'] . "\n";
@@ -430,11 +429,11 @@ class Enotify {
$itemlink = $params['link'];
}
if ($params['type'] == NOTIFY_CONFIRM) {
elseif ($params['type'] === NOTIFY_CONFIRM) {
// ?
}
if ($params['type'] == NOTIFY_SYSTEM) {
elseif ($params['type'] === NOTIFY_SYSTEM) {
// ?
}
@@ -462,7 +461,7 @@ class Enotify {
$sitelink = $h['sitelink'];
$tsitelink = $h['tsitelink'];
$hsitelink = $h['hsitelink'];
$itemlink = $h['itemlink'];
$itemlink = $h['itemlink'];
require_once('include/html2bbcode.php');
@@ -477,7 +476,7 @@ class Enotify {
} while ($dups === true);
$datarray = array();
$datarray = [];
$datarray['hash'] = $hash;
$datarray['sender_hash'] = $sender['xchan_hash'];
$datarray['xname'] = $sender['xchan_name'];
@@ -510,11 +509,11 @@ class Enotify {
// Mark some notifications as seen right away
// Note! The notification have to be created, because they are used to send emails
// So easiest solution to hide them from Notices is to mark them as seen right away.
// Another option would be to not add them to the DB, and change how emails are handled
// Another option would be to not add them to the DB, and change how emails are handled
// (probably would be better that way)
if (!$always_show_in_notices) {
if (($params['type'] == NOTIFY_WALL) || ($params['type'] == NOTIFY_MAIL) || ($params['type'] == NOTIFY_INTRO)) {
if (($params['type'] === NOTIFY_WALL) || ($params['type'] === NOTIFY_MAIL) || ($params['type'] === NOTIFY_INTRO)) {
$seen = 1;
}
}
@@ -550,12 +549,12 @@ class Enotify {
}
$itemlink = z_root() . '/notify/view/' . $notify_id;
$msg = str_replace('$itemlink',$itemlink,$epreamble);
$msg = str_replace('$itemlink', $itemlink, $epreamble);
// wretched hack, but we don't want to duplicate all the preamble variations and we also don't want to screw up a translation
if ((\App::$language === 'en' || (! \App::$language)) && strpos($msg,', '))
$msg = substr($msg,strpos($msg,', ')+1);
$msg = substr($msg, strpos($msg,', ')+1);
$datarray['id'] = $notify_id;
$datarray['msg'] = $msg;
@@ -575,7 +574,7 @@ class Enotify {
logger('notification: sending notification email');
$hn = get_pconfig($recip['channel_id'],'system','email_notify_host');
$hn = get_pconfig($recip['channel_id'], 'system', 'email_notify_host');
if($hn && (! stristr(\App::get_hostname(),$hn))) {
// this isn't the email notification host
pop_lang();
@@ -584,15 +583,15 @@ class Enotify {
$textversion = strip_tags(html_entity_decode(bbcode(stripslashes(str_replace(array("\\r", "\\n"), array( "", "\n"), $body))),ENT_QUOTES,'UTF-8'));
$htmlversion = bbcode(stripslashes(str_replace(array("\\r","\\n"), array("","<br />\n"),$body)));
$htmlversion = bbcode(stripslashes(str_replace(array("\\r","\\n"), array('',"<br />\n"),$body)));
// use $_SESSION['zid_override'] to force zid() to use
// use $_SESSION['zid_override'] to force zid() to use
// the recipient address instead of the current observer
$_SESSION['zid_override'] = channel_reddress($recip);
$_SESSION['zrl_override'] = z_root() . '/channel/' . $recip['channel_address'];
$textversion = zidify_links($textversion);
$htmlversion = zidify_links($htmlversion);
@@ -601,7 +600,7 @@ class Enotify {
unset($_SESSION['zid_override']);
unset($_SESSION['zrl_override']);
$datarray = array();
$datarray = [];
$datarray['banner'] = $banner;
$datarray['product'] = $product;
$datarray['preamble'] = $preamble;
@@ -754,21 +753,21 @@ class Enotify {
return $params['result'];
}
$fromName = email_header_encode(html_entity_decode($params['fromName'],ENT_QUOTES,'UTF-8'),'UTF-8');
$fromName = email_header_encode(html_entity_decode($params['fromName'],ENT_QUOTES,'UTF-8'),'UTF-8');
$messageSubject = email_header_encode(html_entity_decode($params['messageSubject'],ENT_QUOTES,'UTF-8'),'UTF-8');
// generate a mime boundary
$mimeBoundary = rand(0, 9) . "-"
.rand(100000000, 999999999) . "-"
.rand(100000000, 999999999) . "=:"
$mimeBoundary = rand(0, 9) . '-'
.rand(100000000, 999999999) . '-'
.rand(100000000, 999999999) . '=:'
.rand(10000, 99999);
// generate a multipart/alternative message header
$messageHeader =
$params['additionalMailHeader'] .
"From: $fromName <{$params['fromEmail']}>" . PHP_EOL .
"Reply-To: $fromName <{$params['replyTo']}>" . PHP_EOL .
"MIME-Version: 1.0" . PHP_EOL .
"Reply-To: $fromName <{$params['replyTo']}>" . PHP_EOL .
'MIME-Version: 1.0' . PHP_EOL .
"Content-Type: multipart/alternative; boundary=\"{$mimeBoundary}\"";
// assemble the final multipart message body with the text and html types included
@@ -776,15 +775,15 @@ class Enotify {
$htmlBody = chunk_split(base64_encode($params['htmlVersion']));
$multipartMessageBody =
"--" . $mimeBoundary . PHP_EOL . // plain text section
"Content-Type: text/plain; charset=UTF-8" . PHP_EOL .
"Content-Transfer-Encoding: base64" . PHP_EOL . PHP_EOL .
'--' . $mimeBoundary . PHP_EOL . // plain text section
'Content-Type: text/plain; charset=UTF-8' . PHP_EOL .
'Content-Transfer-Encoding: base64' . PHP_EOL . PHP_EOL .
$textBody . PHP_EOL .
"--" . $mimeBoundary . PHP_EOL . // text/html section
"Content-Type: text/html; charset=UTF-8" . PHP_EOL .
"Content-Transfer-Encoding: base64" . PHP_EOL . PHP_EOL .
'--' . $mimeBoundary . PHP_EOL . // text/html section
'Content-Type: text/html; charset=UTF-8' . PHP_EOL .
'Content-Transfer-Encoding: base64' . PHP_EOL . PHP_EOL .
$htmlBody . PHP_EOL .
"--" . $mimeBoundary . "--" . PHP_EOL; // message ending
'--' . $mimeBoundary . '--' . PHP_EOL; // message ending
// send the message
$res = mail(
@@ -793,7 +792,7 @@ class Enotify {
$multipartMessageBody, // message body
$messageHeader // message headers
);
logger("notification: enotify::send returns " . (($res) ? 'success' : 'failure'), LOGGER_DEBUG);
logger('notification: enotify::send returns ' . (($res) ? 'success' : 'failure'), LOGGER_DEBUG);
return $res;
}
@@ -803,7 +802,7 @@ class Enotify {
require_once('include/conversation.php');
// Call localize_item to get a one line status for activities.
// Call localize_item to get a one line status for activities.
// This should set $item['localized'] to indicate we have a brief summary.
// and perhaps $item['shortlocalized'] for an even briefer summary
@@ -833,13 +832,12 @@ class Enotify {
$edit = false;
if($item['edited'] > $item['created']) {
$edit = true;
if($item['item_thread_top']) {
$itemem_text = sprintf( t('edited a post dated %s'), relative_date($item['created']));
$edit = true;
}
else {
$itemem_text = sprintf( t('edited a comment dated %s'), relative_date($item['created']));
$edit = true;
}
}
@@ -856,18 +854,18 @@ class Enotify {
'photo' => $item[$who]['xchan_photo_s'],
'when' => (($edit) ? datetime_convert('UTC', date_default_timezone_get(), $item['edited']) : datetime_convert('UTC', date_default_timezone_get(), $item['created'])),
'class' => (intval($item['item_unseen']) ? 'notify-unseen' : 'notify-seen'),
'b64mid' => (($item['mid']) ? 'b64.' . base64url_encode($item['mid']) : ''),
//'b64mid' => ((in_array($item['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) ? 'b64.' . base64url_encode($item['thr_parent']) : 'b64.' . base64url_encode($item['mid'])),
'b64mid' => (($item['mid']) ? gen_link_id($item['mid']) : ''),
//'b64mid' => ((in_array($item['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) ? gen_link_id($item['thr_parent']) : gen_link_id($item['mid'])),
'thread_top' => (($item['item_thread_top']) ? true : false),
'message' => bbcode(escape_tags($itemem_text)),
'body' => htmlentities(html2plain(bbcode($item['body']), 75, true), ENT_COMPAT, 'UTF-8', false),
'body' => htmlentities(html2plain(bbcode($item['body'], ['drop_media', true]), 75, true), ENT_QUOTES, 'UTF-8', false),
// these are for the superblock addon
'hash' => $item[$who]['xchan_hash'],
'uid' => $item['uid'],
'display' => true
);
call_hooks('enotify_format',$x);
call_hooks('enotify_format', $x);
if(! $x['display']) {
return [];
}
@@ -884,9 +882,9 @@ class Enotify {
$mid = basename($tt['link']);
$b64mid = ((strpos($mid, 'b64.') === 0) ? $mid : 'b64.' . base64url_encode($mid));
$b64mid = gen_link_id($mid);
$x = [
'notify_link' => z_root() . '/notify/view/' . $tt['id'],
'notify_link' => (($tt['ntype'] === NOTIFY_MAIL) ? $tt['link'] : z_root() . '/notify/view/' . $tt['id']),
'name' => $tt['xname'],
'url' => $tt['url'],
'photo' => $tt['photo'],
@@ -903,8 +901,8 @@ class Enotify {
static public function format_intros($rr) {
$x = [
'notify_link' => z_root() . '/connections/ifpending',
return [
'notify_link' => z_root() . '/connections#' . $rr['abook_id'],
'name' => $rr['xchan_name'],
'addr' => $rr['xchan_addr'],
'url' => $rr['xchan_url'],
@@ -914,13 +912,11 @@ class Enotify {
'message' => t('added your channel')
];
return $x;
}
static public function format_files($rr) {
$x = [
return [
'notify_link' => z_root() . '/sharedwithme',
'name' => $rr['author']['xchan_name'],
'addr' => $rr['author']['xchan_addr'],
@@ -931,13 +927,11 @@ class Enotify {
'message' => t('shared a file with you')
];
return $x;
}
static public function format_mail($rr) {
$x = [
return [
'notify_link' => z_root() . '/mail/' . $rr['id'],
'name' => $rr['xchan_name'],
'addr' => $rr['xchan_addr'],
@@ -945,11 +939,9 @@ class Enotify {
'photo' => $rr['xchan_photo_s'],
'when' => datetime_convert('UTC', date_default_timezone_get(), $rr['created']),
'hclass' => (intval($rr['mail_seen']) ? 'notify-seen' : 'notify-unseen'),
'message' => t('sent you a private message'),
'message' => t('sent you a direct message'),
];
return $x;
}
static public function format_all_events($rr) {
@@ -959,7 +951,7 @@ class Enotify {
$today = ((substr($strt, 0, 10) === datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y-m-d')) ? true : false);
$when = day_translate(datetime_convert('UTC', (($rr['adjust']) ? date_default_timezone_get() : 'UTC'), $rr['dtstart'], $bd_format)) . (($today) ? ' ' . t('[today]') : '');
$x = [
return [
'notify_link' => z_root() . '/cdav/calendar/' . $rr['event_hash'],
'name' => $rr['xchan_name'],
'addr' => $rr['xchan_addr'],
@@ -970,23 +962,20 @@ class Enotify {
'message' => t('created an event')
];
return $x;
}
static public function format_register($rr) {
$x = [
return [
'notify_link' => z_root() . '/admin/accounts',
'name' => $rr['account_email'],
//'addr' => $rr['account_email'],
'name' => $rr['reg_did2'],
//'addr' => '',
'photo' => z_root() . '/' . get_default_profile_photo(48),
'when' => datetime_convert('UTC', date_default_timezone_get(),$rr['account_created']),
'when' => datetime_convert('UTC', date_default_timezone_get(),$rr['reg_created']),
'hclass' => ('notify-unseen'),
'message' => t('requires approval')
'message' => t('status verified')
];
return $x;
}
}

View File

@@ -1,405 +0,0 @@
<?php
namespace Zotlabs\Lib;
use Zotlabs\Lib\Libsync;
class Group {
static function add($uid,$name,$public = 0) {
$ret = false;
if(x($uid) && x($name)) {
$r = self::byname($uid,$name); // check for dups
if($r !== false) {
// This could be a problem.
// Let's assume we've just created a group which we once deleted
// all the old members are gone, but the group remains so we don't break any security
// access lists. What we're doing here is reviving the dead group, but old content which
// was restricted to this group may now be seen by the new group members.
$z = q("SELECT * FROM pgrp WHERE id = %d LIMIT 1",
intval($r)
);
if(($z) && $z[0]['deleted']) {
q('UPDATE pgrp SET deleted = 0 WHERE id = %d', intval($z[0]['id']));
notice( t('A deleted group with this name was revived. Existing item permissions <strong>may</strong> apply to this group and any future members. If this is not what you intended, please create another group with a different name.') . EOL);
}
return true;
}
do {
$dups = false;
$hash = random_string(32) . str_replace(['<','>'],['.','.'], $name);
$r = q("SELECT id FROM pgrp WHERE hash = '%s' LIMIT 1", dbesc($hash));
if($r)
$dups = true;
} while($dups == true);
$r = q("INSERT INTO pgrp ( hash, uid, visible, gname )
VALUES( '%s', %d, %d, '%s' ) ",
dbesc($hash),
intval($uid),
intval($public),
dbesc($name)
);
$ret = $r;
}
Libsync::build_sync_packet($uid,null,true);
return $ret;
}
static function remove($uid,$name) {
$ret = false;
if(x($uid) && x($name)) {
$r = q("SELECT id, hash FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1",
intval($uid),
dbesc($name)
);
if($r) {
$group_id = $r[0]['id'];
$group_hash = $r[0]['hash'];
}
if(! $group_id)
return false;
// remove group from default posting lists
$r = q("SELECT channel_default_group, channel_allow_gid, channel_deny_gid FROM channel WHERE channel_id = %d LIMIT 1",
intval($uid)
);
if($r) {
$user_info = $r[0];
$change = false;
if($user_info['channel_default_group'] == $group_hash) {
$user_info['channel_default_group'] = '';
$change = true;
}
if(strpos($user_info['channel_allow_gid'], '<' . $group_hash . '>') !== false) {
$user_info['channel_allow_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_allow_gid']);
$change = true;
}
if(strpos($user_info['channel_deny_gid'], '<' . $group_hash . '>') !== false) {
$user_info['channel_deny_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_deny_gid']);
$change = true;
}
if($change) {
q("UPDATE channel SET channel_default_group = '%s', channel_allow_gid = '%s', channel_deny_gid = '%s'
WHERE channel_id = %d",
intval($user_info['channel_default_group']),
dbesc($user_info['channel_allow_gid']),
dbesc($user_info['channel_deny_gid']),
intval($uid)
);
}
}
// remove all members
$r = q("DELETE FROM pgrp_member WHERE uid = %d AND gid = %d ",
intval($uid),
intval($group_id)
);
// remove group
$r = q("UPDATE pgrp SET deleted = 1 WHERE uid = %d AND gname = '%s'",
intval($uid),
dbesc($name)
);
$ret = $r;
}
Libsync::build_sync_packet($uid,null,true);
return $ret;
}
static function byname($uid,$name) {
if((! $uid) || (! strlen($name)))
return false;
$r = q("SELECT * FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1",
intval($uid),
dbesc($name)
);
if($r)
return $r[0]['id'];
return false;
}
static function rec_byhash($uid,$hash) {
if((! $uid) || (! strlen($hash)))
return false;
$r = q("SELECT * FROM pgrp WHERE uid = %d AND hash = '%s' LIMIT 1",
intval($uid),
dbesc($hash)
);
if($r)
return $r[0];
return false;
}
static function member_remove($uid,$name,$member) {
$gid = self::byname($uid,$name);
if(! $gid)
return false;
if(! ( $uid && $gid && $member))
return false;
$r = q("DELETE FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' ",
intval($uid),
intval($gid),
dbesc($member)
);
Libsync::build_sync_packet($uid,null,true);
return $r;
}
static function member_add($uid,$name,$member,$gid = 0) {
if(! $gid)
$gid = self::byname($uid,$name);
if((! $gid) || (! $uid) || (! $member))
return false;
$r = q("SELECT * FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' LIMIT 1",
intval($uid),
intval($gid),
dbesc($member)
);
if($r)
return true; // You might question this, but
// we indicate success because the group member was in fact created
// -- It was just created at another time
if(! $r)
$r = q("INSERT INTO pgrp_member (uid, gid, xchan)
VALUES( %d, %d, '%s' ) ",
intval($uid),
intval($gid),
dbesc($member)
);
Libsync::build_sync_packet($uid,null,true);
return $r;
}
static function members($gid) {
$ret = array();
if(intval($gid)) {
$r = q("SELECT * FROM pgrp_member
LEFT JOIN abook ON abook_xchan = pgrp_member.xchan left join xchan on xchan_hash = abook_xchan
WHERE gid = %d AND abook_channel = %d and pgrp_member.uid = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 ORDER BY xchan_name ASC ",
intval($gid),
intval(local_channel()),
intval(local_channel())
);
if($r)
$ret = $r;
}
return $ret;
}
static function members_xchan($gid) {
$ret = [];
if(intval($gid)) {
$r = q("SELECT xchan FROM pgrp_member WHERE gid = %d AND uid = %d",
intval($gid),
intval(local_channel())
);
if($r) {
foreach($r as $rr) {
$ret[] = $rr['xchan'];
}
}
}
return $ret;
}
static function members_profile_xchan($uid,$gid) {
$ret = [];
if(intval($gid)) {
$r = q("SELECT abook_xchan as xchan from abook left join profile on abook_profile = profile_guid where profile.id = %d and profile.uid = %d",
intval($gid),
intval($uid)
);
if($r) {
foreach($r as $rr) {
$ret[] = $rr['xchan'];
}
}
}
return $ret;
}
static function select($uid,$group = '') {
$grps = [];
$o = '';
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
intval($uid)
);
$grps[] = array('name' => '', 'hash' => '0', 'selected' => '');
if($r) {
foreach($r as $rr) {
$grps[] = array('name' => $rr['gname'], 'id' => $rr['hash'], 'selected' => (($group == $rr['hash']) ? 'true' : ''));
}
}
logger('select: ' . print_r($grps,true), LOGGER_DATA);
$o = replace_macros(get_markup_template('group_selection.tpl'), array(
'$label' => t('Add new connections to this privacy group'),
'$groups' => $grps
));
return $o;
}
static function widget($every="connections",$each="group",$edit = false, $group_id = 0, $cid = '',$mode = 1) {
$o = '';
if(! (local_channel() && feature_enabled(local_channel(),'groups'))) {
return '';
}
$groups = array();
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
intval($_SESSION['uid'])
);
$member_of = array();
if($cid) {
$member_of = self::containing(local_channel(),$cid);
}
if($r) {
foreach($r as $rr) {
$selected = (($group_id == $rr['id']) ? ' group-selected' : '');
if ($edit) {
$groupedit = [ 'href' => "group/".$rr['id'], 'title' => t('edit') ];
}
else {
$groupedit = null;
}
$groups[] = [
'id' => $rr['id'],
'enc_cid' => base64url_encode($cid),
'cid' => $cid,
'text' => $rr['gname'],
'selected' => $selected,
'href' => (($mode == 0) ? $each.'?f=&gid='.$rr['id'] : $each."/".$rr['id']) . ((x($_GET,'new')) ? '&new=' . $_GET['new'] : '') . ((x($_GET,'order')) ? '&order=' . $_GET['order'] : ''),
'edit' => $groupedit,
'ismember' => in_array($rr['id'],$member_of),
];
}
}
$tpl = get_markup_template("group_side.tpl");
$o = replace_macros($tpl, array(
'$title' => t('Privacy Groups'),
'$edittext' => t('Edit group'),
'$createtext' => t('Add privacy group'),
'$ungrouped' => (($every === 'contacts') ? t('Channels not in any privacy group') : ''),
'$groups' => $groups,
'$add' => t('add'),
));
return $o;
}
static function expand($g) {
if(! (is_array($g) && count($g)))
return array();
$ret = [];
$x = [];
// private profile linked virtual groups
foreach($g as $gv) {
if(substr($gv,0,3) === 'vp.') {
$profile_hash = substr($gv,3);
if($profile_hash) {
$r = q("select abook_xchan from abook where abook_profile = '%s'",
dbesc($profile_hash)
);
if($r) {
foreach($r as $rv) {
$ret[] = $rv['abook_xchan'];
}
}
}
}
else {
$x[] = $gv;
}
}
if($x) {
stringify_array_elms($x,true);
$groups = implode(',', $x);
if($groups) {
$r = q("SELECT xchan FROM pgrp_member WHERE gid IN ( select id from pgrp where hash in ( $groups ))");
if($r) {
foreach($r as $rr) {
$ret[] = $rr['xchan'];
}
}
}
}
return $ret;
}
static function member_of($c) {
$r = q("SELECT pgrp.gname, pgrp.id FROM pgrp LEFT JOIN pgrp_member ON pgrp_member.gid = pgrp.id WHERE pgrp_member.xchan = '%s' AND pgrp.deleted = 0 ORDER BY pgrp.gname ASC ",
dbesc($c)
);
return $r;
}
static function containing($uid,$c) {
$r = q("SELECT gid FROM pgrp_member WHERE uid = %d AND pgrp_member.xchan = '%s' ",
intval($uid),
dbesc($c)
);
$ret = array();
if($r) {
foreach($r as $rr)
$ret[] = $rr['gid'];
}
return $ret;
}
}

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,
@@ -40,21 +40,21 @@ class JSalmon {
$ret = [ 'results' => [] ];
if(! is_array($x)) {
return $false;
return false;
}
if(! ( array_key_exists('signed',$x) && $x['signed'])) {
return $false;
return false;
}
$signed_data = preg_replace('/\s+/','',$x['data']) . '.'
. base64url_encode($x['data_type'],true) . '.'
. base64url_encode($x['encoding'],true) . '.'
$signed_data = preg_replace('/\s+/','',$x['data']) . '.'
. base64url_encode($x['data_type'],true) . '.'
. base64url_encode($x['encoding'],true) . '.'
. base64url_encode($x['alg'],true);
$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

@@ -19,7 +19,6 @@ class Libzotdir {
*/
static function find_upstream_directory($dirmode) {
global $DIRECTORY_FALLBACK_SERVERS;
$preferred = get_config('system','directory_server');
@@ -31,7 +30,7 @@ class Libzotdir {
);
if(($r) && ($r[0]['site_flags'] & DIRECTORY_MODE_STANDALONE)) {
$preferred = '';
}
}
}
@@ -42,19 +41,21 @@ class Libzotdir {
* from our list of directory servers. However, if we're a directory
* server ourself, point at the local instance
* We will then set this value so this should only ever happen once.
* Ideally there will be an admin setting to change to a different
* Ideally there will be an admin setting to change to a different
* directory server if you don't like our choice or if circumstances change.
*/
$directory_fallback_servers = get_directory_fallback_servers();
$dirmode = intval(get_config('system','directory_mode'));
if ($dirmode == DIRECTORY_MODE_NORMAL) {
$toss = mt_rand(0,count($DIRECTORY_FALLBACK_SERVERS));
$preferred = $DIRECTORY_FALLBACK_SERVERS[$toss];
$toss = mt_rand(0,count($directory_fallback_servers));
$preferred = $directory_fallback_servers[$toss];
if(! $preferred) {
$preferred = DIRECTORY_FALLBACK_MASTER;
}
set_config('system','directory_server',$preferred);
}
}
else {
set_config('system','directory_server',z_root());
}
@@ -108,7 +109,7 @@ class Libzotdir {
$ret = get_config('directory', $setting);
// 'safemode' is the default if there is no observer or no established preference.
// 'safemode' is the default if there is no observer or no established preference.
if($setting === 'safemode' && $ret === false)
$ret = 1;
@@ -175,8 +176,8 @@ class Libzotdir {
*
* Checks the directory mode of this hub to see if it is some form of directory server. If it is,
* get the directory realm of this hub. Fetch a list of all other directory servers in this realm and request
* a directory sync packet. This will contain both directory updates and new ratings. Store these all in the DB.
* In the case of updates, we will query each of them asynchronously from a poller task. Ratings are stored
* a directory sync packet. This will contain both directory updates and new ratings. Store these all in the DB.
* In the case of updates, we will query each of them asynchronously from a poller task. Ratings are stored
* directly if the rater's signature matches.
*
* @param int $dirmode;
@@ -188,16 +189,17 @@ class Libzotdir {
return;
$realm = get_directory_realm();
if ($realm == DIRECTORY_REALM) {
$r = q("select * from site where (site_flags & %d) > 0 and site_url != '%s' and site_type = %d and ( site_realm = '%s' or site_realm = '') ",
$r = q("select * from site where (site_flags & %d) > 0 and site_url != '%s' and site_type = %d and ( site_realm = '%s' or site_realm = '') and site_dead = 0",
intval(DIRECTORY_MODE_PRIMARY|DIRECTORY_MODE_SECONDARY),
dbesc(z_root()),
intval(SITE_TYPE_ZOT),
dbesc($realm)
);
}
}
else {
$r = q("select * from site where (site_flags & %d) > 0 and site_url != '%s' and site_realm like '%s' and site_type = %d ",
$r = q("select * from site where (site_flags & %d) > 0 and site_url != '%s' and site_realm like '%s' and site_type = %d and site_dead = 0",
intval(DIRECTORY_MODE_PRIMARY|DIRECTORY_MODE_SECONDARY),
dbesc(z_root()),
dbesc(protect_sprintf('%' . $realm . '%')),
@@ -214,14 +216,14 @@ class Libzotdir {
[
'site_url' => DIRECTORY_FALLBACK_MASTER,
'site_flags' => DIRECTORY_MODE_PRIMARY,
'site_update' => NULL_DATE,
'site_update' => NULL_DATE,
'site_directory' => DIRECTORY_FALLBACK_MASTER . '/dirsearch',
'site_realm' => DIRECTORY_REALM,
'site_valid' => 1,
]
);
$r = q("select * from site where site_flags in (%d, %d) and site_url != '%s' and site_type = %d ",
$r = q("select * from site where site_flags in (%d, %d) and site_url != '%s' and site_type = %d and site_dead = 0",
intval(DIRECTORY_MODE_PRIMARY),
intval(DIRECTORY_MODE_SECONDARY),
dbesc(z_root()),
@@ -250,7 +252,7 @@ class Libzotdir {
continue;
$j = json_decode($x['body'],true);
if (!($j['transactions']) || ($j['ratings']))
if (!$j['transactions'])
continue;
q("update site set site_sync = '%s' where site_url = '%s'",
@@ -262,6 +264,11 @@ class Libzotdir {
if (is_array($j['transactions']) && count($j['transactions'])) {
foreach ($j['transactions'] as $t) {
if (empty($t['hash']) || empty($t['transaction_id']) || empty($t['address'])) {
continue;
}
$r = q("select * from updates where ud_guid = '%s' limit 1",
dbesc($t['transaction_id'])
);
@@ -273,7 +280,7 @@ class Libzotdir {
$ud_flags |= UPDATE_FLAGS_DELETED;
if (is_array($t['flags']) && in_array('forced',$t['flags']))
$ud_flags |= UPDATE_FLAGS_FORCED;
$z = q("insert into updates ( ud_hash, ud_guid, ud_date, ud_flags, ud_addr )
values ( '%s', '%s', '%s', %d, '%s' ) ",
dbesc($t['hash']),
@@ -308,13 +315,22 @@ 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);
// This is a workaround for a missing xchan_updated column
// TODO: implement xchan_updated in the xchan table and update this column instead
if($zf['data']['primary_location']['address'] && $zf['data']['primary_location']['url']) {
q("UPDATE hubloc SET hubloc_updated = '%s' WHERE hubloc_id_url = '%s' AND hubloc_primary = 1",
dbesc(datetime_convert()),
dbesc($zf['data']['primary_location']['url'])
);
}
}
else {
q("update updates set ud_last = '%s' where ud_addr = '%s'",
@@ -338,10 +354,10 @@ class Libzotdir {
static function local_dir_update($uid, $force) {
logger('local_dir_update: uid: ' . $uid, LOGGER_DEBUG);
$p = q("select channel.channel_hash, channel_address, channel_timezone, channel_portable_id, profile.* from profile left join channel on channel_id = uid where uid = %d and is_default = 1",
$p = q("select channel.channel_hash, channel_address, channel_timezone, profile.* from profile left join channel on channel_id = uid where uid = %d and is_default = 1",
intval($uid)
);
@@ -350,11 +366,10 @@ class Libzotdir {
if ($p) {
$hash = $p[0]['channel_hash'];
$legacy_hash = $p[0]['channel_portable_id'];
$profile['description'] = $p[0]['pdesc'];
$profile['birthday'] = $p[0]['dob'];
if ($age = age($p[0]['dob'],$p[0]['channel_timezone'],''))
if ($age = age($p[0]['dob'],$p[0]['channel_timezone'],''))
$profile['age'] = $age;
$profile['gender'] = $p[0]['gender'];
@@ -389,10 +404,9 @@ class Libzotdir {
);
if(intval($r[0]['xchan_hidden']) != $hidden) {
$r = q("update xchan set xchan_hidden = %d where xchan_hash in ('%s', '%s')",
$r = q("update xchan set xchan_hidden = %d where xchan_hash = '%s'",
intval($hidden),
dbesc($hash),
dbesc($legacy_hash)
dbesc($hash)
);
}
@@ -406,16 +420,14 @@ class Libzotdir {
}
else {
// they may have made it private
q("delete from xprof where xprof_hash in ('%s', '%s')",
dbesc($hash),
dbesc($legacy_hash)
q("delete from xprof where xprof_hash = '%s'",
dbesc($hash)
);
q("delete from xtag where xtag_hash in ('%s', '%s')",
dbesc($hash),
dbesc($legacy_hash)
q("delete from xtag where xtag_hash = '%s'",
dbesc($hash)
);
}
}
$ud_hash = random_string() . '@' . \App::get_hostname();
@@ -446,7 +458,7 @@ class Libzotdir {
$arr['xprof_hash'] = $hash;
$arr['xprof_dob'] = (($profile['birthday'] === '0000-00-00') ? $profile['birthday'] : datetime_convert('','',$profile['birthday'],'Y-m-d')); // !!!! check this for 0000 year
$arr['xprof_age'] = (($profile['age']) ? intval($profile['age']) : 0);
$arr['xprof_desc'] = (($profile['description']) ? htmlspecialchars($profile['description'], ENT_COMPAT,'UTF-8',false) : '');
$arr['xprof_desc'] = (($profile['description']) ? htmlspecialchars($profile['description'], ENT_COMPAT,'UTF-8',false) : '');
$arr['xprof_gender'] = (($profile['gender']) ? htmlspecialchars($profile['gender'], ENT_COMPAT,'UTF-8',false) : '');
$arr['xprof_marital'] = (($profile['marital']) ? htmlspecialchars($profile['marital'], ENT_COMPAT,'UTF-8',false) : '');
$arr['xprof_sexual'] = (($profile['sexual']) ? htmlspecialchars($profile['sexual'], ENT_COMPAT,'UTF-8',false) : '');
@@ -631,8 +643,13 @@ class Libzotdir {
$dirmode = intval(get_config('system', 'directory_mode'));
if($dirmode == DIRECTORY_MODE_NORMAL)
if($dirmode == DIRECTORY_MODE_NORMAL) {
return;
}
if (empty($hash) || empty($guid) || empty($addr)) {
return;
}
if($flags) {
q("insert into updates (ud_hash, ud_guid, ud_date, ud_flags, ud_addr ) values ( '%s', '%s', '%s', %d, '%s' )",
@@ -641,7 +658,7 @@ class Libzotdir {
dbesc(datetime_convert()),
intval($flags),
dbesc($addr)
);
);
}
else {
q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and not (ud_flags & %d)>0 ",
@@ -652,9 +669,4 @@ class Libzotdir {
}
}
}

View File

@@ -11,8 +11,6 @@ class MessageFilter {
require_once('include/html2plain.php');
unobscure($item);
$text = prepare_text($item['body'],$item['mimetype']);
$text = html2plain(($item['title']) ? $item['title'] . ' ' . $text : $text);

View File

@@ -9,11 +9,11 @@ define ( 'NWIKI_ITEM_RESOURCE_TYPE', 'nwiki' );
class NativeWiki {
static public function listwikis($channel, $observer_hash) {
public static function listwikis($channel, $observer_hash) {
$sql_extra = item_permissions_sql($channel['channel_id'], $observer_hash);
$wikis = q("SELECT * FROM item
WHERE resource_type = '%s' AND mid = parent_mid AND uid = %d AND item_deleted = 0 $sql_extra",
$wikis = q("SELECT * FROM item
WHERE resource_type = '%s' AND mid = parent_mid AND uid = %d AND item_deleted = 0 $sql_extra",
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
intval($channel['channel_id'])
);
@@ -40,7 +40,7 @@ class NativeWiki {
}
function create_wiki($channel, $observer_hash, $wiki, $acl) {
public static function create_wiki($channel, $observer_hash, $wiki, $acl) {
$resource_id = new_uuid();
$uuid = new_uuid();
@@ -49,7 +49,7 @@ class NativeWiki {
$mid = z_root() . '/item/' . $uuid;
$arr = array(); // Initialize the array of parameters for the post
$item_hidden = ((intval($wiki['postVisible']) === 0) ? 1 : 0);
$item_hidden = ((intval($wiki['postVisible']) === 0) ? 1 : 0);
$wiki_url = z_root() . '/wiki/' . $channel['channel_address'] . '/' . $wiki['urlName'];
$arr['aid'] = $channel['channel_account_id'];
$arr['uuid'] = $uuid;
@@ -61,8 +61,8 @@ class NativeWiki {
$arr['resource_id'] = $resource_id;
$arr['owner_xchan'] = $channel['channel_hash'];
$arr['author_xchan'] = $observer_hash;
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']);
$arr['llink'] = $arr['plink'];
$arr['plink'] = $mid;
$arr['llink'] = z_root() . '/display/' . gen_link_id($mid);
$arr['title'] = $wiki['htmlName']; // name of new wiki;
$arr['allow_cid'] = $ac['allow_cid'];
$arr['allow_gid'] = $ac['allow_gid'];
@@ -101,7 +101,8 @@ class NativeWiki {
}
}
function update_wiki($channel_id, $observer_hash, $arr, $acl) {
public static function update_wiki($channel_id, $observer_hash, $arr, $acl) {
$w = self::get_wiki($channel_id, $observer_hash, $arr['resource_id']);
$item = $w['wiki'];
@@ -132,13 +133,13 @@ class NativeWiki {
// update acl for any existing wiki pages
q("update item set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', item_private = %d where resource_type = 'nwikipage' and resource_id = '%s'",
dbesc($item['allow_cid']),
dbesc($item['allow_gid']),
dbesc($item['deny_cid']),
dbesc($item['deny_gid']),
dbesc($item['item_private']),
dbesc($item['allow_cid']),
dbesc($item['allow_gid']),
dbesc($item['deny_cid']),
dbesc($item['deny_gid']),
dbesc($item['item_private']),
dbesc($arr['resource_id'])
);
);
if($update['item_id']) {
@@ -156,8 +157,8 @@ class NativeWiki {
}
}
static public function sync_a_wiki_item($uid,$id,$resource_id) {
public static function sync_a_wiki_item($uid,$id,$resource_id) {
$r = q("SELECT * from item WHERE uid = %d AND ( id = %d OR ( resource_type = '%s' and resource_id = '%s' )) ",
intval($uid),
@@ -165,8 +166,8 @@ class NativeWiki {
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
dbesc($resource_id)
);
if($r) {
$q = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s'",
dbesc($r[0]['resource_id'])
);
@@ -185,38 +186,45 @@ class NativeWiki {
}
}
function delete_wiki($channel_id,$observer_hash,$resource_id) {
public static function delete_wiki($channel_id,$observer_hash,$resource_id) {
$w = self::get_wiki($channel_id,$observer_hash,$resource_id);
$item = $w['wiki'];
if(! $item) {
return array('item' => null, 'success' => false);
}
else {
$drop = drop_item($item['id'], false, DROPITEM_NORMAL);
if(! $w['wiki']) {
return [ 'success' => false ];
}
else {
info( t('Wiki files deleted successfully'));
$r = q("SELECT id FROM item WHERE uid = %s AND resource_id = '%s'",
intval($channel_id),
dbesc($resource_id)
);
return array('item' => $item, 'item_id' => $item['id'], 'success' => (($drop === 1) ? true : false));
$ids = array_column($r, 'id');
drop_items($ids, true, DROPITEM_PHASE1);
info(t('Wiki files deleted successfully'));
return [ 'success' => true ];
}
}
static public function get_wiki($channel_id, $observer_hash, $resource_id) {
public static function get_wiki($channel_id, $observer_hash, $resource_id) {
$sql_extra = item_permissions_sql($channel_id,$observer_hash);
$item = q("SELECT * FROM item WHERE uid = %d AND resource_type = '%s' AND resource_id = '%s' AND item_deleted = 0
$sql_extra limit 1",
intval($channel_id),
$item = q("SELECT * FROM item WHERE uid = %d AND resource_type = '%s' AND resource_id = '%s' AND item_deleted = 0
$sql_extra ORDER BY id LIMIT 1",
intval($channel_id),
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
dbesc($resource_id)
);
if(! $item) {
return array('wiki' => null);
return [ 'wiki' => null ];
}
else {
$w = $item[0]; // wiki item table record
// Get wiki metadata
$rawName = get_iconfig($w, 'wiki', 'rawName');
@@ -236,29 +244,30 @@ class NativeWiki {
}
static public function exists_by_name($uid, $urlName) {
public static function exists_by_name($uid, $urlName) {
$sql_extra = item_permissions_sql($uid);
$sql_extra = item_permissions_sql($uid);
$item = q("SELECT item.id, resource_id FROM item left join iconfig on iconfig.iid = item.id
WHERE resource_type = '%s' AND iconfig.v = '%s' AND uid = %d
AND item_deleted = 0 $sql_extra limit 1",
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
//dbesc(urldecode($urlName)),
$item = q("SELECT item.id, resource_id FROM item left join iconfig on iconfig.iid = item.id
WHERE resource_type = '%s' AND iconfig.v = '%s' AND uid = %d
AND item_deleted = 0 $sql_extra limit 1",
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
//dbesc(urldecode($urlName)),
dbesc(self::name_decode($urlName)),
intval($uid)
);
if($item) {
return array('id' => $item[0]['id'], 'resource_id' => $item[0]['resource_id']);
}
}
else {
return array('id' => null, 'resource_id' => null);
}
}
static public function get_permissions($resource_id, $owner_id, $observer_hash) {
public static function get_permissions($resource_id, $owner_id, $observer_hash) {
// TODO: For now, only the owner can edit
$sql_extra = item_permissions_sql($owner_id, $observer_hash);
@@ -268,7 +277,7 @@ class NativeWiki {
$r = q("SELECT * FROM item WHERE uid = %d and resource_type = '%s' AND resource_id = '%s' $sql_extra LIMIT 1",
intval($owner_id),
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
dbesc($resource_id)
);
@@ -276,13 +285,12 @@ class NativeWiki {
return array('read' => false, 'write' => false, 'success' => true);
}
else {
// TODO: Create a new permission setting for wiki analogous to webpages. Until
// then, use webpage permissions
$write = perm_is_allowed($owner_id, $observer_hash,'write_wiki');
return array('read' => true, 'write' => $write, 'success' => true);
}
}
public static function name_encode ($string) {
$string = html_entity_decode($string);
@@ -298,6 +306,7 @@ class NativeWiki {
return $ret;
}
public static function name_decode ($string) {
$encoding = mb_internal_encoding();

View File

@@ -2,14 +2,15 @@
namespace Zotlabs\Lib;
use \Zotlabs\Lib as Zlib;
use App;
use Zotlabs\Access\PermissionLimits;
class NativeWikiPage {
static public function page_list($channel_id,$observer_hash, $resource_id) {
static public function page_list($channel_id, $observer_hash, $resource_id) {
// TODO: Create item table records for pages so that metadata like title can be applied
$w = Zlib\NativeWiki::get_wiki($channel_id,$observer_hash,$resource_id);
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
$pages[] = [
'resource_id' => '',
@@ -18,133 +19,149 @@ class NativeWikiPage {
'link_id' => 'id_wiki_home_0'
];
$sql_extra = item_permissions_sql($channel_id,$observer_hash);
$sql_extra = item_permissions_sql($channel_id, $observer_hash);
$r = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' and uid = %d and item_deleted = 0
$r = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' and uid = %d and item_deleted = 0
$sql_extra order by title asc",
dbesc($resource_id),
intval($channel_id)
);
if($r) {
if ($r) {
$x = [];
$y = [];
foreach($r as $rv) {
if(! in_array($rv['mid'],$x)) {
foreach ($r as $rv) {
if (!in_array($rv['mid'], $x)) {
$y[] = $rv;
$x[] = $rv['mid'];
}
}
$items = fetch_post_tags($y,true);
$items = fetch_post_tags($y, true);
foreach($items as $page_item) {
$title = get_iconfig($page_item['id'],'nwikipage','pagetitle',t('(No Title)'));
if(urldecode($title) !== 'Home') {
foreach ($items as $page_item) {
$title = get_iconfig($page_item['id'], 'nwikipage', 'pagetitle', t('(No Title)'));
if (urldecode($title) !== 'Home') {
$pages[] = [
'resource_id' => $resource_id,
'title' => escape_tags($title),
//'url' => str_replace('%2F','/',urlencode(str_replace('%2F','/',urlencode($title)))),
'url' => Zlib\NativeWiki::name_encode($title),
'url' => NativeWiki::name_encode($title),
'link_id' => 'id_' . substr($resource_id, 0, 10) . '_' . $page_item['id']
];
}
}
}
return array('pages' => $pages, 'wiki' => $w);
return ['pages' => $pages, 'wiki' => $w];
}
static public function create_page($channel_id, $observer_hash, $name, $resource_id, $mimetype = 'text/bbcode') {
static public function create_page($channel, $observer_hash, $name, $resource_id, $mimetype = 'text/bbcode') {
logger('mimetype: ' . $mimetype);
if(! in_array($mimetype,[ 'text/markdown','text/bbcode','text/plain','text/html' ]))
if (!in_array($mimetype, ['text/markdown', 'text/bbcode', 'text/plain', 'text/html']))
$mimetype = 'text/markdown';
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
$w = NativeWiki::get_wiki($channel['channel_id'], $observer_hash, $resource_id);
if (! $w['wiki']) {
return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
if (!$w['wiki']) {
return ['content' => null, 'message' => 'Error reading wiki', 'success' => false];
}
// backslashes won't work well in the javascript functions
$name = str_replace('\\','',$name);
$name = str_replace('\\', '', $name);
$uuid = new_uuid();
$mid = z_root() . '/item/' . $uuid;
// create an empty activity
$arr = [];
$arr['uid'] = $channel_id;
$arr['author_xchan'] = $observer_hash;
$arr['mimetype'] = $mimetype;
$arr['title'] = $name;
$arr['resource_type'] = 'nwikipage';
$arr['resource_id'] = $resource_id;
$arr['allow_cid'] = $w['wiki']['allow_cid'];
$arr['allow_gid'] = $w['wiki']['allow_gid'];
$arr['deny_cid'] = $w['wiki']['deny_cid'];
$arr['deny_gid'] = $w['wiki']['deny_gid'];
$arr['public_policy'] = map_scope(\Zotlabs\Access\PermissionLimits::Get($channel_id,'view_wiki'),true);
$arr = [];
$arr['aid'] = $channel['channel_account_id'];
$arr['uid'] = $channel['channel_id'];
$arr['mid'] = $mid;
$arr['parent_mid'] = $w['wiki']['mid'];
$arr['parent'] = $w['wiki']['parent'];
$arr['uuid'] = $uuid;
$arr['item_hidden'] = $w['wiki']['item_hidden'];
$arr['plink'] = $mid;
$arr['llink'] = z_root() . '/display/' . gen_link_id($mid);
$arr['author_xchan'] = $observer_hash;
$arr['mimetype'] = $mimetype;
$arr['title'] = $name;
$arr['resource_type'] = 'nwikipage';
$arr['resource_id'] = $resource_id;
$arr['allow_cid'] = $w['wiki']['allow_cid'];
$arr['allow_gid'] = $w['wiki']['allow_gid'];
$arr['deny_cid'] = $w['wiki']['deny_cid'];
$arr['deny_gid'] = $w['wiki']['deny_gid'];
$arr['item_private'] = $w['wiki']['item_private'];
$arr['item_wall'] = 1;
$arr['item_origin'] = 1;
$arr['item_thread_top'] = 1;
$arr['verb'] = ACTIVITY_CREATE;
$arr['obj_type'] = 'Document';
// TODO: add an object?
$arr['public_policy'] = map_scope(PermissionLimits::Get($channel['channel_id'], 'view_wiki'), true);
// We may wish to change this some day.
$arr['item_unpublished'] = 1;
set_iconfig($arr,'nwikipage','pagetitle',(($name) ? $name : t('(No Title)')),true);
set_iconfig($arr, 'nwikipage', 'pagetitle', (($name) ? $name : t('(No Title)')), true);
$p = item_store($arr, false, false);
$p = post_activity_item($arr, false, false);
if($p['item_id']) {
$page = [
if ($p['item_id']) {
$page = [
'rawName' => $name,
'htmlName' => escape_tags($name),
//'urlName' => urlencode($name),
'urlName' => Zlib\NativeWiki::name_encode($name)
//'urlName' => urlencode($name),
'urlName' => NativeWiki::name_encode($name)
];
return array('page' => $page, 'item_id' => $p['item_id'], 'item' => $p['activity'], 'wiki' => $w, 'message' => '', 'success' => true);
return ['page' => $page, 'item_id' => $p['item_id'], 'item' => $p['activity'], 'wiki' => $w, 'message' => '', 'success' => true];
}
return [ 'success' => false, 'message' => t('Wiki page create failed.') ];
return ['success' => false, 'message' => t('Wiki page create failed.')];
}
static public function rename_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$pageNewName = ((array_key_exists('pageNewName',$arr)) ? $arr['pageNewName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
$pageUrlName = ((array_key_exists('pageUrlName', $arr)) ? $arr['pageUrlName'] : '');
$pageNewName = ((array_key_exists('pageNewName', $arr)) ? $arr['pageNewName'] : '');
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash', $arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id', $arr)) ? $arr['channel_id'] : 0);
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if(! $w['wiki']) {
return array('message' => t('Wiki not found.'), 'success' => false);
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (!$w['wiki']) {
return ['message' => t('Wiki not found.'), 'success' => false];
}
$ic = q("select * from iconfig left join item on iconfig.iid = item.id
$ic = q("select * from iconfig left join item on iconfig.iid = item.id
where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
intval($channel_id),
dbesc($pageNewName)
);
if($ic) {
return [ 'success' => false, 'message' => t('Destination name already exists') ];
if ($ic) {
return ['success' => false, 'message' => t('Destination name already exists')];
}
$ids = [];
$ic = q("select *, item.id as item_id from iconfig left join item on iconfig.iid = item.id
$ic = q("select *, item.id as item_id from iconfig left join item on iconfig.iid = item.id
where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
intval($channel_id),
dbesc($pageUrlName)
);
if($ic) {
foreach($ic as $c) {
set_iconfig($c['item_id'],'nwikipage','pagetitle',$pageNewName);
if ($ic) {
foreach ($ic as $c) {
set_iconfig($c['item_id'], 'nwikipage', 'pagetitle', $pageNewName);
$ids[] = $c['item_id'];
}
@@ -153,101 +170,101 @@ class NativeWikiPage {
dbesc($pageNewName)
);
$page = [
'rawName' => $pageNewName,
'htmlName' => escape_tags($pageNewName),
$page = [
'rawName' => $pageNewName,
'htmlName' => escape_tags($pageNewName),
//'urlName' => urlencode(escape_tags($pageNewName))
'urlName' => Zlib\NativeWiki::name_encode($pageNewName)
'urlName' => NativeWiki::name_encode($pageNewName)
];
return [ 'success' => true, 'page' => $page ];
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')];
}
static public function get_page_content($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? intval($arr['channel_id']) : 0);
$revision = ((array_key_exists('revision',$arr)) ? intval($arr['revision']) : (-1));
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash', $arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id', $arr)) ? intval($arr['channel_id']) : 0);
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (! $w['wiki']) {
return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (!$w['wiki']) {
return ['content' => null, 'message' => 'Error reading wiki', 'success' => false];
}
$item = self::load_page($arr);
if($item) {
if ($item) {
$content = $item['body'];
return [
return [
'content' => $content,
'mimeType' => $w['mimeType'],
'pageMimeType' => $item['mimetype'],
'message' => '',
'pageMimeType' => $item['mimetype'],
'message' => '',
'success' => true
];
}
return array('content' => null, 'message' => t('Error reading page content'), 'success' => false);
return ['content' => null, 'message' => t('Error reading page content'), 'success' => false];
}
static public function page_history($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
static public function page_history($arr) {
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash', $arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id', $arr)) ? $arr['channel_id'] : 0);
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (!$w['wiki']) {
return array('history' => null, 'message' => 'Error reading wiki', 'success' => false);
return ['history' => null, 'message' => 'Error reading wiki', 'success' => false];
}
$items = self::load_page_history($arr);
$history = [];
if($items) {
if ($items) {
$processed = 0;
foreach($items as $item) {
if($processed > 1000)
foreach ($items as $item) {
if ($processed > 1000)
break;
$processed ++;
$history[] = [
$processed++;
$history[] = [
'revision' => $item['revision'],
'date' => datetime_convert('UTC',date_default_timezone_get(),$item['edited']),
'name' => $item['author']['xchan_name'],
'title' => get_iconfig($item,'nwikipage','commit_msg')
'date' => datetime_convert('UTC', date_default_timezone_get(), $item['edited']),
'name' => $item['author']['xchan_name'],
'title' => get_iconfig($item, 'nwikipage', 'commit_msg')
];
}
return [ 'success' => true, 'history' => $history ];
return ['success' => true, 'history' => $history];
}
return [ 'success' => false ];
return ['success' => false];
}
static public function load_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
$revision = ((array_key_exists('revision',$arr)) ? $arr['revision'] : (-1));
$pageUrlName = ((array_key_exists('pageUrlName', $arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash', $arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id', $arr)) ? $arr['channel_id'] : 0);
$revision = ((array_key_exists('revision', $arr)) ? $arr['revision'] : (-1));
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (! $w['wiki']) {
return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
if (!$w['wiki']) {
return ['content' => null, 'message' => 'Error reading wiki', 'success' => false];
}
$ids = '';
@@ -257,32 +274,32 @@ class NativeWikiPage {
dbesc($pageUrlName)
);
if($ic) {
foreach($ic as $c) {
if($ids)
if ($ic) {
foreach ($ic as $c) {
if ($ids)
$ids .= ',';
$ids .= intval($c['iid']);
}
}
$sql_extra = item_permissions_sql($channel_id,$observer_hash);
$sql_extra = item_permissions_sql($channel_id, $observer_hash);
if($revision == (-1))
if ($revision == (-1))
$sql_extra .= " order by revision desc ";
elseif($revision)
elseif ($revision)
$sql_extra .= " and revision = " . intval($revision) . " ";
$r = null;
if($ids) {
if ($ids) {
$r = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' and uid = %d and id in ( $ids ) $sql_extra limit 1",
dbesc($resource_id),
intval($channel_id)
);
if($r) {
$items = fetch_post_tags($r,true);
if ($r) {
$items = fetch_post_tags($r, true);
return $items[0];
}
}
@@ -290,17 +307,17 @@ class NativeWikiPage {
return null;
}
static public function load_page_history($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
$revision = ((array_key_exists('revision',$arr)) ? $arr['revision'] : (-1));
$pageUrlName = ((array_key_exists('pageUrlName', $arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash', $arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id', $arr)) ? $arr['channel_id'] : 0);
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (! $w['wiki']) {
return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (!$w['wiki']) {
return ['content' => null, 'message' => 'Error reading wiki', 'success' => false];
}
$ids = '';
@@ -309,28 +326,28 @@ class NativeWikiPage {
intval($channel_id),
dbesc($pageUrlName)
);
if($ic) {
foreach($ic as $c) {
if($ids)
if ($ic) {
foreach ($ic as $c) {
if ($ids)
$ids .= ',';
$ids .= intval($c['iid']);
}
}
$sql_extra = item_permissions_sql($channel_id,$observer_hash);
$sql_extra = item_permissions_sql($channel_id, $observer_hash);
$sql_extra .= " order by revision desc ";
$r = null;
if($ids) {
if ($ids) {
$r = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' and uid = %d and id in ( $ids ) and item_deleted = 0 $sql_extra",
dbesc($resource_id),
intval($channel_id)
);
if($r) {
if ($r) {
xchan_query($r);
$items = fetch_post_tags($r,true);
$items = fetch_post_tags($r, true);
return $items;
}
}
@@ -338,33 +355,32 @@ class NativeWikiPage {
return null;
}
static public function save_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName', $arr)) ? $arr['pageUrlName'] : '');
$content = ((array_key_exists('content', $arr)) ? $arr['content'] : '');
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash', $arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id', $arr)) ? $arr['channel_id'] : 0);
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$content = ((array_key_exists('content',$arr)) ? $arr['content'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
$revision = ((array_key_exists('revision',$arr)) ? $arr['revision'] : 0);
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (!$w['wiki']) {
return array('message' => t('Error reading wiki'), 'success' => false);
return ['message' => t('Error reading wiki'), 'success' => false];
}
// fetch the most recently saved revision.
// fetch the most recently saved revision.
$item = self::load_page($arr);
if(! $item) {
return array('message' => t('Page not found'), 'success' => false);
if (!$item) {
return ['message' => t('Page not found'), 'success' => false];
}
$mimetype = $item['mimetype'];
// change just the fields we need to change to create a revision;
// change just the fields we need to change to create a revision;
unset($item['id']);
unset($item['author']);
@@ -375,8 +391,8 @@ class NativeWikiPage {
$item['edited'] = datetime_convert();
$item['mimetype'] = $mimetype;
if($item['iconfig'] && is_array($item['iconfig']) && count($item['iconfig'])) {
for($x = 0; $x < count($item['iconfig']); $x ++) {
if ($item['iconfig'] && is_array($item['iconfig']) && count($item['iconfig'])) {
for ($x = 0; $x < count($item['iconfig']); $x++) {
unset($item['iconfig'][$x]['id']);
unset($item['iconfig'][$x]['iid']);
}
@@ -384,162 +400,164 @@ class NativeWikiPage {
$ret = item_store($item, false, false);
if($ret['item_id'])
return array('message' => '', 'item_id' => $ret['item_id'], 'filename' => $filename, 'success' => true);
if ($ret['item_id'])
return ['message' => '', 'item_id' => $ret['item_id'], 'filename' => $pageUrlName, 'success' => true];
else
return array('message' => t('Page update failed.'), 'success' => false);
}
return ['message' => t('Page update failed.'), 'success' => false];
}
static public function delete_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
$pageUrlName = (array_key_exists('pageUrlName', $arr) ? $arr['pageUrlName'] : '');
$resource_id = (array_key_exists('resource_id', $arr) ? $arr['resource_id'] : '');
$observer_hash = (array_key_exists('observer_hash', $arr) ? $arr['observer_hash'] : '');
$channel_id = (array_key_exists('channel_id', $arr) ? $arr['channel_id'] : 0);
if(! $w['wiki']) {
return [ 'success' => false, 'message' => t('Error reading wiki') ];
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (!$w['wiki']) {
return ['success' => false, 'message' => t('Error reading wiki')];
}
$ids = [];
$ic = q("select * from iconfig left join item on iconfig.iid = item.id
$ic = q("select * from iconfig left join item on iconfig.iid = item.id
where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
intval($channel_id),
dbesc($pageUrlName)
);
if($ic) {
foreach($ic as $c) {
if ($ic) {
foreach ($ic as $c) {
$ids[] = intval($c['iid']);
}
}
if($ids) {
drop_items($ids);
return [ 'success' => true ];
if ($ids) {
drop_items($ids, true, DROPITEM_PHASE1);
return ['success' => true];
}
return [ 'success' => false, 'message' => t('Nothing deleted') ];
return ['success' => false, 'message' => t('Nothing deleted')];
}
static public function revert_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$commitHash = ((array_key_exists('commitHash',$arr)) ? $arr['commitHash'] : null);
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
if (! $commitHash) {
return array('content' => $content, 'message' => 'No commit was provided', 'success' => false);
static public function revert_page($arr) {
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
$commitHash = ((array_key_exists('commitHash', $arr)) ? $arr['commitHash'] : null);
$observer_hash = ((array_key_exists('observer_hash', $arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id', $arr)) ? $arr['channel_id'] : 0);
if (!$commitHash) {
return ['message' => 'No commit was provided', 'success' => false];
}
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (!$w['wiki']) {
return array('content' => $content, 'message' => 'Error reading wiki', 'success' => false);
return ['message' => 'Error reading wiki', 'success' => false];
}
$x = $arr;
if(intval($commitHash) > 0) {
if (intval($commitHash) > 0) {
unset($x['commitHash']);
$x['revision'] = intval($commitHash) - 1;
$loaded = self::load_page($x);
$loaded = self::load_page($x);
if($loaded) {
if ($loaded) {
$content = $loaded['body'];
return [ 'content' => $content, 'success' => true ];
return ['content' => $content, 'success' => true];
}
return [ 'content' => $content, 'success' => false ];
return ['success' => false];
}
}
static public function compare_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$currentCommit = ((array_key_exists('currentCommit',$arr)) ? $arr['currentCommit'] : (-1));
$compareCommit = ((array_key_exists('compareCommit',$arr)) ? $arr['compareCommit'] : 0);
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
static public function compare_page($arr) {
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
$compareCommit = ((array_key_exists('compareCommit', $arr)) ? $arr['compareCommit'] : 0);
$observer_hash = ((array_key_exists('observer_hash', $arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id', $arr)) ? $arr['channel_id'] : 0);
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (!$w['wiki']) {
return array('message' => t('Error reading wiki'), 'success' => false);
return ['message' => t('Error reading wiki'), 'success' => false];
}
$x = $arr;
$x = $arr;
$x['revision'] = (-1);
$currpage = self::load_page($x);
if($currpage)
if ($currpage)
$currentContent = $currpage['body'];
$x['revision'] = $compareCommit;
$comppage = self::load_page($x);
if($comppage)
$comppage = self::load_page($x);
if ($comppage)
$compareContent = $comppage['body'];
if($currpage && $comppage) {
if ($currpage && $comppage) {
require_once('library/class.Diff.php');
$diff = \Diff::toTable(\Diff::compare($currentContent, $compareContent));
return [ 'success' => true, 'diff' => $diff ];
return ['success' => true, 'diff' => $diff];
}
return [ 'success' => false, 'message' => t('Compare: object not found.') ];
return ['success' => false, 'message' => t('Compare: object not found.')];
}
static public function commit($arr) {
$commit_msg = ((array_key_exists('commit_msg', $arr)) ? $arr['commit_msg'] : t('Page updated'));
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : t('Untitled'));
$commit_msg = ((array_key_exists('commit_msg', $arr)) ? $arr['commit_msg'] : t('Page updated'));
$observer_hash = ((array_key_exists('observer_hash', $arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id', $arr)) ? $arr['channel_id'] : 0);
if(array_key_exists('resource_id', $arr)) {
if (array_key_exists('resource_id', $arr)) {
$resource_id = $arr['resource_id'];
}
else {
return array('message' => t('Wiki resource_id required for git commit'), 'success' => false);
return ['message' => t('Wiki resource_id required for git commit'), 'success' => false];
}
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (! $w['wiki']) {
return array('message' => t('Error reading wiki'), 'success' => false);
$w = NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (!$w['wiki']) {
return ['message' => t('Error reading wiki'), 'success' => false];
}
$page = self::load_page($arr);
if($page) {
set_iconfig($page['id'],'nwikipage','commit_msg',escape_tags($commit_msg),true);
return [ 'success' => true, 'item_id' => $page['id'], 'page' => $page ];
if ($page) {
set_iconfig($page['id'], 'nwikipage', 'commit_msg', escape_tags($commit_msg), true);
return ['success' => true, 'item_id' => $page['id'], 'page' => $page];
}
return [ 'success' => false, 'message' => t('Page not found.') ];
return ['success' => false, 'message' => t('Page not found.')];
}
static public function convert_links($s, $wikiURL) {
if (strpos($s,'[[') !== false) {
if (strpos($s, '[[') !== false) {
preg_match_all("/\[\[(.*?)\]\]/", $s, $match);
$pages = $pageURLs = array();
$pages = $pageURLs = [];
foreach ($match[1] as $m) {
// TODO: Why do we need to double urlencode for this to work?
//$pageURLs[] = urlencode(urlencode(escape_tags($m)));
$titleUri = explode('|',$m);
$page = $titleUri[0] ?? '';
$title = $titleUri[1] ?? $page;
$pageURLs[] = Zlib\NativeWiki::name_encode(escape_tags($page));
$pages[] = $title;
$titleUri = explode('|', $m);
$page = $titleUri[0] ?? '';
$title = $titleUri[1] ?? $page;
$pageURLs[] = NativeWiki::name_encode(escape_tags($page));
$pages[] = $title;
}
$idx = 0;
while(strpos($s,'[[') !== false) {
$replace = '<a href="'.$wikiURL.'/'.$pageURLs[$idx].'">'.$pages[$idx].'</a>';
$s = preg_replace("/\[\[(.*?)\]\]/", $replace, $s, 1);
while (strpos($s, '[[') !== false) {
$replace = '<a href="' . $wikiURL . '/' . $pageURLs[$idx] . '">' . $pages[$idx] . '</a>';
$s = preg_replace("/\[\[(.*?)\]\]/", $replace, $s, 1);
$idx++;
}
}
@@ -552,26 +570,25 @@ class NativeWikiPage {
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
$pageHistory = self::page_history([
'channel_id' => \App::$profile_uid,
'channel_id' => App::$profile_uid,
'observer_hash' => get_observer_hash(),
'resource_id' => $resource_id,
'pageUrlName' => $pageUrlName
]);
return replace_macros(get_markup_template('nwiki_page_history.tpl'), array(
return replace_macros(get_markup_template('nwiki_page_history.tpl'), [
'$pageHistory' => $pageHistory['history'],
'$permsWrite' => $arr['permsWrite'],
'$name_lbl' => t('Name'),
'$msg_label' => t('Message','wiki_history'),
'$msg_label' => t('Message', 'wiki_history'),
'$date_lbl' => t('Date'),
'$revert_btn' => t('Revert'),
'$compare_btn' => t('Compare')
));
]);
}
/**
* Replace the instances of the string [toc] with a list element that will be populated by
* a table of contents by the JavaScript library
@@ -579,41 +596,42 @@ class NativeWikiPage {
* @return string
*/
static public function generate_toc($s) {
if (strpos($s,'[toc]') !== false) {
if (strpos($s, '[toc]') !== false) {
//$toc_md = wiki_toc($s); // Generate Markdown-formatted list prior to HTML render
$toc_md = '<ul id="wiki-toc"></ul>'; // use the available jQuery plugin http://ndabas.github.io/toc/
$s = preg_replace("/\[toc\]/", $toc_md, $s, -1);
$s = preg_replace("/\[toc\]/", $toc_md, $s, -1);
}
return $s;
}
/**
* Converts a select set of bbcode tags. Much of the code is copied from include/bbcode.php
* @param string $s
* @return string
*/
static public function bbcode($s) {
$s = str_replace(array('[baseurl]', '[sitename]'), array(z_root(), get_config('system', 'sitename')), $s);
$s = preg_replace_callback("/\[observer\.language\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_callback', $s);
$s = preg_replace_callback("/\[observer\.language\!\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_necallback', $s);
$s = str_replace(['[baseurl]', '[sitename]'], [z_root(), get_config('system', 'sitename')], $s);
$s = preg_replace_callback("/\[observer\.language\=(.*?)\](.*?)\[\/observer\]/ism", 'oblanguage_callback', $s);
$s = preg_replace_callback("/\[observer\.language\!\=(.*?)\](.*?)\[\/observer\]/ism", 'oblanguage_necallback', $s);
$observer = \App::get_observer();
$observer = App::get_observer();
if ($observer) {
$s1 = '<span class="bb_observer" title="' . t('Different viewers will see this text differently') . '">';
$s2 = '</span>';
$s1 = '<span class="bb_observer" title="' . t('Different viewers will see this text differently') . '">';
$s2 = '</span>';
$obsBaseURL = $observer['xchan_connurl'];
$obsBaseURL = preg_replace("/\/poco\/.*$/", '', $obsBaseURL);
$s = str_replace('[observer.baseurl]', $obsBaseURL, $s);
$s = str_replace('[observer.url]', $observer['xchan_url'], $s);
$s = str_replace('[observer.name]', $s1 . $observer['xchan_name'] . $s2, $s);
$s = str_replace('[observer.address]', $s1 . $observer['xchan_addr'] . $s2, $s);
$s = str_replace('[observer.webname]', substr($observer['xchan_addr'], 0, strpos($observer['xchan_addr'], '@')), $s);
$s = str_replace('[observer.photo]', '', $s);
}
$s = str_replace('[observer.baseurl]', $obsBaseURL, $s);
$s = str_replace('[observer.url]', $observer['xchan_url'], $s);
$s = str_replace('[observer.name]', $s1 . $observer['xchan_name'] . $s2, $s);
$s = str_replace('[observer.address]', $s1 . $observer['xchan_addr'] . $s2, $s);
$s = str_replace('[observer.webname]', substr($observer['xchan_addr'], 0, strpos($observer['xchan_addr'], '@')), $s);
$s = str_replace('[observer.photo]', '', $s);
}
else {
$s = str_replace('[observer.baseurl]', '', $s);
$s = str_replace('[observer.url]', '', $s);
@@ -625,60 +643,63 @@ class NativeWikiPage {
return $s;
}
static public function get_file_ext($arr) {
if($arr['mimetype'] === 'text/bbcode')
if ($arr['mimetype'] === 'text/bbcode')
return '.bb';
elseif($arr['mimetype'] === 'text/markdown')
elseif ($arr['mimetype'] === 'text/markdown')
return '.md';
elseif($arr['mimetype'] === 'text/plain')
elseif ($arr['mimetype'] === 'text/plain')
return '.txt';
}
// This function is derived from
// This function is derived from
// http://stackoverflow.com/questions/32068537/generate-table-of-contents-from-markdown-in-php
static public function toc($content) {
// ensure using only "\n" as line-break
$source = str_replace(["\r\n", "\r"], "\n", $content);
// look for markdown TOC items
preg_match_all(
'/^(?:=|-|#).*$/m',
$source,
$matches,
PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE
);
// preprocess: iterate matched lines to create an array of items
// where each item is an array(level, text)
$file_size = strlen($source);
foreach ($matches[0] as $item) {
$found_mark = substr($item[0], 0, 1);
if ($found_mark == '#') {
// text is the found item
$item_text = $item[0];
$item_level = strrpos($item_text, '#') + 1;
$item_text = substr($item_text, $item_level);
} else {
// text is the previous line (empty if <hr>)
$item_offset = $item[1];
$prev_line_offset = strrpos($source, "\n", -($file_size - $item_offset + 2));
$item_text =
substr($source, $prev_line_offset, $item_offset - $prev_line_offset - 1);
$item_text = trim($item_text);
$item_level = $found_mark == '=' ? 1 : 2;
// ensure using only "\n" as line-break
$source = str_replace(["\r\n", "\r"], "\n", $content);
// look for markdown TOC items
preg_match_all(
'/^(?:=|-|#).*$/m',
$source,
$matches,
PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE
);
// preprocess: iterate matched lines to create an array of items
// where each item is an array(level, text)
$file_size = strlen($source);
foreach ($matches[0] as $item) {
$found_mark = substr($item[0], 0, 1);
if ($found_mark == '#') {
// text is the found item
$item_text = $item[0];
$item_level = strrpos($item_text, '#') + 1;
$item_text = substr($item_text, $item_level);
}
else {
// text is the previous line (empty if <hr>)
$item_offset = $item[1];
$prev_line_offset = strrpos($source, "\n", -($file_size - $item_offset + 2));
$item_text =
substr($source, $prev_line_offset, $item_offset - $prev_line_offset - 1);
$item_text = trim($item_text);
$item_level = $found_mark == '=' ? 1 : 2;
}
if (!trim($item_text) or strpos($item_text, '|') !== FALSE) {
// item is an horizontal separator or a table header, don't mind
continue;
}
$raw_toc[] = ['level' => $item_level, 'text' => trim($item_text)];
}
if (!trim($item_text) OR strpos($item_text, '|') !== FALSE) {
// item is an horizontal separator or a table header, don't mind
continue;
}
$raw_toc[] = ['level' => $item_level, 'text' => trim($item_text)];
}
$o = '';
foreach($raw_toc as $t) {
foreach ($raw_toc as $t) {
$level = intval($t['level']);
$text = $t['text'];
$text = $t['text'];
switch ($level) {
case 1:
$li = '* ';
@@ -698,7 +719,7 @@ class NativeWikiPage {
}
$o .= $li . $text . "\n";
}
return $o;
return $o;
}
}

View File

@@ -2,6 +2,8 @@
namespace Zotlabs\Lib;
use App;
/**
* @brief Class for handling channel specific configurations.
*
@@ -32,15 +34,15 @@ class PConfig {
if(is_null($uid) || $uid === false)
return false;
if(! is_array(\App::$config)) {
if(! is_array(App::$config)) {
btlogger('App::$config not an array');
}
if(! array_key_exists($uid, \App::$config)) {
\App::$config[$uid] = array();
if(! array_key_exists($uid, App::$config)) {
App::$config[$uid] = array();
}
if(! is_array(\App::$config[$uid])) {
if(! is_array(App::$config[$uid])) {
btlogger('App::$config[$uid] not an array: ' . $uid);
}
@@ -52,12 +54,12 @@ class PConfig {
foreach($r as $rr) {
$k = $rr['k'];
$c = $rr['cat'];
if(! array_key_exists($c, \App::$config[$uid])) {
\App::$config[$uid][$c] = array();
\App::$config[$uid][$c]['config_loaded'] = true;
if(! array_key_exists($c, App::$config[$uid])) {
App::$config[$uid][$c] = array();
App::$config[$uid][$c]['config_loaded'] = true;
}
\App::$config[$uid][$c][$k] = $rr['v'];
\App::$config[$uid][$c]['pcfgud:'.$k] = $rr['updated'];
App::$config[$uid][$c][$k] = $rr['v'];
App::$config[$uid][$c]['pcfgud:'.$k] = $rr['updated'];
}
}
}
@@ -86,15 +88,15 @@ class PConfig {
if(is_null($uid) || $uid === false)
return $default;
if(! array_key_exists($uid, \App::$config))
if(! array_key_exists($uid, App::$config))
self::Load($uid);
if((! array_key_exists($family, \App::$config[$uid])) || (! array_key_exists($key, \App::$config[$uid][$family])))
if((! array_key_exists($family, App::$config[$uid])) || (! array_key_exists($key, App::$config[$uid][$family])))
return $default;
return ((! is_array(\App::$config[$uid][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$uid][$family][$key]))
? unserialize(\App::$config[$uid][$family][$key])
: \App::$config[$uid][$family][$key]
return ((! is_array(App::$config[$uid][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', App::$config[$uid][$family][$key]))
? unserialize(App::$config[$uid][$family][$key])
: App::$config[$uid][$family][$key]
);
}
@@ -132,6 +134,8 @@ class PConfig {
// manage array value
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
$new = false;
$update = false;
$now = datetime_convert();
if (! $updated) {
@@ -142,23 +146,22 @@ class PConfig {
$updated = datetime_convert('UTC','UTC','-2 seconds');
}
$hash = hash('sha256',$family.':'.$key);
$hash = gen_link_id($family.':'.$key);
if (self::Get($uid, 'hz_delpconfig', $hash) !== false) {
if (self::Get($uid, 'hz_delpconfig', $hash) > $now) {
logger('Refusing to update pconfig with outdated info (Item deleted more recently).', LOGGER_NORMAL, LOG_ERR);
return self::Get($uid,$family,$key);
} else {
self::Delete($uid,'hz_delpconfig',$hash);
self::Delete($uid, 'hz_delpconfig', $hash);
}
}
if(self::Get($uid, $family, $key) === false) {
if(! array_key_exists($uid, \App::$config))
\App::$config[$uid] = array();
if(! array_key_exists($family, \App::$config[$uid]))
\App::$config[$uid][$family] = array();
if(! array_key_exists($uid, App::$config))
App::$config[$uid] = array();
if(! array_key_exists($family, App::$config[$uid]))
App::$config[$uid][$family] = array();
$ret = q("INSERT INTO pconfig ( uid, cat, k, v, updated ) VALUES ( %d, '%s', '%s', '%s', '%s' ) ",
intval($uid),
@@ -176,13 +179,14 @@ class PConfig {
logger("Error: Insert to pconfig failed.",LOGGER_NORMAL, LOG_ERR);
}
\App::$config[$uid][$family]['pcfgud:'.$key] = $updated;
$new = true;
App::$config[$uid][$family]['pcfgud:'.$key] = $updated;
}
else {
$new = (\App::$config[$uid][$family]['pcfgud:'.$key] < $now);
$update = (App::$config[$uid][$family]['pcfgud:'.$key] < $now);
if ($new) {
if ($update) {
// @NOTE There is still a possible race condition under limited circumstances
// where a value will be updated by another thread with more current data than
@@ -197,7 +201,7 @@ class PConfig {
dbesc($key)
);
\App::$config[$uid][$family]['pcfgud:'.$key] = $updated;
App::$config[$uid][$family]['pcfgud:'.$key] = $updated;
} else {
logger('Refusing to update pconfig with outdated info.', LOGGER_NORMAL, LOG_ERR);
@@ -210,16 +214,16 @@ class PConfig {
// set in the life of this page. We need this to
// synchronise channel clones.
if(! array_key_exists('transient', \App::$config[$uid]))
\App::$config[$uid]['transient'] = array();
if(! array_key_exists($family, \App::$config[$uid]['transient']))
\App::$config[$uid]['transient'][$family] = array();
if(! array_key_exists('transient', App::$config[$uid]))
App::$config[$uid]['transient'] = array();
if(! array_key_exists($family, App::$config[$uid]['transient']))
App::$config[$uid]['transient'][$family] = array();
\App::$config[$uid][$family][$key] = $value;
App::$config[$uid][$family][$key] = $value;
if ($new) {
\App::$config[$uid]['transient'][$family][$key] = $value;
\App::$config[$uid]['transient'][$family]['pcfgud:'.$key] = $updated;
if ($new || $update) {
App::$config[$uid]['transient'][$family][$key] = $value;
App::$config[$uid]['transient'][$family]['pcfgud:'.$key] = $updated;
}
if($ret)
@@ -252,7 +256,7 @@ class PConfig {
$updated = ($updated) ? $updated : datetime_convert('UTC','UTC','-2 seconds');
$now = datetime_convert();
$newer = (\App::$config[$uid][$family]['pcfgud:'.$key] < $now);
$newer = (App::$config[$uid][$family]['pcfgud:'.$key] < $now);
if (! $newer) {
logger('Refusing to delete pconfig with outdated delete request.', LOGGER_NORMAL, LOG_ERR);
@@ -261,12 +265,12 @@ class PConfig {
$ret = false;
if (isset(\App::$config[$uid][$family][$key])) {
unset(\App::$config[$uid][$family][$key]);
if (isset(App::$config[$uid][$family][$key])) {
unset(App::$config[$uid][$family][$key]);
}
if (isset(\App::$config[$uid][$family]['pcfgud:'.$key])) {
unset(\App::$config[$uid][$family]['pcfgud:'.$key]);
if (isset(App::$config[$uid][$family]['pcfgud:'.$key])) {
unset(App::$config[$uid][$family]['pcfgud:'.$key]);
}
$ret = q("DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s'",
@@ -277,9 +281,9 @@ class PConfig {
// Synchronize delete with clones.
if ($family != 'hz_delpconfig') {
$hash = hash('sha256',$family.':'.$key);
set_pconfig($uid,'hz_delpconfig',$hash,$updated);
if ($family !== 'hz_delpconfig') {
$hash = gen_link_id($family.':'.$key);
set_pconfig($uid, 'hz_delpconfig', $hash, $updated);
}
return $ret;

View File

@@ -4,6 +4,8 @@ namespace Zotlabs\Lib;
use Zotlabs\Access\PermissionRoles;
use Zotlabs\Access\Permissions;
use Zotlabs\Lib\Libsync;
use Zotlabs\Daemon\Master;
/**
* @brief Permission Categories. Permission rules for various classes of connections.
@@ -79,8 +81,9 @@ class Permcat {
$this->permcats[] = [
'name' => 'default',
'localname' => t('default','permcat'),
'localname' => t('Default','permcat'),
'perms' => Permissions::Operms($perms),
'raw_perms' => $perms,
'system' => 1
];
@@ -92,6 +95,7 @@ class Permcat {
'name' => $p[$x][0],
'localname' => $p[$x][1],
'perms' => Permissions::Operms(Permissions::FilledPerms($p[$x][2])),
'raw_perms' => Permissions::FilledPerms($p[$x][2]),
'system' => intval($p[$x][3])
];
}
@@ -128,27 +132,24 @@ class Permcat {
}
public function load_permcats($uid) {
/*
$permcats = [
[ 'follower', t('follower','permcat'),
[ 'view_stream','view_profile','view_contacts','view_storage','view_pages','view_wiki',
'post_like' ], 1
],
[ 'contributor', t('contributor','permcat'),
[ 'view_stream','view_profile','view_contacts','view_storage','view_pages','view_wiki',
'post_wall','post_comments','write_wiki','post_like','tag_deliver','chat' ], 1
],
[ 'publisher', t('publisher','permcat'),
[ 'contributor', t('Contributor','permcat'),
[ 'view_stream','view_profile','view_contacts','view_storage','view_pages',
'write_storage','post_wall','write_pages','write_wiki','post_comments','post_like','tag_deliver',
'chat', 'republish' ], 1
]
'write_storage','post_wall','write_pages','write_wiki','post_comments', 'post_mail', 'post_like',
'chat' ], 1
],
[ 'muted', t('Muted','permcat'),
[ 'view_stream','view_profile','view_contacts','view_storage','view_pages','view_wiki',
'post_comments','write_wiki','post_like' ], 1
],
];
*/
if($uid) {
$x = q("select * from pconfig where uid = %d and cat = 'permcat'",
intval($uid)
);
if($x) {
foreach($x as $xv) {
$value = ((preg_match('|^a:[0-9]+:{.*}$|s', $xv['v'])) ? unserialize($xv['v']) : $xv['v']);
@@ -183,4 +184,105 @@ class Permcat {
PConfig::Delete($channel_id, 'permcat', $name);
}
}
/**
* @brief assign a contact role to contacts
*
* @param int $channel_id
* @param string $role the name of the role
* @param array $contacts an array of contact hashes
*/
public static function assign($channel, $role, $contacts) {
if(!isset($channel['channel_id'])) {
return;
}
if(!is_array($contacts) || empty($contacts)) {
return;
}
if(!$role) {
// lookup the default
$role = get_pconfig($channel_id, 'system', 'default_permcat', 'default');
}
// Doublecheck that we do not assign a role to ourself.
// It does not make a difference but could be confusing.
if (in_array($channel['channel_hash'], $contacts)) {
$contacts = array_diff($contacts, [$channel['channel_hash']]);
}
$all_perms = Permissions::Perms();
$permcats = new Permcat($channel['channel_id']);
$role_perms = $permcats->fetch($role);
if (isset($role_perms['error'])) {
return false;
}
$perms = $role_perms['raw_perms'];
$values_sql = '';
stringify_array_elms($contacts, true);
if ($all_perms && $perms) {
foreach ($contacts as $contact) {
foreach ($all_perms as $perm => $desc) {
if (array_key_exists($perm, $perms)) {
$values_sql .= " (" . intval($channel['channel_id']) . ", " . protect_sprintf($contact) . ", 'my_perms', '" . dbesc($perm) . "', " . intval($perms[$perm]) . "),";
}
else {
$values_sql .= " (" . intval($channel['channel_id']) . ", " . protect_sprintf($contact) . ", 'my_perms', '" . dbesc($perm) . "', 0), ";
}
}
}
}
$values_sql = rtrim($values_sql, ',');
dbq("DELETE FROM abconfig WHERE chan = " . intval($channel['channel_id']) . " AND cat = 'my_perms' AND xchan IN (" . protect_sprintf(implode(',', $contacts)) . ")");
dbq("INSERT INTO abconfig ( chan, xchan, cat, k, v ) VALUES $values_sql");
q("UPDATE abook SET abook_role = '%s'
WHERE abook_xchan IN (" . protect_sprintf(implode(',', $contacts)) . ") AND abook_channel = %d",
dbesc($role),
intval($channel['channel_id'])
);
$r = q("SELECT abook.*, xchan.* FROM abook LEFT JOIN xchan ON abook.abook_xchan = xchan.xchan_hash WHERE abook.abook_xchan IN (" . protect_sprintf(implode(',', $contacts)) . ") AND abook.abook_channel = %d AND abook_self = 0",
intval($channel['channel_id'])
);
foreach ($r as $rr) {
if (intval($rr['abook_self'])) {
continue;
}
Master::Summon([
'Notifier',
'permission_update',
$rr['abook_id']
]);
$clone = $rr;
unset($clone['abook_id']);
unset($clone['abook_account']);
unset($clone['abook_channel']);
$abconfig = load_abconfig($channel['channel_id'], $clone['abook_xchan']);
if ($abconfig)
$clone['abconfig'] = $abconfig;
Libsync::build_sync_packet(0 /* use the current local_channel */, ['abook' => [$clone]]);
}
return true;
}
}

View File

@@ -2,8 +2,8 @@
namespace Zotlabs\Lib;
use Zotlabs\Lib\Libzot;
use Zotlabs\Zot6\Receiver;
use Zotlabs\Zot6\Zot6Handler;
class Queue {
@@ -31,19 +31,19 @@ class Queue {
$might_be_down = ((datetime_convert('UTC','UTC',$y[0]['earliest']) < datetime_convert('UTC','UTC','now - 2 days')) ? true : false);
// Set all other records for this destination way into the future.
// Set all other records for this destination way into the future.
// The queue delivers by destination. We'll keep one queue item for
// this destination (this one) with a shorter delivery. If we succeed
// once, we'll try to deliver everything for that destination.
// The delivery will be set to at most once per hour, and if the
// The delivery will be set to at most once per hour, and if the
// queue item is less than 12 hours old, we'll schedule for fifteen
// minutes.
// minutes.
$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'])
);
$since = datetime_convert('UTC','UTC',$x[0]['outq_created']);
if(($might_be_down) || ($since < datetime_convert('UTC','UTC','now - 12 hour'))) {
@@ -53,9 +53,9 @@ class Queue {
$next = datetime_convert('UTC','UTC','now + ' . intval($add_priority) . ' minutes');
}
q("UPDATE outq SET outq_updated = '%s',
outq_priority = outq_priority + %d,
outq_scheduled = '%s'
q("UPDATE outq SET outq_updated = '%s',
outq_priority = outq_priority + %d,
outq_scheduled = '%s'
WHERE outq_hash = '%s'",
dbesc(datetime_convert()),
@@ -69,7 +69,7 @@ class Queue {
static function remove($id,$channel_id = 0) {
logger('queue: remove queue item ' . $id,LOGGER_DEBUG);
$sql_extra = (($channel_id) ? " and outq_channel = " . intval($channel_id) . " " : '');
q("DELETE FROM outq WHERE outq_hash = '%s' $sql_extra",
dbesc($id)
);
@@ -78,7 +78,7 @@ class Queue {
static function remove_by_posturl($posturl) {
logger('queue: remove queue posturl ' . $posturl,LOGGER_DEBUG);
q("DELETE FROM outq WHERE outq_posturl = '%s' ",
dbesc($posturl)
);
@@ -88,10 +88,10 @@ 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.
// long before it ever makes it back into the delivery chain.
q("update outq set outq_delivered = 1, outq_updated = '%s', outq_scheduled = '%s' where outq_hash = '%s' $sql_extra ",
dbesc(datetime_convert()),
@@ -111,7 +111,7 @@ class Queue {
}
$x = q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_priority,
outq_created, outq_updated, outq_scheduled, outq_notify, outq_msg )
outq_created, outq_updated, outq_scheduled, outq_notify, outq_msg )
values ( '%s', %d, %d, '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s' )",
dbesc($arr['hash']),
intval($arr['account_id']),
@@ -119,7 +119,7 @@ class Queue {
dbesc(($arr['driver']) ? $arr['driver'] : 'zot6'),
dbesc($arr['posturl']),
intval(1),
intval(($arr['priority']) ? $arr['priority'] : 0),
intval(isset($arr['priority']) ? $arr['priority'] : 0),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
@@ -136,8 +136,8 @@ class Queue {
$base = null;
$h = parse_url($outq['outq_posturl']);
if($h !== false)
$base = $h['scheme'] . '://' . $h['host'] . (($h['port']) ? ':' . $h['port'] : '');
if($h !== false)
$base = $h['scheme'] . '://' . $h['host'] . (isset($h['port']) ? ':' . $h['port'] : '');
if(($base) && ($base !== z_root()) && ($immediate)) {
$y = q("select site_update, site_dead from site where site_url = '%s' ",
@@ -150,7 +150,7 @@ class Queue {
return;
}
if($y[0]['site_update'] < datetime_convert('UTC','UTC','now - 1 month')) {
self::update($outq['outq_hash'],10);
self::update($outq['outq_hash'], 10);
logger('immediate delivery deferred for site ' . $base);
return;
}
@@ -161,12 +161,12 @@ class Queue {
// your site has existed. Since we don't know for sure what these sites are,
// call them unknown
site_store_lowlevel(
site_store_lowlevel(
[
'site_url' => $base,
'site_update' => datetime_convert(),
'site_dead' => 0,
'site_type' => intval(($outq['outq_driver'] === 'post') ? SITE_TYPE_NOTZOT : SITE_TYPE_UNKNOWN),
'site_type' => SITE_TYPE_UNKNOWN,
'site_crypto' => ''
]
);
@@ -174,67 +174,18 @@ class Queue {
}
$arr = array('outq' => $outq, 'base' => $base, 'handled' => false, 'immediate' => $immediate);
call_hooks('queue_deliver',$arr);
call_hooks('queue_deliver', $arr);
if($arr['handled'])
return;
// "post" queue driver - used for diaspora and friendica-over-diaspora communications.
if($outq['outq_driver'] === 'post') {
$result = z_post_url($outq['outq_posturl'],$outq['outq_msg']);
if($result['success'] && $result['return_code'] < 300) {
logger('deliver: queue post success to ' . $outq['outq_posturl'], LOGGER_DEBUG);
if($base) {
q("update site set site_update = '%s', site_dead = 0 where site_url = '%s' ",
dbesc(datetime_convert()),
dbesc($base)
);
}
q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'",
dbesc('accepted for delivery'),
dbesc(datetime_convert()),
dbesc($outq['outq_hash'])
);
self::remove($outq['outq_hash']);
// server is responding - see if anything else is going to this destination and is piled up
// and try to send some more. We're relying on the fact that do_delivery() results in an
// immediate delivery otherwise we could get into a queue loop.
if(! $immediate) {
$x = q("select outq_hash from outq where outq_posturl = '%s' and outq_delivered = 0",
dbesc($outq['outq_posturl'])
);
$piled_up = array();
if($x) {
foreach($x as $xx) {
$piled_up[] = $xx['outq_hash'];
}
}
if($piled_up) {
// call do_delivery() with the force flag
do_delivery($piled_up, true);
}
}
}
else {
logger('deliver: queue post returned ' . $result['return_code']
. ' from ' . $outq['outq_posturl'],LOGGER_DEBUG);
self::update($outq['outq_hash'],10);
}
return;
}
// normal zot delivery
logger('deliver: dest: ' . $outq['outq_posturl'], LOGGER_DEBUG);
if($outq['outq_posturl'] === z_root() . '/zot') {
// local delivery
$zot = new \Zotlabs\Zot6\Receiver(new \Zotlabs\Zot6\Zot6Handler(),$outq['outq_notify']);
$result = $zot->run(true);
$zot = new Receiver(new Zot6Handler(), $outq['outq_notify']);
$result = $zot->run();
logger('returned_json: ' . json_encode($result,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES), LOGGER_DATA);
logger('deliver: local zot delivery succeeded to ' . $outq['outq_posturl']);
Libzot::process_response($outq['outq_posturl'],[ 'success' => true, 'body' => json_encode($result) ], $outq);
@@ -244,13 +195,14 @@ class Queue {
$channel = null;
if($outq['outq_channel']) {
$channel = channelx_by_n($outq['outq_channel']);
$channel = channelx_by_n($outq['outq_channel'], true);
}
$host_crypto = null;
if($channel && $base) {
$h = q("select hubloc_sitekey, site_crypto from hubloc left join site on hubloc_url = site_url where site_url = '%s' and hubloc_sitekey != '' order by hubloc_id desc limit 1",
$h = q("SELECT hubloc_sitekey, site_crypto FROM hubloc LEFT JOIN site ON hubloc_url = site_url
WHERE site_url = '%s' AND hubloc_network = 'zot6' ORDER BY hubloc_id DESC LIMIT 1",
dbesc($base)
);
if($h) {
@@ -260,7 +212,7 @@ class Queue {
$msg = $outq['outq_notify'];
$result = Libzot::zot($outq['outq_posturl'],$msg,$channel,$host_crypto);
$result = Libzot::zot($outq['outq_posturl'], $msg, $channel, $host_crypto);
if($result['success']) {
logger('deliver: remote zot delivery succeeded to ' . $outq['outq_posturl']);
@@ -269,7 +221,7 @@ class Queue {
else {
logger('deliver: remote zot delivery failed to ' . $outq['outq_posturl']);
logger('deliver: remote zot delivery fail data: ' . print_r($result,true), LOGGER_DATA);
self::update($outq['outq_hash'],10);
self::update($outq['outq_hash'], 10);
}
}
return;

View File

@@ -2,21 +2,19 @@
namespace Zotlabs\Lib;
use Zotlabs\Lib\Activity;
class Share {
private $item = null;
public function __construct($post_id) {
if(! $post_id)
return;
if(! (local_channel() || remote_channel()))
return;
$r = q("SELECT * from item left join xchan on author_xchan = xchan_hash WHERE id = %d LIMIT 1",
intval($post_id)
);
@@ -25,26 +23,26 @@ class Share {
if(($r[0]['item_private']) && ($r[0]['xchan_network'] !== 'rss'))
return;
$sql_extra = item_permissions_sql($r[0]['uid']);
$r = q("select * from item where id = %d $sql_extra",
intval($post_id)
);
if(! $r)
return;
if($r[0]['mimetype'] !== 'text/bbcode')
return;
/** @FIXME eventually we want to post remotely via rpost on your home site */
// When that works remove this next bit:
if(! local_channel())
return;
xchan_query($r);
$this->item = $r[0];
return;
}
@@ -68,14 +66,14 @@ class Share {
'address' => $this->item['author']['xchan_addr'],
'network' => $this->item['author']['xchan_network'],
'link' => [
[
'rel' => 'alternate',
'type' => 'text/html',
[
'rel' => 'alternate',
'type' => 'text/html',
'href' => $this->item['author']['xchan_url']
],
[
'rel' => 'photo',
'type' => $this->item['author']['xchan_photo_mimetype'],
'rel' => 'photo',
'type' => $this->item['author']['xchan_photo_mimetype'],
'href' => $this->item['author']['xchan_photo_m']
]
]
@@ -86,14 +84,14 @@ class Share {
'address' => $this->item['owner']['xchan_addr'],
'network' => $this->item['owner']['xchan_network'],
'link' => [
[
'rel' => 'alternate',
'type' => 'text/html',
[
'rel' => 'alternate',
'type' => 'text/html',
'href' => $this->item['owner']['xchan_url']
],
[
'rel' => 'photo',
'type' => $this->item['owner']['xchan_photo_mimetype'],
'rel' => 'photo',
'type' => $this->item['owner']['xchan_photo_mimetype'],
'href' => $this->item['owner']['xchan_photo_m']
]
]
@@ -119,7 +117,7 @@ class Share {
$object = json_decode($this->item['obj'],true);
$photo_bb = $object['body'];
}
if (strpos($this->item['body'], "[/share]") !== false) {
$pos = strpos($this->item['body'], "[share");
$bb = substr($this->item['body'], $pos);
@@ -128,7 +126,7 @@ class Share {
"' profile='" . $this->item['author']['xchan_url'] .
"' avatar='" . $this->item['author']['xchan_photo_s'] .
"' link='" . $this->item['plink'] .
"' auth='" . ((in_array($this->item['author']['xchan_network'], ['zot6', 'zot'])) ? 'true' : 'false') .
"' auth='" . (($this->item['author']['xchan_network'] === 'zot6') ? 'true' : 'false') .
"' posted='" . $this->item['created'] .
"' message_id='" . $this->item['mid'] .
"']";

View File

@@ -2,7 +2,9 @@
namespace Zotlabs\Lib;
use App;
use Zotlabs\Lib\Apps;
use Zotlabs\Access\AccessList;
require_once('include/text.php');
@@ -35,7 +37,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');
@@ -43,7 +45,7 @@ class ThreadItem {
$observer = \App::get_observer();
// Prepare the children
if($data['children']) {
if(isset($data['children'])) {
foreach($data['children'] as $item) {
/*
@@ -58,6 +60,9 @@ class ThreadItem {
$child = new ThreadItem($item);
$this->add_child($child);
}
// performance: we have already added the children
unset($this->data['children']);
}
// allow a site to configure the order and content of the reaction emoji list
@@ -98,17 +103,42 @@ 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'])
|| strlen($item['deny_cid']) || strlen($item['deny_gid']))))
? t('Private Message')
$acl = new AccessList(false);
$acl->set($item);
$lock = ((intval($item['item_private']) || ($item['uid'] == local_channel() && $acl->is_private()))
? t('Restricted message')
: false);
// 1 = restricted message, 2 = direct message
$locktype = intval($item['item_private']);
if ($locktype === 2) {
$lock = t('Direct message');
}
// 0 = limited based on public policy
if ($item['uid'] == local_channel() && intval($item['item_private']) && !$acl->is_private() && strlen($item['public_policy'])) {
$lock = t('Public Policy');
$locktype = 0;
}
$shareable = ((($conv->get_profile_owner() == local_channel() && local_channel()) && ($item['item_private'] != 1)) ? true : false);
// allow an exemption for sharing stuff from your private feeds
if($item['author']['xchan_network'] === 'rss')
$shareable = true;
// @fixme
// Have recently added code to properly handle polls in group reshares by redirecting all of the poll responses to the group.
// Sharing a poll using a regular embedded share is harder because the poll will need to fork. This is due to comment permissions.
// The original poll author may not accept responses from strangers. Forking the poll will receive responses from the sharer's
// followers, but there's no elegant way to merge these two sets of results together. For now, we'll disable sharing polls.
if ($item['obj_type'] === 'Question') {
$shareable = false;
}
$privacy_warning = false;
if(intval($item['item_private']) && ($item['owner']['xchan_network'] === 'activitypub')) {
$recips = get_iconfig($item['parent'], 'activitypub', 'recips');
@@ -151,9 +181,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 +199,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 +253,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 +284,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 +294,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 +305,7 @@ class ThreadItem {
);
}
}
}
else {
$is_comment = true;
}
@@ -298,7 +328,7 @@ class ThreadItem {
);
*/
$settings = t('Conversation Tools');
$settings = t('Conversation Features');
}
$has_bookmarks = false;
@@ -349,7 +379,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 +387,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);
@@ -366,7 +396,7 @@ class ThreadItem {
call_hooks('dropdown_extras',$dropdown_extras_arr);
$dropdown_extras = $dropdown_extras_arr['dropdown_extras'];
$midb64 = 'b64.' . base64url_encode($item['mid']);
$midb64 = gen_link_id($item['mid']);
$mids = [ $midb64 ];
$response_mids = [];
foreach($response_verbs as $v) {
@@ -383,10 +413,16 @@ class ThreadItem {
$pinned_items = ($allowed_type ? get_pconfig($item['uid'], 'pinned', $item['item_type'], []) : []);
$pinned = ((!empty($pinned_items) && in_array($midb64, $pinned_items)) ? true : false);
$contact = [];
if(App::$contacts && array_key_exists($item['author_xchan'], App::$contacts)) {
$contact = App::$contacts[$item['author_xchan']];
}
$tmp_item = array(
'template' => $this->get_template(),
'mode' => $mode,
'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'],
@@ -400,6 +436,7 @@ class ThreadItem {
'mids' => $json_mids,
'parent' => $item['parent'],
'author_id' => (($item['author']['xchan_addr']) ? $item['author']['xchan_addr'] : $item['author']['xchan_url']),
'author_is_group_actor' => (($item['author']['xchan_pubforum']) ? t('Forum') : ''),
'isevent' => $isevent,
'attend' => $attend,
'consensus' => $consensus,
@@ -432,6 +469,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,
@@ -501,7 +539,9 @@ class ThreadItem {
'wait' => t('Please wait'),
'thread_level' => $thread_level,
'settings' => $settings,
'thr_parent' => (($item['parent_mid'] != $item['thr_parent']) ? 'b64.' . base64url_encode($item['thr_parent']) : '')
'thr_parent' => (($item['parent_mid'] != $item['thr_parent']) ? gen_link_id($item['thr_parent']) : ''),
'contact_id' => (($contact) ? $contact['abook_id'] : '')
);
$arr = array('item' => $item, 'output' => $tmp_item);
@@ -518,8 +558,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 +579,7 @@ class ThreadItem {
}
}
}
$result['private'] = $item['item_private'];
$result['toplevel'] = ($this->is_toplevel() ? 'toplevel_item' : '');
@@ -554,7 +594,7 @@ class ThreadItem {
return $result;
}
public function get_id() {
return $this->get_data_value('id');
}
@@ -609,7 +649,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 +723,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 +832,7 @@ class ThreadItem {
if(!$this->is_toplevel() && !get_config('system','thread_allow')) {
return '';
}
$comment_box = '';
$conv = $this->get_conversation();
@@ -808,7 +848,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(),
@@ -840,7 +880,7 @@ class ThreadItem {
'$cipher' => $conv->get_cipher(),
'$sourceapp' => \App::$sourcename,
'$observer' => get_observer_hash(),
'$anoncomments' => ((($conv->get_mode() === 'channel' || $conv->get_mode() === 'display') && perm_is_allowed($conv->get_profile_owner(),'','post_comments')) ? true : false),
'$anoncomments' => ((in_array($conv->get_mode(), ['channel', 'display', 'cards', 'articles']) && perm_is_allowed($conv->get_profile_owner(),'','post_comments')) ? true : false),
'$anonname' => [ 'anonname', t('Your full name (required)') ],
'$anonmail' => [ 'anonmail', t('Your email address (required)') ],
'$anonurl' => [ 'anonurl', t('Your website URL (optional)') ]
@@ -865,7 +905,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

@@ -77,7 +77,7 @@ class ThreadStream {
$this->reload = $_SESSION['return_url'];
break;
case 'display':
// in this mode we set profile_owner after initialisation (from conversation()) and then
// in this mode we set profile_owner after initialisation (from conversation()) and then
// pull some trickery which allows us to re-invoke this function afterward
// it's an ugly hack so @FIXME
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
@@ -170,14 +170,14 @@ class ThreadStream {
* Only add things that will be displayed
*/
if(($item->get_data_value('id') != $item->get_data_value('parent')) && (activity_match($item->get_data_value('verb'),ACTIVITY_LIKE) || activity_match($item->get_data_value('verb'),ACTIVITY_DISLIKE))) {
return false;
}
$item->set_commentable(false);
$ob_hash = (($this->observer) ? $this->observer['xchan_hash'] : '');
if(! comments_are_now_closed($item->get_data())) {
if(($item->get_data_value('author_xchan') === $ob_hash) || ($item->get_data_value('owner_xchan') === $ob_hash))
$item->set_commentable(true);
@@ -194,7 +194,7 @@ class ThreadStream {
}
if($this->mode === 'pubstream' && (! local_channel())) {
$item->set_commentable(false);
}
}
$item->set_conversation($this);

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;
@@ -88,4 +87,4 @@ class ZotURL {
return ids_to_array($r,'hubloc_url');
}
}
}

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

@@ -2,8 +2,10 @@
namespace Zotlabs\Module;
use Zotlabs\Lib\Libzotdir;
use Zotlabs\Lib\AccessList;
require_once 'include/acl_selectors.php';
require_once 'include/group.php';
/**
* @brief ACL selector json backend.
@@ -46,20 +48,20 @@ class Acl extends \Zotlabs\Web\Controller {
// 'a' => autocomplete connections (mod_connections, mod_poke, mod_sources, mod_photos)
// 'x' => nav search bar autocomplete (match any xchan)
// $_REQUEST['query'] contains autocomplete search text.
// List of channels whose connections to also suggest,
// List of channels whose connections to also suggest,
// e.g. currently viewed channel or channels mentioned in a post
$extra_channels = (x($_REQUEST,'extra_channels') ? $_REQUEST['extra_channels'] : array());
// The different autocomplete libraries use different names for the search text
// parameter. Internally we'll use $search to represent the search text no matter
// what request variable it was attached to.
// what request variable it was attached to.
if(array_key_exists('query',$_REQUEST)) {
$search = $_REQUEST['query'];
}
if( (! local_channel()) && (! in_array($type, [ 'x', 'c', 'f' ])))
killme();
@@ -68,7 +70,7 @@ class Acl extends \Zotlabs\Web\Controller {
if(in_array($type, [ 'm', 'a', 'c', 'f' ])) {
// These queries require permission checking. We'll create a simple array of xchan_hash for those with
// the requisite permissions which we can check against.
// the requisite permissions which we can check against.
$x = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = '%s' and v = '1'",
intval(local_channel()),
@@ -85,34 +87,34 @@ class Acl extends \Zotlabs\Web\Controller {
$sql_extra2 = "AND ( xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " OR xchan_addr LIKE " . protect_sprintf( "'%" . dbesc(punify($search)) . ((strpos($search,'@') === false) ? "%@%'" : "%'")) . ") ";
$sql_extra2_xchan = "AND ( xchan_name LIKE " . protect_sprintf( "'" . dbesc($search) . "%'" ) . " OR xchan_addr LIKE " . protect_sprintf( "'" . dbesc(punify($search)) . ((strpos($search,'@') === false) ? "%@%'" : "%'")) . ") ";
// This horrible mess is needed because position also returns 0 if nothing is found.
// This horrible mess is needed because position also returns 0 if nothing is found.
// Would be MUCH easier if it instead returned a very large value
// Otherwise we could just
// Otherwise we could just
// order by LEAST(POSITION($search IN xchan_name),POSITION($search IN xchan_addr)).
$order_extra2 = "CASE WHEN xchan_name LIKE "
. protect_sprintf( "'%" . dbesc($search) . "%'" )
. " then POSITION('" . protect_sprintf(dbesc($search))
$order_extra2 = "CASE WHEN xchan_name LIKE "
. protect_sprintf( "'%" . dbesc($search) . "%'" )
. " then POSITION('" . protect_sprintf(dbesc($search))
. "' IN xchan_name) else position('" . protect_sprintf(dbesc(punify($search))) . "' IN xchan_addr) end, ";
$sql_extra3 = "AND ( xchan_addr like " . protect_sprintf( "'%" . dbesc(punify($search)) . "%'" ) . " OR xchan_name like " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " ) ";
}
else {
$sql_extra = $sql_extra2 = $sql_extra3 = "";
}
$groups = array();
$contacts = array();
if($type == '' || $type == 'g') {
// virtual groups based on private profile viewing ability
$r = q("select id, profile_guid, profile_name from profile where is_default = 0 and uid = %d",
intval(local_channel())
);
);
if($r) {
foreach($r as $rv) {
$groups[] = array(
@@ -121,7 +123,7 @@ class Acl extends \Zotlabs\Web\Controller {
"name" => t('Profile','acl') . ' ' . $rv['profile_name'],
"id" => 'vp' . $rv['id'],
"xid" => 'vp.' . $rv['profile_guid'],
"uids" => group_get_profile_members_xchan(local_channel(), $rv['id']),
"uids" => AccessList::profile_members_xchan(local_channel(), $rv['id']),
"link" => ''
);
}
@@ -130,37 +132,37 @@ class Acl extends \Zotlabs\Web\Controller {
// Normal privacy groups
$r = q("SELECT pgrp.id, pgrp.hash, pgrp.gname
FROM pgrp, pgrp_member
WHERE pgrp.deleted = 0 AND pgrp.uid = %d
FROM pgrp, pgrp_member
WHERE pgrp.deleted = 0 AND pgrp.uid = %d
AND pgrp_member.gid = pgrp.id
$sql_extra
GROUP BY pgrp.id
ORDER BY pgrp.gname
ORDER BY pgrp.gname
LIMIT %d OFFSET %d",
intval(local_channel()),
intval($count),
intval($start)
);
if($r) {
if($r) {
foreach($r as $g){
// logger('acl: group: ' . $g['gname'] . ' members: ' . group_get_members_xchan($g['id']));
// logger('acl: group: ' . $g['gname'] . ' members: ' . AccessList::members_xchan(local_channel(), $g['id']));
$groups[] = array(
"type" => "g",
"photo" => "images/twopeople.png",
"name" => $g['gname'],
"id" => $g['id'],
"xid" => $g['hash'],
"uids" => group_get_members_xchan($g['id']),
"uids" => AccessList::members_xchan(local_channel(), $g['id']),
"link" => ''
);
}
}
}
if($type == '' || $type == 'c' || $type === 'f') {
$extra_channels_sql = '';
$extra_channels_sql = '';
// Only include channels who allow the observer to view their connections
if($extra_channels) {
@@ -172,7 +174,7 @@ class Acl extends \Zotlabs\Web\Controller {
}
}
}
// Getting info from the abook is better for local users because it contains info about permissions
if(local_channel()) {
if($extra_channels_sql != '')
@@ -199,7 +201,7 @@ class Acl extends \Zotlabs\Web\Controller {
$r2 = array();
foreach($r1 as $rr) {
$x = atoken_xchan($rr);
$r2[] = [
$r2[] = [
'id' => 'a' . $rr['atoken_id'] ,
'hash' => $x['xchan_hash'],
'name' => $x['xchan_name'],
@@ -211,42 +213,43 @@ class Acl extends \Zotlabs\Web\Controller {
'abook_self' => 0
];
}
}
}
// add connections
$r = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, xchan_pubforum, abook_flags, abook_self
FROM abook left join xchan on abook_xchan = xchan_hash
$r = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_network as net, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, xchan_pubforum, abook_flags, abook_self
FROM abook left join xchan on abook_xchan = xchan_hash
WHERE (abook_channel = %d $extra_channels_sql) AND abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc" ,
intval(local_channel())
);
if($r2)
$r = array_merge($r2,$r);
}
else { // Visitors
$r = q("SELECT xchan_hash as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self
$r = q("SELECT xchan_hash as id, xchan_hash as hash, xchan_name as name, xchan_network as net, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self
FROM xchan left join xlink on xlink_link = xchan_hash
WHERE xlink_xchan = '%s' AND xchan_deleted = 0 $sql_extra2_xchan order by $order_extra2 xchan_name asc" ,
dbesc(get_observer_hash())
);
// Find contacts of extra channels
// This is probably more complicated than it needs to be
if($extra_channels_sql) {
// Build a list of hashes that we got previously so we don't get them again
$known_hashes = array("'".get_observer_hash()."'");
if($r)
foreach($r as $rr)
foreach($r as $rr)
$known_hashes[] = "'".$rr['hash']."'";
$known_hashes_sql = 'AND xchan_hash not in ('.join(',',$known_hashes).')';
$r2 = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, abook_flags, abook_self
FROM abook left join xchan on abook_xchan = xchan_hash
$r2 = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_network as net, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, abook_flags, abook_self
FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_channel IN ($extra_channels_sql) $known_hashes_sql AND abook_blocked = 0 and abook_pending = 0 and abook_hidden = 0 and xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc");
if($r2)
$r = array_merge($r,$r2);
// Sort accoring to match position, then alphabetically. This could be avoided if the above two SQL queries could be combined into one, and the sorting could be done on the SQl server (like in the case of a local user)
$matchpos = function($x) use($search) {
$namepos = strpos($x['name'],$search);
@@ -269,24 +272,23 @@ class Acl extends \Zotlabs\Web\Controller {
}
}
if((count($r) < 100) && $type == 'c') {
$r2 = q("SELECT substr(xchan_hash,1,18) as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self
FROM xchan
$r2 = q("SELECT substr(xchan_hash,1,18) as id, xchan_hash as hash, xchan_name as name, xchan_network as net, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self
FROM xchan
WHERE xchan_deleted = 0 and not xchan_network in ('rss','anon','unknown') $sql_extra2_xchan order by $order_extra2 xchan_name asc"
);
if($r2) {
$r = array_merge($r,$r2);
$r = unique_multidim_array($r,'hash');
}
}
}
}
elseif($type == 'm') {
$r = array();
$z = q("SELECT xchan_hash as hash, xchan_name as name, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url
$z = q("SELECT xchan_hash as hash, xchan_name as name, xchan_network as net, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url
FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_channel = %d
WHERE abook_channel = %d
and xchan_deleted = 0
and xchan_network IN ('zot', 'diaspora', 'friendica-over-diaspora')
and not xchan_network IN ('rss', 'anon', 'unknown')
$sql_extra3
ORDER BY xchan_name ASC ",
intval(local_channel())
@@ -298,18 +300,18 @@ class Acl extends \Zotlabs\Web\Controller {
}
}
}
}
elseif($type == 'a') {
$r = q("SELECT abook_id as id, xchan_name as name, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_network as network, xchan_url as url, xchan_addr as attag , abook_their_perms FROM abook left join xchan on abook_xchan = xchan_hash
$r = q("SELECT abook_id as id, xchan_name as name, xchan_network as net, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url, xchan_addr as attag , abook_their_perms FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_channel = %d
and xchan_deleted = 0
$sql_extra3
ORDER BY xchan_name ASC ",
intval(local_channel())
);
}
elseif($type == 'x') {
$r = $this->navbar_complete($a);
@@ -323,7 +325,7 @@ class Acl extends \Zotlabs\Web\Controller {
);
}
}
$o = array(
'start' => $start,
'count' => $count,
@@ -334,27 +336,34 @@ class Acl extends \Zotlabs\Web\Controller {
}
else
$r = array();
if($r) {
$i = count($contacts);
$x = [];
foreach($r as $g) {
if(in_array($g['network'],['rss','anon','unknown']) && ($type != 'a'))
if(in_array($g['net'],['rss','anon','unknown']) && ($type != 'a'))
continue;
$g['hash'] = urlencode($g['hash']);
if(! $g['nick']) {
$g['nick'] = $g['url'];
}
$clink = ($g['nick']) ? $g['nick'] : $g['url'];
$lkey = md5($clink);
if (! array_key_exists($lkey, $x))
$x[$lkey] = $i;
if(in_array($g['hash'],$permitted) && $type === 'f' && (! $noforums)) {
$contacts[] = array(
$contacts[$i] = array(
"type" => "c",
"photo" => "images/twopeople.png",
"name" => $g['name'],
"id" => urlencode($g['id']),
"xid" => $g['hash'],
"link" => (($g['nick']) ? $g['nick'] : $g['url']),
"link" => $clink,
"nick" => substr($g['nick'],0,strpos($g['nick'],'@')),
"self" => (intval($g['abook_self']) ? 'abook-self' : ''),
"taggable" => 'taggable',
@@ -362,24 +371,28 @@ class Acl extends \Zotlabs\Web\Controller {
);
}
if($type !== 'f') {
$contacts[] = array(
"type" => "c",
"photo" => $g['micro'],
"name" => $g['name'],
"id" => urlencode($g['id']),
"xid" => $g['hash'],
"link" => (($g['nick']) ? $g['nick'] : $g['url']),
"nick" => ((strpos($g['nick'],'@')) ? substr($g['nick'],0,strpos($g['nick'],'@')) : $g['nick']),
"self" => (intval($g['abook_self']) ? 'abook-self' : ''),
"taggable" => '',
"label" => '',
);
if (! array_key_exists($x[$lkey], $contacts) || ($contacts[$x[$lkey]]['net'] !== 'zot6' && $g['net'] == 'zot6')) {
$contacts[$x[$lkey]] = array(
"type" => "c",
"photo" => $g['micro'],
"name" => $g['name'],
"id" => urlencode($g['id']),
"xid" => $g['hash'],
"link" => $clink,
"nick" => ((strpos($g['nick'],'@')) ? substr($g['nick'],0,strpos($g['nick'],'@')) : $g['nick']),
"self" => (intval($g['abook_self']) ? 'abook-self' : ''),
"taggable" => '',
"label" => '',
"net" => $g['net']
);
}
}
}
$i++;
}
}
$items = array_merge($groups, $contacts);
$o = array(
'start' => $start,
'count' => $count,
@@ -393,50 +406,49 @@ class Acl extends \Zotlabs\Web\Controller {
function navbar_complete(&$a) {
// logger('navbar_complete');
if(observer_prohibited()) {
return;
}
$dirmode = intval(get_config('system','directory_mode'));
$search = ((x($_REQUEST,'search')) ? htmlentities($_REQUEST['search'],ENT_COMPAT,'UTF-8',false) : '');
if(! $search || mb_strlen($search) < 2)
return array();
$star = false;
$address = false;
if(substr($search,0,1) === '@')
$search = substr($search,1);
if(substr($search,0,1) === '*') {
$star = true;
$search = substr($search,1);
}
if(strpos($search,'@') !== false) {
$address = true;
}
if(($dirmode == DIRECTORY_MODE_PRIMARY) || ($dirmode == DIRECTORY_MODE_STANDALONE)) {
$url = z_root() . '/dirsearch';
}
if(! $url) {
require_once("include/dir_fns.php");
$directory = find_upstream_directory($dirmode);
$directory = Libzotdir::find_upstream_directory($dirmode);
$url = $directory['url'] . '/dirsearch';
}
$token = get_config('system','realm_token');
$count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 100);
if($url) {
$query = $url . '?f=' . (($token) ? '&t=' . urlencode($token) : '');
$query .= '&name=' . urlencode($search) . "&limit=$count" . (($address) ? '&address=' . urlencode(punify($search)) : '');
$x = z_fetch_url($query);
if($x['success']) {
$t = 0;

View File

@@ -26,7 +26,12 @@ class Activity extends Controller {
$portable_id = EMPTY_STR;
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 ";
$item_normal_extra = sprintf(" and not verb in ('%s', '%s') ",
dbesc(ACTIVITY_FOLLOW),
dbesc(ACTIVITY_UNFOLLOW)
);
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 $item_normal_extra ";
$i = null;
@@ -86,7 +91,7 @@ class Activity extends Controller {
}
$parents_str = ids_to_querystr($i,'item_id');
$items = q("SELECT item.*, item.id AS item_id FROM item WHERE item.parent IN ( %s ) $item_normal ",
dbesc($parents_str)
);
@@ -143,8 +148,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)
@@ -197,8 +202,12 @@ class Activity extends Controller {
}
}
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0
and item.item_delayed = 0 and item.item_blocked = 0 ";
$item_normal_extra = sprintf(" and not verb in ('%s', '%s') ",
dbesc(ACTIVITY_FOLLOW),
dbesc(ACTIVITY_UNFOLLOW)
);
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 $item_normal_extra ";
$sigdata = HTTPSig::verify(EMPTY_STR);
if ($sigdata['portable_id'] && $sigdata['header_valid']) {
@@ -239,6 +248,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

@@ -8,7 +8,6 @@
namespace Zotlabs\Module;
require_once('include/queue_fn.php');
require_once('include/account.php');
/**
@@ -101,11 +100,14 @@ class Admin extends \Zotlabs\Web\Controller {
// pending registrations
$pdg = q("SELECT account.*, register.hash from account left join register on account_id = register.uid where (account_flags & %d ) > 0 ",
intval(ACCOUNT_PENDING)
// $pdg = q("SELECT account.*, register.reg_hash from account left join register on account_id = register.reg_uid // where (account_flags & %d ) > 0 ",
// intval(ACCOUNT_PENDING)
// );
$pdg = q("SELECT COUNT(*) AS pdg FROM register WHERE reg_vital = 1 AND reg_expires > '%s' ",
dbesc(date('Y-m-d H:i:s'))
);
$pending = (($pdg) ? count($pdg) : 0);
$pending = ($pdg ? $pdg[0]['pdg'] : 0);
// available channels, primary and clones
$channels = array();

View File

@@ -5,7 +5,7 @@ namespace Zotlabs\Module\Admin;
class Accounts {
/**
* @brief Handle POST actions on accounts admin page.
*
@@ -15,14 +15,105 @@ class Accounts {
*
*/
const MYP = 'ZAR'; // ZAR2x
const VERSION = '2.0.0';
function post() {
$pending = ( x($_POST, 'pending') ? $_POST['pending'] : array() );
$users = ( x($_POST, 'user') ? $_POST['user'] : array() );
$blocked = ( x($_POST, 'blocked') ? $_POST['blocked'] : array() );
check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts');
$isajax = is_ajax();
$rc = 0;
If (!is_site_admin()) {
if ($isajax) {
killme();
exit;
}
goaway(z_root() . '/');
}
if ($isajax) {
//$debug = print_r($_SESSION[self::MYP],true);
$zarop = (x($_POST['zardo']) && preg_match('/^[ad]{1,1}$/', $_POST['zardo']) )
? $_POST['zardo'] : '';
// zarat arrives with leading underscore _n
$zarat = (x($_POST['zarat']) && preg_match('/^_{1,1}[0-9]{1,6}$/', $_POST['zarat']) )
? substr($_POST['zarat'],1) : '';
$zarse = (x($_POST['zarse']) && preg_match('/^[0-9a-f]{8,8}$/', $_POST['zarse']) )
? hex2bin($_POST['zarse']) : '';
if ($zarop && $zarat >= 0 && $zarse && $zarse == $_SESSION[self::MYP]['h'][$zarat]) {
//
if ($zarop == 'd') {
$rd = q("UPDATE register SET reg_vital = 0 WHERE reg_id = %d AND SUBSTR(reg_hash,1,4) = '%s' ",
intval($_SESSION[self::MYP]['i'][$zarat]),
dbesc($_SESSION[self::MYP]['h'][$zarat])
);
$rc = '×';
}
elseif ($zarop == 'a') {
// approval, REGISTER_DENIED by user 0x0040, REGISTER_AGREED by user 0x0020 @Regate
$rd = q("UPDATE register SET reg_flags = (reg_flags & ~ 16), "
. " reg_vital = (CASE (reg_flags & ~ 48) WHEN 0 THEN 0 ELSE 1 END) "
. " WHERE reg_vital = 1 AND reg_id = %d AND SUBSTR(reg_hash,1,4) = '%s' ",
intval($_SESSION[self::MYP]['i'][$zarat]),
dbesc($_SESSION[self::MYP]['h'][$zarat])
);
$rc = 0;
$rs = q("SELECT * from register WHERE reg_id = %d ",
intval($_SESSION[self::MYP]['i'][$zarat])
);
if ($rs && ($rs[0]['reg_flags'] & ~ 48) == 0) {
// create account
$rc = 'ok'.$rs[0]['reg_id'];
$ac = create_account_from_register($rs[0]);
if ( $ac['success'] ) {
$rc .= '✔';
$auto_create = get_config('system','auto_channel_create',1);
if($auto_create) {
$reonar = json_decode($rs[0]['reg_stuff'], true);
// prepare channel creation
if($reonar['chan.name'])
set_aconfig($ac['account']['account_id'], 'register', 'channel_name', $reonar['chan.name']);
if($reonar['chan.did1'])
set_aconfig($ac['account']['account_id'], 'register', 'channel_address', $reonar['chan.did1']);
$permissions_role = get_config('system','default_permissions_role');
if($permissions_role)
set_aconfig($ac['account']['account_id'], 'register', 'permissions_role', $permissions_role);
// create channel
$new_channel = auto_channel_create($ac['account']['account_id']);
if($new_channel['success']) {
$rc .= ' c,ok' . $new_channel['channel']['channel_id'] . '✔';
}
else {
$rc .= ' c ×';
}
}
}
} else {
$rc='oh ×';
}
}
echo json_encode(array('re' => $zarop, 'at' => '_' . $zarat, 'rc' => $rc));
}
killme();
exit;
}
// change to switch structure?
// account block/unblock button was submitted
if (x($_POST, 'page_accounts_block')) {
@@ -55,7 +146,7 @@ class Accounts {
account_deny($hash);
}
}
goaway(z_root() . '/admin/accounts' );
}
@@ -75,19 +166,21 @@ class Accounts {
$account = q("SELECT * FROM account WHERE account_id = %d",
intval($uid)
);
if (! $account) {
notice( t('Account not found') . EOL);
goaway(z_root() . '/admin/accounts' );
}
check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts', 't');
$debug = '';
switch (argv(2)){
case 'delete':
// delete user
account_remove($uid,true,false);
notice( sprintf(t("Account '%s' deleted"), $account[0]['account_email']) . EOL);
break;
case 'block':
@@ -95,7 +188,7 @@ class Accounts {
intval(ACCOUNT_BLOCKED),
intval($uid)
);
notice( sprintf( t("Account '%s' blocked") , $account[0]['account_email']) . EOL);
break;
case 'unblock':
@@ -103,27 +196,74 @@ class Accounts {
intval(ACCOUNT_BLOCKED),
intval($uid)
);
notice( sprintf( t("Account '%s' unblocked"), $account[0]['account_email']) . EOL);
break;
}
goaway(z_root() . '/admin/accounts' );
}
/* get pending */
$pending = q("SELECT account.*, register.hash from account left join register on account_id = register.uid where (account_flags & %d )>0 ",
intval(ACCOUNT_PENDING)
);
$tao = 'tao.zar.zarax = ' . "'" . '<img src="' . z_root() . '/images/zapax16.gif">' . "';\n";
// by default we will only return verified results. if reg_all is set we will return everything''
$get_all = isset($_REQUEST['get_all']);
$pending = get_pending_accounts($get_all);
unset($_SESSION[self::MYP]);
if ($pending) {
// collect and group all ip
$atips = dbq("SELECT reg_atip AS atip, COUNT(reg_atip) AS atips FROM register
WHERE reg_vital = 1 GROUP BY reg_atip"
);
(($atips) ? $atipn = array_column($atips, 'atips', 'atip') : $atipn = ['' => 0]);
$tao .= 'tao.zar.zarar = {';
foreach ($pending as $n => $v) {
$stuff = json_decode($v['reg_stuff'], true);
if(isset($stuff['msg'])) {
$pending[$n]['msg'] = $stuff['msg'];
}
if (array_key_exists($v['reg_atip'], $atipn)) {
$pending[$n]['reg_atip'] = $v['reg_atip'];
$pending[$n]['reg_atip_n'] = $atipn[$v['reg_atip']];
}
$pending[$n]['status'] = '';
if($pending[$n]['reg_flags'] & ACCOUNT_UNVERIFIED > 0)
$pending[$n]['status'] = [t('Unverified'), 'bg-warning'];
if($pending[$n]['status'] && $pending[$n]['reg_expires'] < datetime_convert())
$pending[$n]['status'] = [t('Expired'), 'bg-danger text-white'];
// timezone adjust date_time for display
$pending[$n]['reg_created'] = datetime_convert('UTC', date_default_timezone_get(), $pending[$n]['reg_created']);
$pending[$n]['reg_startup'] = datetime_convert('UTC', date_default_timezone_get(), $pending[$n]['reg_startup']);
$pending[$n]['reg_expires'] = datetime_convert('UTC', date_default_timezone_get(), $pending[$n]['reg_expires']);
// better secure
$tao .= $n . ": '" . substr(bin2hex($v['reg_hash']),0,8) . "',";
$_SESSION[self::MYP]['h'][] = substr($v['reg_hash'],0,4);
$_SESSION[self::MYP]['i'][] = $v['reg_id'];
}
$tao = rtrim($tao,',') . '};' . "\n";
}
// <- hilmar]
/* get accounts */
$total = q("SELECT count(*) as total FROM account");
if (count($total)) {
\App::set_pager_total($total[0]['total']);
\App::set_pager_itemspage(100);
}
$serviceclass = (($_REQUEST['class']) ? " and account_service_class = '" . dbesc($_REQUEST['class']) . "' " : '');
$key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'account_id');
@@ -134,8 +274,8 @@ class Accounts {
$base = z_root() . '/admin/accounts?f=';
$odir = (($dir === 'asc') ? '0' : '1');
$users = q("SELECT account_id , account_email, account_lastlog, account_created, account_expires, account_service_class, ( account_flags & %d ) > 0 as blocked,
(SELECT %s FROM channel as ch WHERE ch.channel_account_id = ac.account_id and ch.channel_removed = 0 ) as channels FROM account as ac
$users = q("SELECT account_id , account_email, account_lastlog, account_created, account_expires, account_service_class, ( account_flags & %d ) > 0 as blocked,
(SELECT %s FROM channel as ch WHERE ch.channel_account_id = ac.account_id and ch.channel_removed = 0 ) as channels FROM account as ac
where true $serviceclass and account_flags != %d order by $key $dir limit %d offset %d ",
intval(ACCOUNT_BLOCKED),
db_concat('ch.channel_address', ' '),
@@ -143,15 +283,15 @@ class Accounts {
intval(\App::$pager['itemspage']),
intval(\App::$pager['start'])
);
// function _setup_users($e){
// $accounts = Array(
// t('Normal Account'),
// t('Normal Account'),
// t('Soapbox Account'),
// t('Community/Celebrity Account'),
// t('Automatic Friend Account')
// );
// $e['page_flags'] = $accounts[$e['page-flags']];
// $e['register_date'] = relative_date($e['register_date']);
// $e['login_date'] = relative_date($e['login_date']);
@@ -159,49 +299,57 @@ class Accounts {
// return $e;
// }
// $users = array_map("_setup_users", $users);
$t = get_markup_template('admin_accounts.tpl');
$o = replace_macros($t, array(
// strings //
'$debug' => $debug,
'$title' => t('Administration'),
'$page' => t('Accounts'),
'$submit' => t('Submit'),
'$select_all' => t('select all'),
'$h_pending' => t('Registrations waiting for confirm'),
'$th_pending' => array( t('Request date'), t('Email') ),
'$no_pending' => t('No registrations.'),
'$get_all' => (($get_all) ? t('Show verified registrations') : t('Show all registrations')),
'$get_all_link' => (($get_all) ? z_root() .'/admin/accounts' : z_root() .'/admin/accounts?get_all'),
'$sel_tall' => t('Select toggle'),
'$sel_deny' => t('Deny selected'),
'$sel_aprv' => t('Approve selected'),
'$h_pending' => (($get_all) ? t('All registrations') : t('Verified registrations waiting for approval')),
'$th_pending' => array(t('Request date'), 'dId2', t('Email'), 'IP', t('Requests')),
'$no_pending' => (($get_all) ? t('No registrations available') : t('No verified registrations available')),
'$approve' => t('Approve'),
'$deny' => t('Deny'),
'$delete' => t('Delete'),
'$block' => t('Block'),
'$unblock' => t('Unblock'),
'$verified' => t('Verified'),
'$not_verified' => t('Not yet verified'),
'$odir' => $odir,
'$base' => $base,
'$h_users' => t('Accounts'),
'$th_users' => array(
'$th_users' => array(
[ t('ID'), 'account_id' ],
[ t('Email'), 'account_email' ],
[ t('All Channels'), 'channels' ],
[ t('All channels'), 'channels' ],
[ t('Register date'), 'account_created' ],
[ t('Last login'), 'account_lastlog' ],
[ t('Expires'), 'account_expires' ],
[ t('Service Class'), 'account_service_class'] ),
'$confirm_delete_multi' => t('Selected accounts will be deleted!\n\nEverything these accounts had posted on this site will be permanently deleted!\n\nAre you sure?'),
'$confirm_delete' => t('The account {0} will be deleted!\n\nEverything this account has posted on this site will be permanently deleted!\n\nAre you sure?'),
[ t('Service class'), 'account_service_class'] ),
'$confirm_delete_multi' => p2j(t('Selected accounts will be deleted!\n\nEverything these accounts had posted on this site will be permanently deleted!\n\nAre you sure?')),
'$confirm_delete' => p2j(t('The account {0} will be deleted!\n\nEverything this account has posted on this site will be permanently deleted!\n\nAre you sure?')),
'$form_security_token' => get_form_security_token("admin_accounts"),
// values //
'$baseurl' => z_root(),
'$pending' => $pending,
'$users' => $users,
'$baseurl' => z_root(),
'$tao' => $tao,
'$pending' => $pending,
'$users' => $users,
'$msg' => t('Message')
));
$o .= paginate($a);
return $o;
}
}

View File

@@ -173,4 +173,4 @@ class Channels {
return $o;
}
}
}

View File

@@ -2,35 +2,35 @@
namespace Zotlabs\Module\Admin;
use Zotlabs\Lib\Queue as LibQueue;
class Queue {
function get() {
$o = '';
$expert = ((array_key_exists('expert',$_REQUEST)) ? intval($_REQUEST['expert']) : 0);
if($_REQUEST['drophub']) {
hubloc_mark_as_down($_REQUEST['drophub']);
remove_queue_by_posturl($_REQUEST['drophub']);
LibQueue::remove_by_posturl($_REQUEST['drophub']);
}
if($_REQUEST['emptyhub']) {
remove_queue_by_posturl($_REQUEST['emptyhub']);
LibQueue::remove_by_posturl($_REQUEST['emptyhub']);
}
$r = q("select count(outq_posturl) as total, max(outq_priority) as priority, outq_posturl from outq
$r = q("select count(outq_posturl) as total, max(outq_priority) as priority, outq_posturl from outq
where outq_delivered = 0 group by outq_posturl order by total desc");
for($x = 0; $x < count($r); $x ++) {
$r[$x]['eurl'] = urlencode($r[$x]['outq_posturl']);
$r[$x]['connected'] = datetime_convert('UTC',date_default_timezone_get(),$r[$x]['connected'],'Y-m-d');
}
$o = replace_macros(get_markup_template('admin_queue.tpl'), array(
'$banner' => t('Queue Statistics'),
'$numentries' => t('Total Entries'),
@@ -43,11 +43,11 @@ class Queue {
'$entries' => $r,
'$expert' => $expert
));
return $o;
}
}
}

View File

@@ -5,14 +5,25 @@ namespace Zotlabs\Module\Admin;
class Site {
/**
* @brief POST handler for Admin Site Page.
*
*/
function post(){
// [hilmar->
$this->isajax = is_ajax();
$this->eol = $this->isajax ? "\n" : EOL;
// ]
if (!x($_POST, 'page_site')) {
return;
// [
if (!$this->isajax)
// ]
return;
}
// [
$this->msgbg = '';
// <-hilmar]
check_form_security_token_redirectOnErr('/admin/site', 'admin_site');
@@ -24,14 +35,17 @@ class Site {
$siteinfo = ((x($_POST,'siteinfo')) ? trim($_POST['siteinfo']) : '');
$language = ((x($_POST,'language')) ? notags(trim($_POST['language'])) : '');
$theme = ((x($_POST,'theme')) ? notags(trim($_POST['theme'])) : '');
// $theme_mobile = ((x($_POST,'theme_mobile')) ? notags(trim($_POST['theme_mobile'])) : '');
// $site_channel = ((x($_POST,'site_channel')) ? notags(trim($_POST['site_channel'])) : '');
// $theme_mobile = ((x($_POST,'theme_mobile')) ? notags(trim($_POST['theme_mobile'])) : '');
// $site_channel = ((x($_POST,'site_channel')) ? notags(trim($_POST['site_channel'])) : '');
$maximagesize = ((x($_POST,'maximagesize')) ? intval(trim($_POST['maximagesize'])) : 0);
$register_policy = ((x($_POST,'register_policy')) ? intval(trim($_POST['register_policy'])) : 0);
$register_wo_email = ((x($_POST,'register_wo_email')) ? intval(trim($_POST['register_wo_email'])) : 0);
$minimum_age = ((x($_POST,'minimum_age')) ? intval(trim($_POST['minimum_age'])) : 13);
$access_policy = ((x($_POST,'access_policy')) ? intval(trim($_POST['access_policy'])) : 0);
$invite_only = ((x($_POST,'invite_only')) ? True : False);
$reg_autochannel = ((x($_POST,'auto_channel_create')) ? True : False);
$invitation_only = ((x($_POST,'invitation_only')) ? True : False);
$invitation_also = ((x($_POST,'invitation_also')) ? True : False);
$abandon_days = ((x($_POST,'abandon_days')) ? intval(trim($_POST['abandon_days'])) : 0);
$register_text = ((x($_POST,'register_text')) ? notags(trim($_POST['register_text'])) : '');
@@ -75,6 +89,16 @@ class Site {
$maxloadavg = ((x($_POST,'maxloadavg')) ? intval(trim($_POST['maxloadavg'])) : 50);
$feed_contacts = ((x($_POST,'feed_contacts')) ? intval($_POST['feed_contacts']) : 0);
$verify_email = ((x($_POST,'verify_email')) ? 1 : 0);
$register_perday = ((x($_POST,'register_perday')) ? intval(trim($_POST['register_perday'])) : 50);
$register_sameip = ((x($_POST,'register_sameip')) ? intval(trim($_POST['register_sameip'])) : 3);
$regdelayn = ((x($_POST,'zardelayn')) ? intval(trim($_POST['zardelayn'])) : 0);
$regdelayu = ((x($_POST,'zardelay')) ? notags(trim($_POST['zardelay'])) : '');
$reg_delay = (preg_match('/^[a-z]{1,1}$/', $regdelayu) ? $regdelayn . $regdelayu : '');
$regexpiren = ((x($_POST,'zarexpiren')) ? intval(trim($_POST['zarexpiren'])) : 0);
$regexpireu = ((x($_POST,'zarexpire')) ? notags(trim($_POST['zarexpire'])) : '');
$reg_expire = (preg_match('/^[a-z]{1,1}$/', $regexpireu) ? $regexpiren . $regexpireu : '');
$imagick_path = ((x($_POST,'imagick_path')) ? trim($_POST['imagick_path']) : '');
$force_queue = ((intval($_POST['force_queue']) > 0) ? intval($_POST['force_queue']) : 3000);
$pub_incl = escape_tags(trim($_POST['pub_incl']));
@@ -82,6 +106,35 @@ class Site {
$permissions_role = escape_tags(trim($_POST['permissions_role']));
// [hilmar->
$this->register_duty = ((x($_POST,'register_duty')) ? notags(trim($_POST['register_duty'])) : '');
if (! preg_match('/^[0-9 .,:\-]{0,191}$/', $this->register_duty)) {
$this->msgbg .= 'ZAR0131E,' . t('Invalid input') . $this->eol;
$this->error++;
} else {
$this->duty();
if ($this->isajax) {
echo json_encode(array('msgbg' => $this->msgbg, 'me' => 'zar'));
// that mission is complete
killme();
exit;
} else {
//logger( print_r( $this->msgbg, true) );
//logger( print_r( $this->joo, true) );
if ($this->error === 0) {
set_config('system', 'register_duty', $this->register_duty);
set_config('system', 'register_duty_jso', $this->joo);
} else {
notice('ZAR0130E,'.t('Errors') . ': ' . $this->error) . EOL . $this->msgfg;
}
}
}
// <-hilmar]
set_config('system', 'feed_contacts', $feed_contacts);
set_config('system', 'delivery_interval', $delivery_interval);
set_config('system', 'delivery_batch_count', $delivery_batch_count);
@@ -96,6 +149,10 @@ class Site {
set_config('system', 'login_on_homepage', $login_on_homepage);
set_config('system', 'enable_context_help', $enable_context_help);
set_config('system', 'verify_email', $verify_email);
set_config('system', 'max_daily_registrations', $register_perday);
set_config('system', 'register_sameip', $register_sameip);
set_config('system', 'register_delay', $reg_delay);
set_config('system', 'register_expire', $reg_expire);
set_config('system', 'default_expire_days', $default_expire_days);
set_config('system', 'active_expire_days', $active_expire_days);
set_config('system', 'reply_address', $reply_address);
@@ -126,17 +183,20 @@ class Site {
set_config('system','siteinfo',$siteinfo);
set_config('system', 'language', $language);
set_config('system', 'theme', $theme);
// if ( $theme_mobile === '---' ) {
// del_config('system', 'mobile_theme');
// } else {
// set_config('system', 'mobile_theme', $theme_mobile);
// }
// set_config('system','site_channel', $site_channel);
// if ( $theme_mobile === '---' ) {
// del_config('system', 'mobile_theme');
// } else {
// set_config('system', 'mobile_theme', $theme_mobile);
// }
// set_config('system','site_channel', $site_channel);
set_config('system','maximagesize', $maximagesize);
set_config('system','register_policy', $register_policy);
set_config('system','register_wo_email', $register_wo_email);
set_config('system','minimum_age', $minimum_age);
set_config('system','invitation_only', $invite_only);
set_config('system','auto_channel_create', $reg_autochannel);
set_config('system', 'invitation_only', $invitation_only);
set_config('system', 'invitation_also', $invitation_also);
set_config('system','access_policy', $access_policy);
set_config('system','account_abandon_days', $abandon_days);
set_config('system','register_text', $register_text);
@@ -260,6 +320,8 @@ class Site {
REGISTER_APPROVE => t("Yes - with approval"),
REGISTER_OPEN => t("Yes")
);
$this->register_duty = get_config('system', 'register_duty', '-:-');
$register_perday = get_config('system','max_daily_registrations', 50);
/* Acess policy */
$access_choices = Array(
@@ -277,8 +339,8 @@ class Site {
// now invert the logic for the setting.
$discover_tab = (1 - $discover_tab);
$perm_roles = \Zotlabs\Access\PermissionRoles::roles();
$default_role = get_config('system','default_permissions_role','social');
$perm_roles = \Zotlabs\Access\PermissionRoles::channel_roles();
$default_role = get_config('system','default_permissions_role','personal');
$role = array('permissions_role' , t('Default permission role for new accounts'), $default_role, t('This role will be used for the first channel created after registration.'),$perm_roles);
@@ -286,9 +348,66 @@ class Site {
$homelogin = get_config('system','login_on_homepage');
$enable_context_help = get_config('system','enable_context_help');
// for reuse reg_delay and reg_expire
$reg_rabots = array(
'i' => t('Minute(s)'),
'h' => t('Hour(s)') ,
'd' => t('Day(s)') ,
'w' => t('Week(s)') ,
'm' => t('Month(s)') ,
'y' => t('Year(s)')
);
$regdelay_n = $regdelay_u = false;
$regdelay = get_config('system','register_delay');
if ($regdelay)
list($regdelay_n, $regdelay_u) = array(substr($regdelay,0,-1),substr($regdelay,-1));
$reg_delay = replace_macros(get_markup_template('field_duration.qmc.tpl'),
array(
'label' => t('Register verification delay'),
'qmc' => 'zar',
'qmcid' => '',
'help' => t('Time to wait before a registration can be verified'),
'field' => array(
'name' => 'delay',
'title' => t('duration up from now'),
'value' => ($regdelay_n === false ? 0 : $regdelay_n),
'min' => '0',
'max' => '99',
'size' => '2',
'default' => ($regdelay_u === false ? 'i' : $regdelay_u)
),
'rabot' => $reg_rabots
)
);
$regexpire_n = $regexpire_u = false;
$regexpire = get_config('system','register_expire');
if ($regexpire)
list($regexpire_n, $regexpire_u) = array(substr($regexpire,0,-1),substr($regexpire,-1));
$reg_expire = replace_macros(get_markup_template('field_duration.qmc.tpl'),
array(
'label' => t('Register verification expiration time'),
'qmc' => 'zar',
'qmcid' => '',
'help' => t('Time before an unverified registration will expire'),
'field' => array(
'name' => 'expire',
'title' => t('duration up from now'),
'value' => ($regexpire_n === false ? 3 : $regexpire_n),
'min' => '0',
'max' => '99',
'size' => '2',
'default' => ($regexpire_u === false ? 'd' : $regexpire_u)
),
'rabot' => $reg_rabots
)
);
$tao = '';
$t = get_markup_template("admin_site.tpl");
return replace_macros($t, array(
'$title' => t('Administration'),
// interfacing js vars
'$tao' => $tao,
'$page' => t('Site'),
'$submit' => t('Submit'),
'$registration' => t('Registration'),
@@ -305,21 +424,87 @@ class Site {
'$siteinfo' => array('siteinfo', t('Site Information'), get_config('system','siteinfo'), t("Publicly visible description of this site. Displayed on siteinfo page. BBCode can be used here")),
'$language' => array('language', t("System language"), get_config('system','language'), "", $lang_choices),
'$theme' => array('theme', t("System theme"), get_config('system','theme'), t("Default system theme - may be over-ridden by user profiles - <a href='#' id='cnftheme'>change theme settings</a>"), $theme_choices),
// '$theme_mobile' => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile_theme'), t("Theme for mobile devices"), $theme_choices_mobile),
// '$site_channel' => array('site_channel', t("Channel to use for this website's static pages"), get_config('system','site_channel'), t("Site Channel")),
// '$theme_mobile' => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile_theme'), t("Theme for mobile devices"), $theme_choices_mobile),
// '$site_channel' => array('site_channel', t("Channel to use for this website's static pages"), get_config('system','site_channel'), t("Site Channel")),
'$feed_contacts' => array('feed_contacts', t('Allow Feeds as Connections'),get_config('system','feed_contacts'),t('(Heavy system resource usage)')),
'$maximagesize' => array('maximagesize', t("Maximum image size"), intval(get_config('system','maximagesize')), t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")),
'$register_policy' => array('register_policy', t("Does this site allow new member registration?"), get_config('system','register_policy'), "", $register_choices),
'$invite_only' => array('invite_only', t("Invitation only"), get_config('system','invitation_only'), t("Only allow new member registrations with an invitation code. Above register policy must be set to Yes.")),
'$minimum_age' => array('minimum_age', t("Minimum age"), (x(get_config('system','minimum_age'))?get_config('system','minimum_age'):13), t("Minimum age (in years) for who may register on this site.")),
'$access_policy' => array('access_policy', t("Which best describes the types of account offered by this hub?"), get_config('system','access_policy'), t("This is displayed on the public server site list."), $access_choices),
'$register_text' => array('register_text', t("Register text"), htmlspecialchars(get_config('system','register_text'), ENT_QUOTES, 'UTF-8'), t("Will be displayed prominently on the registration page.")),
// Register
// [hilmar->
'$register_text' => [
'register_text',
t("Register text"),
htmlspecialchars(get_config('system','register_text'), ENT_QUOTES, 'UTF-8'),
t("This text will be displayed prominently at the registration page")
],
'$register_policy' => [
'register_policy',
t("Does this site allow new member registration?"),
get_config('system','register_policy'),
"",
$register_choices,
],
'$register_duty' => [
'register_duty',
t('Configure the registration open days/hours'),
get_config('system', 'register_duty', '-:-'),
t('Empty or \'-:-\' value will keep registration open 24/7 (default)') . EOL .
t('Weekdays and hours must be separated by colon \':\', From-To ranges with a dash `-` example: 1:800-1200') . EOL .
t('Weekday:Hour pairs must be separated by space \' \' example: 1:900-1700 2:900-1700') . EOL .
t('From-To ranges must be separated by comma \',\' example: 1:800-1200,1300-1700 or 1-2,4-5:900-1700') . EOL .
t('Advanced examples:') . ' 1-5:0900-1200,1300-1700 6:900-1230 ' . t('or') . ' 1-2,4-5:800-1800<br>' . EOL .
'<a id="zar083a" class="btn btn-sm btn-outline-secondary zuia">' . t('Check your configuration') . '</a>'. EOL
],
'$register_perday' => [
'register_perday',
t('Max account registrations per day'),
get_config('system', 'max_daily_registrations', 50),
t('Unlimited if zero or no value - default 50')
],
'$register_sameip' => [
'register_sameip',
t('Max account registrations from same IP'),
get_config('system', 'register_sameip', 3),
t('Unlimited if zero or no value - default 3')
],
'$reg_delay' => $reg_delay,
'$reg_expire' => $reg_expire,
'$reg_autochannel' => [
'auto_channel_create',
t("Auto channel create"),
get_config('system','auto_channel_create', 1),
t("If disabled the channel will be created in a separate step during the registration process")
],
'$invitation_only' => [
'invitation_only',
t("Require invite code"),
get_config('system', 'invitation_only', 0)
],
'$invitation_also' => [
'invitation_also',
t("Allow invite code"),
get_config('system', 'invitation_also', 0)
],
'$verify_email' => [
'verify_email',
t("Require email address"),
get_config('system','verify_email'),
t("The provided email address will be verified (recommended)")
],
'$abandon_days' => [
'abandon_days',
t('Abandon account after x days'),
get_config('system','account_abandon_days'),
t('Will not waste system resources polling external sites for abandonded accounts. Enter 0 for no time limit.')
],
// <-hilmar]
'$role' => $role,
'$frontpage' => array('frontpage', t("Site homepage to show visitors (default: login box)"), get_config('system','frontpage'), t("example: 'pubstream' to show public stream, 'page/sys/home' to show a system webpage called 'home' or 'include:home.html' to include a file.")),
'$mirror_frontpage' => array('mirror_frontpage', t("Preserve site homepage URL"), get_config('system','mirror_frontpage'), t('Present the site homepage in a frame at the original location instead of redirecting')),
'$abandon_days' => array('abandon_days', t('Accounts abandoned after x days'), get_config('system','account_abandon_days'), t('Will not waste system resources polling external sites for abandonded accounts. Enter 0 for no time limit.')),
'$allowed_sites' => array('allowed_sites', t("Allowed friend domains"), get_config('system','allowed_sites'), t("Comma separated list of domains which are allowed to establish friendships with this site. Wildcards are accepted. Empty to allow any domains")),
'$verify_email' => array('verify_email', t("Verify Email Addresses"), get_config('system','verify_email'), t("Check to verify email addresses used in account registration (recommended).")),
'$force_publish' => array('publish_all', t("Force publish"), get_config('system','publish_all'), t("Check to force all profiles on this site to be listed in the site directory.")),
'$disable_discover_tab' => array('disable_discover_tab', t('Import Public Streams'), $discover_tab, t('Import and allow access to public content pulled from other sites. Warning: this content is unmoderated.')),
'$site_firehose' => array('site_firehose', t('Site only Public Streams'), get_config('system','site_firehose'), t('Allow access to public content originating only from this site if Imported Public Streams are disabled.')),
@@ -350,15 +535,184 @@ class Site {
'$maxloadavg' => array('maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")),
'$default_expire_days' => array('default_expire_days', t('Expiration period in days for imported (grid/network) content'), intval(get_config('system','default_expire_days')), t('0 for no expiration of imported content')),
'$active_expire_days' => array('active_expire_days', t('Do not expire any posts which have comments less than this many days ago'), intval(get_config('system','active_expire_days',7)), ''),
'$sellpage' => array('site_sellpage', t('Public servers: Optional landing (marketing) webpage for new registrants'), get_config('system','sellpage',''), sprintf( t('Create this page first. Default is %s/register'),z_root())),
'$first_page' => array('first_page', t('Page to display after creating a new channel'), get_config('system','workflow_channel_next','profiles'), t('Default: profiles')),
'$location' => array('site_location', t('Optional: site location'), get_config('system','site_location',''), t('Region or country')),
'$form_security_token' => get_form_security_token("admin_site"),
));
}
/**
* @brief Admin page site common post submit and ajax interaction
* @author hilmar runge
* @since 2020-02-04
* Configure register office duty weekdays and hours
* Syntax: weekdays:hours [weekdays:hours]
* [.d[,d-d.]]]:hhmm-hhmm[,hhmm-hhmm...]
* ranges are between blanks, days are 1-7, where 1 = Monday
* hours are [h]hmm 3-4digit 24 clock values
* ie 0900-1200,1300-1800 for hours
* ie 1-2,4,5 for weekdays
* ie 1-2:900-1800 monday and tuesday open from 9 to 18h
*
* @var $register_duty is the input field from the admin -> site page
* @return the results are in the class vars $error, $msgbg and $jsoo
* $jsoo is
*/
// 3-4 digit 24h clock regex
const regxTime34 = '/^(?:2[0-3]|[01][0-9]|[0-9])[0-5][0-9]$/';
var $wdconst = array('','mo','tu','we','th','fr','sa','so');
// in
var $register_duty;
// intermediate
var $isajax;
// return
var $jsoo;
var $msgbg;
var $error = 0;
var $msgfg = '';
private function duty() {
$aro=array_fill(1, 7, 0);
if ($this->isajax) {
$op = (preg_match('/[a-z]{2,4}/', $_REQUEST['zarop'])) ? $_REQUEST['zarop'] : '';
if ($op == 'zar083') {
$this->msgbg = 'Testmode:' . $this->eol . $this->msgbg;
} else {
killme();
exit;
}
}
$ranges = preg_split('/\s+/', $this->register_duty);
$this->msgbg .= '..ranges: ' . print_r(count($ranges),true) . $this->eol;
foreach ($ranges as $rn => $range) {
list($ws,$hs,) = explode(':', $range);
$ws ? $arw = explode( ',', $ws) : $arw=array();
$this->msgbg .= ($rn+1).'.weekday ranges: ' . count($arw) . $this->eol;
// $this->msgbg .= print_r($arw,true);
$hs ? $arh = explode( ',', $hs) : $arh=array();
$this->msgbg .= ($rn+1).'.hour ranges: ' . count($arh) . $this->eol;
$this->msgbg .= ($rn+1).'.wdays: ' . ( $ws ? print_r($ws,true) : 'none') . ' : '
. ' hours: ' . print_r($hs,true) . $this->eol;
// several hs may belog to one wd
// aro[0] is tmp store
foreach ($arh as $hs) {
list($ho,$hc,) = explode( '-', $hs );
// no value forces open very early, and be sure having valid hhmm values
!$ho ? $ho = "0000" : '';
!$hc ? $hc = "0000" : ''; // pseudo
if (preg_match(self::regxTime34, $ho)
&& preg_match(self::regxTime34, $hc)) {
// fix pseudo, allow no reverse range
$hc == "0000" || $ho > $hc ? $hc = "2400" : '';
$aro[0][$ho] = 0;
$aro[0][$hc] = 1;
$this->msgbg .= ($ho ? ' .open:' . $ho : '') . ($hc ? ' close:' . $hc : '') .$this->eol;
} else {
$this->msgbg .= ' .' . t('Invalid 24h time value (hhmm/hmm)') . $this->eol;
$this->msgfg .= ' .ZAR0132E,' . t('Invalid 24h time value (hhmm/hmm)') . $this->eol;
$this->error++;
}
}
// the weekday(s) values or ranges
foreach ($arw as $ds) {
$wd=explode('-', $ds);
array_key_exists("1", $wd) && $wd[1]=="" ? $wd[1] = "7" : ''; // a case 3-
array_key_exists("1", $wd) && $wd[0]=="" ? $wd[0] = "1" : ''; // a case -3
!array_key_exists("1", $wd) ? $wd[1] = $wd[0] : ''; // a case 3
if ($wd[0] > $wd[1]) continue; // reverse order will be ignored // a case 5-3
if (preg_match('/^[1-7]{1}$/', $wd[0])) {
if (preg_match('/^[1-7]{1}$/', $wd[1])) {
// $this->msgbg .= print_r($wd,true);
for ($i=$wd[0]; $i<=$wd[1]; $i++) {
// take the tmp store for the selected day(s)
$aro[$i]=$aro[0];
}
}
}
}
//$this->msgbg .= 'aro0: ' . print_r($aro,true) . $this->eol; // 4devels
// clear the tmp store
$aro[0]=array();
}
// discart the tmp store
unset($aro[0]);
// not configured days close at the beginning 0000h
for ($i=1;$i<=7;$i++) { is_array($aro[$i]) ? '' : $aro[$i] = array("0000" => 1); }
// $this->msgbg .= 'aro: ' . print_r($aro,true) . $this->eol; // 4devels
if ($this->isajax) {
// tell what we have
// $this->msgbg .= 'aro0: ' . print_r($aro,true) . $this->eol; // 4devels
$this->msgbg .= 'Duty time table:' . $this->eol;
foreach ($aro as $dow => $hrs) {
$this->msgbg .= ' ' . $this->wdconst[$dow] . ' ';
// $this->msgbg .= '**' . print_r($hrs,true);
foreach ($hrs as $h => $o) {
$this->msgbg .= ((!$o) ? $h . ':open' : $h . ':close') . ', ';
}
$this->msgbg = rtrim($this->msgbg, ', ') . $this->eol;
}
$this->msgbg .= 'Generating 6 random times to check duty hours: ' . $this->eol;
// we only need some random dates from anyway in past or future
// because only the weekday and the clock is to test
for ($i=0; $i<6; $i++) {
$adow = rand(1, 7); // 1 to 7 (days)
$cdow = $this->wdconst[$adow];
// below is the essential algo to verify a date (of format Hi) meets an open or closed condition
$t = date('Hi', ( rand(time(), 60*60*24+time()) ) );
$how='close';
foreach ($aro[$adow] as $o => $v) {
// $this->msgbg .= 'debug: ' . $o . ' gt ' . $t . ' / ' . $v . $this->eol; // 4devels
if ($o > $t) {
$how = ($v ? 'open' : 'close');
break;
}
}
// now we know
$this->msgbg .= ' ' . $cdow . '.' . $t . '=' . $how . ', ';
}
$this->msgbg = rtrim($this->msgbg, ', ') . $this->eol;
}
/*
//$jov1 = array( 'view1' => $aro, 'view2' => '');
$jov2=array();
foreach ($aro as $d => $ts) {
foreach ($ts as $t => $ft) {
$jov2['view2'][$ft][] = $d.$t;
//$ft=="1" && $t=="0000" ? $jov2['view2']["0"][] = $d."2400" : '';
}
}
$this->msgbg .= print_r($jov2, true) . $this->eol; // 4devels
*/
$this->joo = json_encode($aro);
// $this->msgbg .= $this->joo . $this->eol; // 4devels
// $this->msgbg .= print_r($aro, true) . $this->eol; // 4devels
$okko = (json_decode($this->joo, true) ? true : false);
if (!$okko) {
$this->msgbg .= 'ZAR0139D,json 4 duty KO crash' . $this->eol;
$this->msgfg .= 'ZAR0139D,json 4 duty KO crash' . $this->eol;
$this->error++;
}
return ;
}
}

View File

@@ -44,17 +44,14 @@ class Affinity extends \Zotlabs\Web\Controller {
if(! local_channel())
return;
$desc = t('This app presents a slider control in your connection editor and also on your network page. The slider represents your degree of friendship (affinity) with each connection. It allows you to zoom in or out and display conversations from only your closest friends or everybody in your stream.');
if(! Apps::system_app_installed(local_channel(),'Affinity Tool')) {
if(! Apps::system_app_installed(local_channel(), 'Affinity Tool')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Affinity Tool App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= $desc;
return $o;
$papp = Apps::get_papp('Affinity Tool');
return Apps::app_render($papp, 'module');
}
$text = t('The numbers below represent the minimum and maximum slider default positions for your network/stream page as a percentage.');
$text = t('The numbers below represent the minimum and maximum slider default positions for your network/stream page as a percentage.');
$content = '<div class="section-content-info-wrapper">' . $text . '</div>';

103
Zotlabs/Module/Album.php Normal file
View File

@@ -0,0 +1,103 @@
<?php
namespace Zotlabs\Module;
use App;
use Zotlabs\Web\Controller;
use Zotlabs\Lib\Activity;
use Zotlabs\Lib\ActivityStreams;
use Zotlabs\Lib\Config;
use Zotlabs\Web\HTTPSig;
require_once('include/security.php');
require_once('include/attach.php');
require_once('include/photo/photo_driver.php');
require_once('include/photos.php');
class Album extends Controller {
function init() {
if (ActivityStreams::is_as_request()) {
$sigdata = HTTPSig::verify(EMPTY_STR);
if ($sigdata['portable_id'] && $sigdata['header_valid']) {
$portable_id = $sigdata['portable_id'];
if (!check_channelallowed($portable_id)) {
http_status_exit(403, 'Permission denied');
}
if (!check_siteallowed($sigdata['signer'])) {
http_status_exit(403, 'Permission denied');
}
observer_auth($portable_id);
}
elseif (Config::get('system', 'require_authenticated_fetch', false)) {
http_status_exit(403, 'Permission denied');
}
$observer_xchan = get_observer_hash();
$allowed = false;
$bear = Activity::token_from_request();
if ($bear) {
logger('bear: ' . $bear, LOGGER_DEBUG);
}
$channel = null;
if (argc() > 1) {
$channel = channelx_by_nick(argv(1));
}
if (!$channel) {
http_status_exit(404, 'Not found.');
}
$sql_extra = permissions_sql($channel['channel_id'], $observer_xchan);
if (argc() > 2) {
$folder = argv(2);
$r = q("select * from attach where is_dir = 1 and hash = '%s' and uid = %d $sql_extra limit 1",
dbesc($folder),
intval($channel['channel_id'])
);
$allowed = (($r) ? attach_can_view($channel['channel_id'], $observer_xchan, $r[0]['hash'] /*,$bear */) : false);
}
else {
$folder = EMPTY_STR;
$allowed = perm_is_allowed($channel['channel_id'], $observer_xchan, 'view_storage');
}
if (!$allowed) {
http_status_exit(403, 'Permission denied.');
}
$x = q("select * from attach where folder = '%s' and uid = %d $sql_extra",
dbesc($folder),
intval($channel['channel_id'])
);
$contents = [];
if ($x) {
foreach ($x as $xv) {
if (intval($xv['is_dir'])) {
continue;
}
if (!attach_can_view($channel['channel_id'], $observer_xchan, $xv['hash'] /*,$bear*/)) {
continue;
}
if (intval($xv['is_photo'])) {
$contents[] = z_root() . '/photo/' . $xv['hash'];
}
}
}
$obj = Activity::encode_simple_collection($contents, App::$query_string, 'OrderedCollection', count($contents));
as_return_and_die($obj, $channel);
}
}
}

View File

@@ -1,18 +1,18 @@
<?php /** @file */
namespace Zotlabs\Module;
namespace Zotlabs\Module;
//require_once('include/apps.php');
use \Zotlabs\Lib as Zlib;
use App;
use Zotlabs\Lib\Apps;
use Zotlabs\Lib\Libsync;
class Appman extends \Zotlabs\Web\Controller {
function post() {
if(! local_channel())
return;
if($_POST['url']) {
$arr = array(
'uid' => intval($_REQUEST['uid']),
@@ -32,32 +32,70 @@ class Appman extends \Zotlabs\Web\Controller {
'sig' => escape_tags($_REQUEST['sig']),
'categories' => escape_tags($_REQUEST['categories'])
);
$_REQUEST['appid'] = Zlib\Apps::app_install(local_channel(),$arr);
if(Zlib\Apps::app_installed(local_channel(),$arr))
$_REQUEST['appid'] = Apps::app_install(local_channel(),$arr);
if(Apps::app_installed(local_channel(),$arr))
info( t('App installed.') . EOL);
goaway(z_root() . '/apps');
return; //not reached
}
$papp = Zlib\Apps::app_decode($_POST['papp']);
$papp = Apps::app_decode($_POST['papp']);
if(! is_array($papp)) {
notice( t('Malformed app.') . EOL);
return;
}
if($_POST['install']) {
Zlib\Apps::app_install(local_channel(),$papp);
if(Zlib\Apps::app_installed(local_channel(),$papp))
Apps::app_install(local_channel(),$papp);
if(Apps::app_installed(local_channel(),$papp))
info( t('App installed.') . EOL);
$sync = q("SELECT * FROM app WHERE app_channel = %d AND app_id = '%s' LIMIT 1",
intval(local_channel()),
dbesc($papp['guid'])
);
if (!$sync) {
return;
}
if (intval($sync[0]['app_system'])) {
Libsync::build_sync_packet($uid, ['sysapp' => $sync]);
}
else {
Libsync::build_sync_packet($uid, ['app' => $sync]);
}
}
if($_POST['delete']) {
Zlib\Apps::app_destroy(local_channel(),$papp);
// Fetch the app for sync before it is deleted (if it is deletable))
$sync = q("SELECT * FROM app WHERE app_channel = %d AND app_id = '%s' LIMIT 1",
intval(local_channel()),
dbesc($papp['guid'])
);
if (!$sync) {
return;
}
Apps::app_destroy(local_channel(), $papp);
// Now flag it deleted
$sync[0]['app_deleted'] = 1;
if (intval($sync[0]['app_system'])) {
Libsync::build_sync_packet($uid, ['sysapp' => $sync]);
}
else {
Libsync::build_sync_packet($uid, ['app' => $sync]);
}
}
if($_POST['edit']) {
@@ -65,37 +103,65 @@ class Appman extends \Zotlabs\Web\Controller {
}
if($_POST['feature']) {
Zlib\Apps::app_feature(local_channel(), $papp, $_POST['feature']);
Apps::app_feature(local_channel(), $papp, $_POST['feature']);
$sync = q("SELECT * FROM app WHERE app_channel = %d AND app_id = '%s' LIMIT 1",
intval(local_channel()),
dbesc($papp['guid'])
);
if (intval($sync[0]['app_system'])) {
Libsync::build_sync_packet($uid, ['sysapp' => $sync]);
}
else {
Libsync::build_sync_packet($uid, ['app' => $sync]);
}
}
if($_POST['pin']) {
Zlib\Apps::app_feature(local_channel(), $papp, $_POST['pin']);
Apps::app_feature(local_channel(), $papp, $_POST['pin']);
$sync = q("SELECT * FROM app WHERE app_channel = %d AND app_id = '%s' LIMIT 1",
intval(local_channel()),
dbesc($papp['guid'])
);
if (intval($sync[0]['app_system'])) {
Libsync::build_sync_packet($uid, ['sysapp' => $sync]);
}
else {
Libsync::build_sync_packet($uid, ['app' => $sync]);
}
}
if($_SESSION['return_url'])
if($_POST['aj']) {
killme();
}
if($_SESSION['return_url'])
goaway(z_root() . '/' . $_SESSION['return_url']);
goaway(z_root() . '/apps');
}
function get() {
if(! local_channel()) {
notice( t('Permission denied.') . EOL);
return;
}
$channel = \App::get_channel();
$channel = App::get_channel();
if(argc() > 3) {
if(argv(2) === 'moveup') {
Zlib\Apps::moveup(local_channel(),argv(1),argv(3));
Apps::moveup(local_channel(),argv(1),argv(3));
}
if(argv(2) === 'movedown') {
Zlib\Apps::movedown(local_channel(),argv(1),argv(3));
Apps::movedown(local_channel(),argv(1),argv(3));
}
goaway(z_root() . '/apporder');
}
@@ -129,12 +195,12 @@ class Appman extends \Zotlabs\Web\Controller {
}
}
$embed = array('embed', t('Embed code'), Zlib\Apps::app_encode($app,true),'', 'onclick="this.select();"');
$embed = array('embed', t('Embed code'), Apps::app_encode($app,true),'', 'onclick="this.select();"');
}
return replace_macros(get_markup_template('app_create.tpl'), array(
'$banner' => (($app) ? t('Edit App') : t('Create App')),
'$app' => $app,
'$guid' => (($app) ? $app['app_id'] : ''),
@@ -154,7 +220,7 @@ class Appman extends \Zotlabs\Web\Controller {
'$embed' => $embed,
'$submit' => t('Submit')
));
}
}

View File

@@ -9,7 +9,7 @@ class Apps extends \Zotlabs\Web\Controller {
function get() {
nav_set_selected('Apps');
if(argc() == 2 && argv(1) == 'edit')
$mode = 'edit';
else
@@ -18,9 +18,9 @@ class Apps extends \Zotlabs\Web\Controller {
$available = ((argc() == 2 && argv(1) === 'available') ? true : false);
$_SESSION['return_url'] = \App::$query_string;
$apps = array();
if(local_channel()) {
Zlib\Apps::import_system_apps();
$syslist = array();
@@ -37,9 +37,9 @@ class Apps extends \Zotlabs\Web\Controller {
$syslist = Zlib\Apps::get_system_apps(true);
usort($syslist,'Zotlabs\\Lib\\Apps::app_name_compare');
// logger('apps: ' . print_r($syslist,true));
foreach($syslist as $app) {
$apps[] = Zlib\Apps::app_render($app,(($available) ? 'install' : $mode));
}
@@ -53,7 +53,7 @@ class Apps extends \Zotlabs\Web\Controller {
'$manage' => (($available) ? '' : t('Manage Apps')),
'$create' => (($mode == 'edit') ? t('Create Custom App') : '')
));
}
}

View File

@@ -14,7 +14,7 @@ class Apschema extends \Zotlabs\Web\Controller {
'zot' => z_root() . '/apschema#',
'id' => '@id',
'type' => '@type',
'commentPolicy' => 'as:commentPolicy',
'commentPolicy' => 'zot:commentPolicy',
'meData' => 'zot:meData',
'meDataType' => 'zot:meDataType',
'meEncoding' => 'zot:meEncoding',
@@ -33,6 +33,9 @@ class Apschema extends \Zotlabs\Web\Controller {
'PropertyValue' => 'schema:PropertyValue',
'value' => 'schema:value',
'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers',
'magicEnv' => [
'@id' => 'zot:magicEnv',
'@type' => '@id'
@@ -50,7 +53,7 @@ class Apschema extends \Zotlabs\Web\Controller {
'guid' => 'diaspora:guid',
'Hashtag' => 'as:Hashtag'
]
];

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 .= ', ';
@@ -85,7 +85,6 @@ class Article_edit extends \Zotlabs\Web\Controller {
$mimetype = $itm[0]['mimetype'];
$summary = (($itm[0]['summary']) ? '[summary]' . $itm[0]['summary'] . '[/summary]' . "\r\n" : '');
$content = $itm[0]['body'];
$rp = 'articles/' . $channel['channel_address'];
@@ -109,10 +108,11 @@ class Article_edit extends \Zotlabs\Web\Controller {
'ptyp' => $itm[0]['type'],
'mimeselect' => false,
'mimetype' => $itm[0]['mimetype'],
'body' => $summary . undo_post_tagging($content),
'body' => undo_post_tagging($content),
'post_id' => $post_id,
'visitor' => true,
'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'),
'summary' => htmlspecialchars($itm[0]['summary'],ENT_COMPAT,'UTF-8'),
'placeholdertitle' => t('Title (optional)'),
'pagetitle' => $card_title,
'profile_uid' => (intval($channel['channel_id'])),

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();
}
@@ -48,15 +48,13 @@ class Articles extends Controller {
if(! Apps::system_app_installed(App::$profile_uid, 'Articles')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Articles App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('Create interactive articles');
return $o;
$papp = Apps::get_papp('Articles');
return Apps::app_render($papp, 'module');
}
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 +63,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 +72,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 +103,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 +112,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 +144,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 +173,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 +211,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,61 +1,188 @@
<?php
namespace Zotlabs\Module;
use ZipArchive;
use Zotlabs\Web\Controller;
use Zotlabs\Lib\Verify;
require_once('include/security.php');
require_once('include/attach.php');
class Attach extends Controller {
class Attach extends \Zotlabs\Web\Controller {
function post() {
function init() {
if(argc() < 2) {
notice( t('Item not available.') . EOL);
$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);
if (!$channel) {
notice(t('Channel not found.') . EOL);
return;
}
$r = attach_by_hash(argv(1),get_observer_hash(),((argc() > 2) ? intval(argv(2)) : 0));
if(! $r['success']) {
notice( $r['message'] . EOL);
$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))
mkdir($zip_dir, STORAGE_DEFAULT_PERMISSIONS, true);
$token = random_string(32);
$zip_file = 'download_' . $token . '.zip';
$zip_path = $zip_dir . '/' . $zip_file;
$zip = new ZipArchive();
if ($zip->open($zip_path, ZipArchive::CREATE) === true) {
$zip_filename = self::zip_archive_handler($zip, $attach_ids, $attach_path);
$zip->close();
$meta = [
'zip_filename' => $zip_filename,
'zip_path' => $zip_path
];
Verify::create('zip_token', 0, $token, json_encode($meta));
json_return_and_die([
'success' => true,
'token' => $token
]);
}
}
}
function get() {
if (argc() < 2) {
notice(t('Item not available.') . EOL);
return;
}
$token = ((x($_REQUEST, 'token')) ? $_REQUEST['token'] : '');
if (argv(1) === 'download') {
$meta = Verify::get_meta('zip_token', 0, $token);
if (!$meta)
killme();
$meta = json_decode($meta, true);
header('Content-Type: application/zip');
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) {
pipe_streams($istream, $ostream);
fclose($istream);
fclose($ostream);
}
unlink($meta['zip_path']);
killme();
}
$r = attach_by_hash(argv(1), get_observer_hash(), ((argc() > 2) ? intval(argv(2)) : 0));
if (!$r['success']) {
notice($r['message'] . EOL);
return;
}
$c = q("select channel_address from channel where channel_id = %d limit 1",
intval($r['data']['uid'])
);
if(! $c)
if (!$c)
return;
$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');
$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');
}
else {
header('Content-type: ' . $r['data']['filetype']);
header('Content-Type: ' . $r['data']['filetype']);
}
header('Content-disposition: attachment; filename="' . $r['data']['filename'] . '"');
if(intval($r['data']['os_storage'])) {
$fname = dbunescbin($r['data']['content']);
if(strpos($fname,'store') !== false)
$istream = fopen($fname,'rb');
header('Content-Disposition: attachment; filename="' . $r['data']['filename'] . '"');
if (intval($r['data']['os_storage'])) {
$fname = $r['data']['content'];
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) {
pipe_streams($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);
}
}
else
echo dbunescbin($r['data']['content']);
echo $r['data']['content'];
killme();
}
public function zip_archive_handler($zip, $attach_ids, $attach_path, $pass = 1) {
$observer_hash = get_observer_hash();
$single = ((count($attach_ids) == 1) ? true : false);
$download_name = 'download.zip';
foreach ($attach_ids as $attach_id) {
$r = attach_by_id($attach_id, $observer_hash);
if (!$r['success']) {
continue;
}
if ($r['data']['is_dir'] && $single && $pass === 1)
$download_name = $r['data']['filename'] . '.zip';
$zip_path = $r['data']['display_path'];
if ($attach_path) {
$strip_str = $attach_path . '/';
$count = strlen($strip_str);
$zip_path = substr($r['data']['display_path'], $count);
}
if ($r['data']['is_dir']) {
$zip->addEmptyDir($zip_path);
$d = q("SELECT id FROM attach WHERE folder = '%s'",
dbesc($r['data']['hash'])
);
$attach_ids = ids_to_array($d);
self::zip_archive_handler($zip, $attach_ids, $attach_path, $pass++);
}
else {
$file_path = $r['data']['content'];
$zip->addFile($file_path, $zip_path);
// compressing can be ressource intensive - just store the data
$zip->setCompressionName($zip_path, ZipArchive::CM_STORE);
}
}
return $download_name;
}
}

View File

@@ -0,0 +1,203 @@
<?php
namespace Zotlabs\Module;
/**
* @file Zotlabs/Module/Attach_edit.php
*
*/
use App;
use Zotlabs\Web\Controller;
use Zotlabs\Lib\Libsync;
use Zotlabs\Access\AccessList;
class Attach_edit extends Controller {
function post() {
if (!local_channel() && !remote_channel()) {
return;
}
$attach_ids = ((x($_POST, 'attach_ids')) ? $_POST['attach_ids'] : []);
$attach_id = ((x($_POST, 'attach_id')) ? intval($_POST['attach_id']) : 0);
$channel_id = ((x($_POST, 'channel_id')) ? intval($_POST['channel_id']) : 0);
$dnd = ((x($_POST, 'dnd')) ? intval($_POST['dnd']) : 0);
$permissions = ((x($_POST, 'permissions')) ? intval($_POST['permissions']) : 0);
$return_path = ((x($_POST, 'return_path')) ? notags($_POST['return_path']) : 'cloud');
$delete = ((x($_POST, 'delete')) ? intval($_POST['delete']) : 0);
$newfolder = ((x($_POST, 'newfolder_' . $attach_id)) ? notags($_POST['newfolder_' . $attach_id]) : '');
if(! $newfolder)
$newfolder = ((x($_POST, 'newfolder')) ? notags($_POST['newfolder']) : '');
$newfilename = ((x($_POST, 'newfilename_' . $attach_id)) ? notags($_POST['newfilename_' . $attach_id]) : '');
$recurse = ((x($_POST, 'recurse_' . $attach_id)) ? intval($_POST['recurse_' . $attach_id]) : 0);
if(! $recurse)
$recurse = ((x($_POST, 'recurse')) ? intval($_POST['recurse']) : 0);
$notify = ((x($_POST, 'notify_edit_' . $attach_id)) ? intval($_POST['notify_edit_' . $attach_id]) : 0);
$copy = ((x($_POST, 'copy_' . $attach_id)) ? intval($_POST['copy_' . $attach_id]) : 0);
if(! $copy)
$copy = ((x($_POST, 'copy')) ? intval($_POST['copy']) : 0);
$categories = ((x($_POST, 'categories_' . $attach_id)) ? notags($_POST['categories_' . $attach_id]) : '');
if(! $categories)
$categories = ((x($_POST, 'categories')) ? notags($_POST['categories']) : '');
if($attach_id)
$attach_ids[] = $attach_id;
$single = ((count($attach_ids) === 1) ? true : false);
$channel = channelx_by_n($channel_id);
if (! $channel) {
notice(t('Channel not found.') . EOL);
return;
}
$nick = $channel['channel_address'];
$observer = App::get_observer();
$observer_hash = (($observer) ? $observer['xchan_hash'] : '');
$is_owner = ((local_channel() == $channel_id) ? true : false);
$ids_str = implode(',', $attach_ids);
$r = q("SELECT id, uid, hash, creator, folder, filename, is_photo, is_dir FROM attach WHERE id IN ( %s ) AND uid = %d",
dbesc($ids_str),
intval($channel_id)
);
if (! $r) {
notice(t('File not found.') . EOL);
return;
}
foreach ($r as $rr) {
$actions_done = '';
$attach_id = $rr['id'];
$resource = $rr['hash'];
$creator = $rr['creator'];
$folder = $rr['folder'];
$filename = $rr['filename'];
$is_photo = intval($rr['is_photo']);
$is_dir = intval($rr['is_dir']);
$admin_delete = false;
$is_creator = (($creator == $observer_hash) ? true : false);
$move = ((! $copy && ($folder !== $newfolder || (($single) ? $filename !== $newfilename : false))) ? true : false);
$perms = get_all_perms($channel_id, $observer_hash);
if (! ($perms['view_storage'] || is_site_admin())) {
notice( t('Permission denied.') . EOL);
continue;
}
if (! $perms['write_storage']) {
if (is_site_admin()) {
$admin_delete = true;
}
else {
notice( t('Permission denied.') . EOL);
continue;
}
}
if (!$is_owner && !$admin_delete) {
if(! $is_creator) {
notice( t('Permission denied.') . EOL);
continue;
}
}
if ($delete) {
attach_delete($channel_id, $resource, $is_photo);
$actions_done .= 'delete,';
}
if ($copy) {
if($is_dir && $resource == $newfolder) {
notice( t('Can not copy folder into itself.') . EOL);
continue;
}
$x = attach_copy($channel_id, $resource, $newfolder, (($single) ? $newfilename : ''));
if ($x['success'])
$resource = $x['resource_id'];
$actions_done .= 'copy,';
}
if ($move) {
if($is_dir && $resource == $newfolder) {
notice( sprintf(t('Can not move folder "%s" into itself.'), $filename) . EOL);
continue;
}
$x = attach_move($channel_id, $resource, $newfolder, (($single) ? $newfilename : ''));
$actions_done .= 'move,';
}
if(! $delete && ! $dnd) {
if ($single || (! $single && $categories)) {
q("DELETE FROM term WHERE uid = %d AND oid = %d AND otype = %d",
intval($channel_id),
intval($attach_id),
intval(TERM_OBJ_FILE)
);
$cat = explode(',', $categories);
if ($cat) {
foreach($cat as $term) {
$term = trim(escape_tags($term));
if ($term) {
$term_link = z_root() . '/cloud/' . $nick . '/?cat=' . $term;
store_item_tag($channel_id, $attach_id, TERM_OBJ_FILE, TERM_CATEGORY, $term, $term_link);
}
}
$actions_done .= 'cat_add,';
}
}
else {
q("DELETE FROM term WHERE uid = %d AND oid = %d AND otype = %d",
intval($channel_id),
intval($attach_id),
intval(TERM_OBJ_FILE)
);
$actions_done .= 'cat_remove,';
}
if ($is_owner && ($single || (! $single && $permissions))) {
$acl = new AccessList($channel);
$acl->set_from_array($_REQUEST);
$x = $acl->get();
attach_change_permissions($channel_id, $resource, $x['allow_cid'], $x['allow_gid'], $x['deny_cid'], $x['deny_gid'], $recurse, true);
$actions_done .= 'permissions,';
if ($notify) {
attach_store_item($channel, $observer, $resource);
$actions_done .= 'notify,';
}
}
}
if (! $admin_delete && $actions_done) {
$sync = attach_export_data($channel, $resource, (($delete) ? true : false));
if ($sync) {
Libsync::build_sync_packet($channel_id, ['file' => [$sync]]);
}
}
logger('attach_edit: ' . $actions_done);
}
if($dnd || $delete) {
json_return_and_die([ 'success' => true ]);
}
goaway($return_path);
}
}

View File

@@ -1,41 +1,38 @@
<?php
namespace Zotlabs\Module;
require_once('include/zot.php');
class Authtest extends \Zotlabs\Web\Controller {
function get() {
$auth_success = false;
$o .= '<h3>Magic-Auth Diagnostic</h3>';
if(! local_channel()) {
notice( t('Permission denied.') . EOL);
return $o;
}
$o .= '<form action="authtest" method="get">';
$o .= 'Target URL: <input type="text" style="width: 250px;" name="dest" value="' . $_GET['dest'] .'" />';
$o .= '<input type="submit" name="submit" value="Submit" /></form>';
$o .= '<input type="submit" name="submit" value="Submit" /></form>';
$o .= '<br /><br />';
if(x($_GET,'dest')) {
if(strpos($_GET['dest'],'@')) {
$_GET['dest'] = $_REQUEST['dest'] = 'https://' . substr($_GET['dest'],strpos($_GET['dest'],'@')+1) . '/channel/' . substr($_GET['dest'],0,strpos($_GET['dest'],'@'));
}
$_REQUEST['test'] = 1;
$mod = new Magic();
$x = $mod->init($a);
$o .= 'Local Setup returns: ' . print_r($x,true);
if($x['url']) {
$z = z_fetch_url($x['url'] . '&test=1');
if($z['success']) {
@@ -50,12 +47,12 @@ class Authtest extends \Zotlabs\Web\Controller {
$o .= 'fetch url failure.' . print_r($z,true);
}
}
if(! $auth_success)
$o .= 'Authentication Failed!' . EOL;
}
return str_replace("\n",'<br />',$o);
}
}

View File

@@ -16,33 +16,33 @@ class Bookmarks extends \Zotlabs\Web\Controller {
nav_set_selected('Bookmarks');
$item_id = intval($_REQUEST['item']);
$burl = trim($_REQUEST['burl']);
$item_id = (isset($_REQUEST['item']) ? $_REQUEST['item'] : false);
$burl = (isset($_REQUEST['burl']) ? trim($_REQUEST['burl']) : '');
if(! $item_id)
return;
$u = \App::get_channel();
$item_normal = item_normal();
$i = q("select * from item where id = %d and uid = %d $item_normal limit 1",
intval($item_id),
intval(local_channel())
);
if(! $i)
return;
$i = fetch_post_tags($i);
$item = $i[0];
$terms = get_terms_oftype($item['term'],TERM_BOOKMARK);
$terms = (x($item, 'term') ? get_terms_oftype($item['term'],TERM_BOOKMARK) : false);
if($terms) {
require_once('include/bookmarks.php');
$s = q("select * from xchan where xchan_hash = '%s' limit 1",
dbesc($item['author_xchan'])
);
@@ -58,13 +58,13 @@ class Bookmarks extends \Zotlabs\Web\Controller {
}
else
bookmark_add($u,$s[0],$t,$item['item_private']);
info( t('Bookmark added') . EOL);
}
}
killme();
}
function get() {
if(! local_channel()) {
notice( t('Permission denied.') . EOL);
@@ -74,49 +74,47 @@ class Bookmarks extends \Zotlabs\Web\Controller {
if(! Apps::system_app_installed(local_channel(), 'Bookmarks')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Bookmarks App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('Bookmark links from posts and manage them');
return $o;
$papp = Apps::get_papp('Bookmarks');
return Apps::app_render($papp, 'module');
}
require_once('include/menu.php');
require_once('include/conversation.php');
$channel = \App::get_channel();
$o = '';
$o .= '<div class="generic-content-wrapper-styled">';
$o .= '<h3>' . t('My Bookmarks') . '</h3>';
$o .= '<h3>' . t('Bookmarks') . '</h3>';
$x = menu_list(local_channel(),'',MENU_BOOKMARK);
if($x) {
foreach($x as $xx) {
$y = menu_fetch($xx['menu_name'],local_channel(),get_observer_hash());
$o .= menu_render($y,'',true);
}
}
$o .= '<h3>' . t('My Connections Bookmarks') . '</h3>';
$x = menu_list(local_channel(),'',MENU_SYSTEM|MENU_BOOKMARK);
if($x) {
foreach($x as $xx) {
$y = menu_fetch($xx['menu_name'],local_channel(),get_observer_hash());
$o .= menu_render($y,'',true);
}
}
$o .= '</div>';
return $o;
}
}

View File

@@ -19,47 +19,45 @@ class Cal extends Controller {
if(observer_prohibited()) {
return;
}
if(argc() > 1) {
$nick = argv(1);
profile_load($nick);
$channelx = channelx_by_nick($nick);
if(! $channelx) {
notice( t('Channel not found.') . EOL);
return;
}
App::$data['channel'] = $channelx;
$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>" ;
}
return;
}
function get() {
if(observer_prohibited()) {
return;
}
$channel = App::$data['channel'];
// since we don't currently have an event permission - use the stream permission
if(! perm_is_allowed($channel['channel_id'], get_observer_hash(), 'view_stream')) {
notice( t('Permissions denied.') . EOL);
return;
@@ -78,10 +76,10 @@ class Cal extends Controller {
if(! perm_is_allowed($channel['channel_id'], get_observer_hash(), 'view_contacts') || App::$profile['hide_friends'])
$sql_extra .= " and etype != 'birthday' ";
$first_day = feature_enabled($channel['channel_id'], 'cal_first_day');
$first_day = (($first_day) ? $first_day : 0);
$start = '';
$finish = '';
@@ -89,7 +87,7 @@ class Cal extends Controller {
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);
@@ -109,10 +107,10 @@ class Cal extends Controller {
// Noting this for now - it will need to be fixed here and in Friendica.
// Ultimately the finish date shouldn't be involved in the query.
$r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan, item.id as item_id
from event left join item on event.event_hash = item.resource_id
where item.resource_type = 'event' and event.uid = %d and event.uid = item.uid
AND (( event.adjust = 0 AND ( event.dtend >= '%s' or event.nofinish = 1 ) AND event.dtstart <= '%s' )
OR ( event.adjust = 1 AND ( event.dtend >= '%s' or event.nofinish = 1 ) AND event.dtstart <= '%s' ))
from event left join item on event.event_hash = item.resource_id
where item.resource_type = 'event' and event.uid = %d and event.uid = item.uid
AND (( event.adjust = 0 AND ( event.dtend >= '%s' or event.nofinish = 1 ) AND event.dtstart <= '%s' )
OR ( event.adjust = 1 AND ( event.dtend >= '%s' or event.nofinish = 1 ) AND event.dtstart <= '%s' ))
$sql_extra",
intval($channel['channel_id']),
dbesc($start),
@@ -121,7 +119,7 @@ class Cal extends Controller {
dbesc($adjust_finish)
);
}
if($r) {
xchan_query($r);
$r = fetch_post_tags($r,true);
@@ -129,20 +127,16 @@ class Cal extends Controller {
}
$events = [];
if($r) {
foreach($r as $rr) {
$tz = get_iconfig($rr, 'event', 'timezone');
if(! $tz)
$tz = 'UTC';
$start = (($rr['adjust']) ? datetime_convert($tz, date_default_timezone_get(), $rr['dtstart'], 'c') : datetime_convert('UTC', 'UTC', $rr['dtstart'], 'c'));
$start = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['dtstart'], 'c') : datetime_convert('UTC', 'UTC', $rr['dtstart'], 'c'));
if ($rr['nofinish']){
$end = null;
} else {
$end = (($rr['adjust']) ? datetime_convert($tz, date_default_timezone_get(), $rr['dtend'], 'c') : datetime_convert('UTC', 'UTC', $rr['dtend'], 'c'));
$end = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['dtend'], 'c') : datetime_convert('UTC', 'UTC', $rr['dtend'], 'c'));
}
$html = '';
@@ -151,6 +145,10 @@ class Cal extends Controller {
$html = format_event_html($rr);
}
$tz = get_iconfig($rr, 'event', 'timezone');
if(! $tz)
$tz = 'UTC';
$events[] = array(
'calendar_id' => 'channel_calendar',
'rw' => true,
@@ -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'),
@@ -180,7 +178,7 @@ class Cal extends Controller {
echo json_encode($events);
killme();
}
if (x($_GET,'id')) {
$o = replace_macros(get_markup_template("cal_event.tpl"), [
'$events' => $events
@@ -205,14 +203,14 @@ class Cal extends Controller {
'$prev' => t('Previous'),
'$next' => t('Next'),
'$today' => t('Today'),
'$title' => $title,
'$dtstart' => $dtstart,
'$dtend' => $dtend,
'$title' => '',
'$dtstart' => '',
'$dtend' => '',
'$nick' => $nick
]);
return $o;
}
}

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

@@ -47,10 +47,8 @@ class Cards extends Controller {
if(! Apps::system_app_installed(App::$profile_uid, 'Cards')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Cards App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('Create personal planning cards');
return $o;
$papp = Apps::get_papp('Cards');
return Apps::app_render($papp, 'module');
}
nav_set_selected('Cards');
@@ -110,7 +108,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

@@ -5,6 +5,9 @@ use App;
use Zotlabs\Lib\Apps;
use Zotlabs\Web\Controller;
use Zotlabs\Web\HTTPSig;
use Zotlabs\Lib\Libzot;
use Zotlabs\Lib\Libsync;
require_once('include/event.php');
@@ -47,11 +50,12 @@ class Cdav extends Controller {
if($sigblock) {
$keyId = str_replace('acct:','',$sigblock['keyId']);
if($keyId) {
$r = q("select * from hubloc where hubloc_addr = '%s' limit 1",
$r = q("select * from hubloc where hubloc_id_url = '%s'",
dbesc($keyId)
);
if($r) {
$c = channelx_by_hash($r[0]['hubloc_hash']);
$r = Libzot::zot_record_preferred($r);
$c = channelx_by_hash($r['hubloc_hash']);
if($c) {
$a = q("select * from account where account_id = %d limit 1",
intval($c['channel_account_id'])
@@ -131,7 +135,7 @@ class Cdav extends Controller {
$auth = new \Zotlabs\Storage\BasicAuth();
$auth->setRealm(ucfirst(\Zotlabs\Lib\System::get_platform_name()) . 'CalDAV/CardDAV');
if (local_channel()) {
if(local_channel()) {
logger('loggedin');
@@ -149,36 +153,39 @@ class Cdav extends Controller {
$auth->observer = $channel['channel_hash'];
$principalUri = 'principals/' . $channel['channel_address'];
if(!cdav_principal($principalUri)) {
if(! cdav_principal($principalUri)) {
$this->activate($pdo, $channel);
if(!cdav_principal($principalUri)) {
if(! cdav_principal($principalUri)) {
return;
}
}
}
// Track CDAV updates from remote clients
$httpmethod = $_SERVER['REQUEST_METHOD'];
$httpmethod = $_SERVER['REQUEST_METHOD'];
if($httpmethod === 'PUT' || $httpmethod === 'DELETE') {
$channel = channelx_by_nick(argv(2));
$principalUri = 'principals/' . $channel['channel_address'];
$httpuri = $_SERVER['REQUEST_URI'];
logger("debug: method: " . $httpmethod, LOGGER_DEBUG);
logger("debug: uri: " . $httpuri, LOGGER_DEBUG);
if(strpos($httpuri, 'cdav/addressbooks')) {
if(strpos($httpuri, 'cdav/addressbooks') !== false) {
$sync = 'addressbook';
$cdavtable = 'addressbooks';
}
elseif(strpos($httpuri, 'cdav/calendars')) {
elseif(strpos($httpuri, 'cdav/calendars') !== false) {
$sync = 'calendar';
$cdavtable = 'calendarinstances';
}
else
else {
$sync = false;
}
if($sync) {
@@ -187,37 +194,36 @@ class Cdav extends Controller {
logger("debug: body: " . $httpbody, LOGGER_DEBUG);
if($x = get_cdav_id($principalUri, explode("/", $httpuri)[4], $cdavtable)) {
if($x = get_cdav_id($principalUri, argv(3), $cdavtable)) {
$cdavdata = $this->get_cdav_data($x['id'], $cdavtable);
$etag = (isset($_SERVER['HTTP_IF_MATCH']) ? $_SERVER['HTTP_IF_MATCH'] : false);
// delete
if($httpmethod === 'DELETE' && $cdavdata['etag'] == $etag)
build_sync_packet($channel['channel_id'], [
if($httpmethod === 'DELETE' && $cdavdata['etag'] == $etag) {
Libsync::build_sync_packet($channel['channel_id'], [
$sync => [
'action' => 'delete_card',
'uri' => $cdavdata['uri'],
'carduri' => $uri
]
]);
}
else {
if($etag) {
if($etag && $cdavdata['etag'] !== $etag) {
// update
if($cdavdata['etag'] !== $etag)
build_sync_packet($channel['channel_id'], [
$sync => [
'action' => 'update_card',
'uri' => $cdavdata['uri'],
'carduri' => $uri,
'card' => $httpbody
]
]);
Libsync::build_sync_packet($channel['channel_id'], [
$sync => [
'action' => 'update_card',
'uri' => $cdavdata['uri'],
'carduri' => $uri,
'card' => $httpbody
]
]);
}
else {
// new
build_sync_packet($channel['channel_id'], [
Libsync::build_sync_packet($channel['channel_id'], [
$sync => [
'action' => 'import',
'uri' => $cdavdata['uri'],
@@ -231,7 +237,6 @@ class Cdav extends Controller {
}
}
$principalBackend = new \Sabre\DAVACL\PrincipalBackend\PDO($pdo);
$carddavBackend = new \Sabre\CardDAV\Backend\PDO($pdo);
$caldavBackend = new \Sabre\CalDAV\Backend\PDO($pdo);
@@ -264,7 +269,7 @@ class Cdav extends Controller {
// Plugins
$server->addPlugin(new \Sabre\DAV\Auth\Plugin($auth));
//$server->addPlugin(new \Sabre\DAV\Browser\Plugin());
// $server->addPlugin(new \Sabre\DAV\Browser\Plugin());
$server->addPlugin(new \Sabre\DAV\Sync\Plugin());
$server->addPlugin(new \Sabre\DAV\Sharing\Plugin());
$server->addPlugin(new \Sabre\DAVACL\Plugin());
@@ -272,7 +277,7 @@ class Cdav extends Controller {
// CalDAV plugins
$server->addPlugin(new \Sabre\CalDAV\Plugin());
$server->addPlugin(new \Sabre\CalDAV\SharingPlugin());
//$server->addPlugin(new \Sabre\CalDAV\Schedule\Plugin());
// $server->addPlugin(new \Sabre\CalDAV\Schedule\Plugin());
$server->addPlugin(new \Sabre\CalDAV\ICSExportPlugin());
// CardDAV plugins
@@ -280,7 +285,7 @@ class Cdav extends Controller {
$server->addPlugin(new \Sabre\CardDAV\VCFExportPlugin());
// And off we go!
$server->exec();
$server->start();
killme();
@@ -337,7 +342,7 @@ class Cdav extends Controller {
// set new calendar to be visible
set_pconfig(local_channel(), 'cdav_calendar' , $id[0], 1);
build_sync_packet($channel['channel_id'], [
Libsync::build_sync_packet($channel['channel_id'], [
'calendar' => [
'action' => 'create',
'uri' => $calendarUri,
@@ -413,7 +418,7 @@ class Cdav extends Controller {
$calendarData = $vcalendar->serialize();
$caldavBackend->createCalendarObject($id, $objectUri, $calendarData);
build_sync_packet($channel['channel_id'], [
Libsync::build_sync_packet($channel['channel_id'], [
'calendar' => [
'action' => 'import',
'uri' => $cdavdata['uri'],
@@ -444,7 +449,7 @@ class Cdav extends Controller {
$caldavBackend->updateCalendar($id, $patch);
$patch->commit();
build_sync_packet($channel['channel_id'], [
Libsync::build_sync_packet($channel['channel_id'], [
'calendar' => [
'action' => 'edit',
'uri' => $cdavdata['uri'],
@@ -510,7 +515,7 @@ class Cdav extends Controller {
$calendarData = $vcalendar->serialize();
$caldavBackend->updateCalendarObject($id, $uri, $calendarData);
build_sync_packet($channel['channel_id'], [
Libsync::build_sync_packet($channel['channel_id'], [
'calendar' => [
'action' => 'update_card',
'uri' => $cdavdata['uri'],
@@ -536,7 +541,7 @@ class Cdav extends Controller {
$caldavBackend->deleteCalendarObject($id, $uri);
build_sync_packet($channel['channel_id'], [
Libsync::build_sync_packet($channel['channel_id'], [
'calendar' => [
'action' => 'delete_card',
'uri' => $cdavdata['uri'],
@@ -594,7 +599,7 @@ class Cdav extends Controller {
$calendarData = $vcalendar->serialize();
$caldavBackend->updateCalendarObject($id, $uri, $calendarData);
build_sync_packet($channel['channel_id'], [
Libsync::build_sync_packet($channel['channel_id'], [
'calendar' => [
'action' => 'update_card',
'uri' => $cdavdata['uri'],
@@ -653,7 +658,7 @@ class Cdav extends Controller {
$carddavBackend->createAddressBook($principalUri, $addressbookUri, $properties);
build_sync_packet($channel['channel_id'], [
Libsync::build_sync_packet($channel['channel_id'], [
'addressbook' => [
'action' => 'create',
'uri' => $addressbookUri,
@@ -680,7 +685,7 @@ class Cdav extends Controller {
$carddavBackend->updateAddressBook($id, $patch);
$patch->commit();
build_sync_packet($channel['channel_id'], [
Libsync::build_sync_packet($channel['channel_id'], [
'addressbook' => [
'action' => 'edit',
'uri' => $cdavdata['uri'],
@@ -724,7 +729,7 @@ class Cdav extends Controller {
$cardData = $vcard->serialize();
$carddavBackend->createCard($id, $uri, $cardData);
build_sync_packet($channel['channel_id'], [
Libsync::build_sync_packet($channel['channel_id'], [
'addressbook' => [
'action' => 'import',
'uri' => $cdavdata['uri'],
@@ -762,8 +767,8 @@ class Cdav extends Controller {
$cardData = $vcard->serialize();
$carddavBackend->updateCard($id, $uri, $cardData);
build_sync_packet($channel['channel_id'], [
Libsync::build_sync_packet($channel['channel_id'], [
'addressbook' => [
'action' => 'update_card',
'uri' => $cdavdata['uri'],
@@ -788,7 +793,7 @@ class Cdav extends Controller {
$carddavBackend->deleteCard($id, $uri);
build_sync_packet($channel['channel_id'], [
Libsync::build_sync_packet($channel['channel_id'], [
'addressbook' => [
'action' => 'delete_card',
'uri' => $cdavdata['uri'],
@@ -804,7 +809,7 @@ class Cdav extends Controller {
$src = $_FILES['userfile']['tmp_name'];
if($src) {
$carddata = @file_get_contents($src);
if($_REQUEST['c_upload']) {
@@ -840,14 +845,14 @@ class Cdav extends Controller {
$objects = new \Sabre\VObject\Splitter\VCard($carddata);
$profile = \Sabre\VObject\Node::PROFILE_CARDDAV;
$backend = new \Sabre\CardDAV\Backend\PDO($pdo);
$cdavdata = $this->get_cdav_data($id, 'addressbooks');
}
$ids = [];
import_cdav_card($id, $ext, $table, $column, $objects, $profile, $backend, $ids, true);
build_sync_packet($channel['channel_id'], [
Libsync::build_sync_packet($channel['channel_id'], [
$sync => [
'action' => 'import',
'uri' => $cdavdata['uri'],
@@ -868,10 +873,8 @@ class Cdav extends Controller {
if((argv(1) === 'addressbook') && (! Apps::system_app_installed(local_channel(), 'CardDAV'))) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('CardDAV App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('CalDAV capable addressbook');
return $o;
$papp = Apps::get_papp('CardDAV');
return Apps::app_render($papp, 'module');
}
App::$profile_uid = local_channel();
@@ -1013,7 +1016,7 @@ class Cdav extends Controller {
$catsenabled = feature_enabled(local_channel(), 'categories');
require_once('include/acl_selectors.php');
$accesslist = new \Zotlabs\Access\AccessList($channel);
$perm_defaults = $accesslist->get();
@@ -1054,6 +1057,7 @@ class Cdav extends Controller {
'$cancel' => t('Cancel'),
'$create' => t('Create'),
'$recurrence_warning' => t('Sorry! Editing of recurrent events is not yet implemented.'),
'$disabled_warning' => t('Could not fetch calendar resource. The selected calendar might be disabled.'),
'$channel_hash' => $channel['channel_hash'],
'$acl' => $acl,
@@ -1167,7 +1171,7 @@ class Cdav extends Controller {
set_pconfig(local_channel(), 'cdav_calendar', $id, argv(4));
build_sync_packet(local_channel(), [
Libsync::build_sync_packet(local_channel(), [
'calendar' => [
'action' => 'switch',
'uri' => $cdavdata['uri'],
@@ -1190,7 +1194,7 @@ class Cdav extends Controller {
$caldavBackend->deleteCalendar($id);
build_sync_packet($channel['channel_id'], [
Libsync::build_sync_packet($channel['channel_id'], [
'calendar' => [
'action' => 'drop',
'uri' => $cdavdata['uri']
@@ -1409,7 +1413,7 @@ class Cdav extends Controller {
$carddavBackend->deleteAddressBook($id);
if($cdavdata)
build_sync_packet($channel['channel_id'], [
Libsync::build_sync_packet($channel['channel_id'], [
'addressbook' => [
'action' => 'drop',
'uri' => $cdavdata['uri']
@@ -1427,7 +1431,7 @@ class Cdav extends Controller {
return;
$uri = 'principals/' . $channel['channel_address'];
$r = q("select * from principals where uri = '%s' limit 1",
dbesc($uri)

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,125 @@ require_once('include/opengraph.php');
* @brief Channel Controller
*
*/
class Channel extends Controller {
function init() {
if(in_array(substr($_GET['search'],0,1),[ '@', '!', '?']))
goaway('search' . '?f=&search=' . $_GET['search']);
if (array_key_exists('search', $_GET) && (in_array(substr($_GET['search'], 0, 1), ['@', '!', '?']) || strpos($_GET['search'], 'https://') === 0))
goaway(z_root() . '/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')) {
$channel = App::get_channel();
$which = $channel['channel_address'];
$profile = argv(1);
}
$channel = channelx_by_nick($which);
if(! $channel) {
$channel = channelx_by_nick($which, true);
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'] ]));
if ($sigdata && $sigdata['signer'] && $sigdata['header_valid']) {
$data = json_encode(Libzot::zotinfo(['guid_hash' => $channel['channel_hash'], 'target_url' => $sigdata['signer']]));
$s = q("select site_crypto, hubloc_sitekey from site left join hubloc on hubloc_url = site_url where hubloc_id_url = '%s' and hubloc_network = 'zot6' 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 ($channel['channel_removed']) {
http_status_exit(410, 'Gone');
}
if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
$which = $channel['channel_address'];
if (get_pconfig($channel['channel_id'], 'system', 'index_opt_out')) {
App::$meta->set('robots', 'noindex, noarchive');
}
if (ActivityStreams::is_as_request($channel)) {
// Somebody may attempt an ActivityStreams fetch on one of our message permalinks
// Make it do the right thing.
$mid = ((x($_REQUEST, 'mid')) ? unpack_link_id($_REQUEST['mid']) : '');
if ($mid === false) {
http_status_exit(404, 'Not found');
}
if ($mid) {
$obj = null;
if (strpos($mid, z_root() . '/item/') === 0) {
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,20 +150,24 @@ 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'])
);
opengraph_add_meta($r ? $r[0] : [], $channel);
$mid = ((x($_REQUEST, 'mid')) ? unpack_link_id($_REQUEST['mid']) : '');
if ($mid === false) {
notice(t('Malformed message id.') . EOL);
return;
}
if ($mid) {
$r = q("SELECT * FROM item WHERE mid = '%s' AND uid = %d AND item_private = 0 LIMIT 1",
dbesc($mid),
intval($channel['channel_id'])
);
}
opengraph_add_meta((isset($r) && count($r) ? $r[0] : []), $channel);
}
function get($update = 0, $load = false) {
@@ -132,99 +176,98 @@ class Channel extends Controller {
$category = $datequery = $datequery2 = '';
$mid = ((x($_REQUEST,'mid')) ? $_REQUEST['mid'] : '');
$mid = ((x($_REQUEST, 'mid')) ? unpack_link_id($_REQUEST['mid']) : '');
if ($mid === false) {
notice(t('Malformed message id.') . EOL);
return;
}
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');
nav_set_selected('Channel');
// 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 +276,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 +293,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,19 +309,19 @@ 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) {
$r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal_update
if ($mid) {
$r = q("SELECT parent AS item_id from item where mid = '%s' and uid = %d $item_normal_update
AND item_wall = 1 $simple_update $sql_extra limit 1",
dbesc($mid . '%'),
dbesc($mid),
intval(App::$profile['profile_uid'])
);
}
@@ -296,61 +339,62 @@ class Channel extends Controller {
}
else {
if(x($category)) {
$sql_extra2 .= protect_sprintf(term_item_parent_query(App::$profile['profile_uid'],'item', $category, TERM_CATEGORY));
$sql_extra2 = '';
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) {
$r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal
if ($noscript_content || $load) {
if ($mid) {
$r = q("SELECT parent AS item_id from item where mid = '%s' and uid = %d $item_normal
AND item_wall = 1 $sql_extra limit 1",
dbesc($mid . '%'),
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 +407,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)
$mid = 'b64.' . base64url_encode($mid);
$mode = (($search) ? 'search' : 'channel');
if ((!$update) && (!$load)) {
//if we got a decoded hash we must encode it again before handing to javascript
$mid = gen_link_id($mid);
// This is ugly, but we can't pass the profile_uid through the session to the ajax updater,
// because browser prefetching might change it on us. We have to deliver it with the page.
$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 +446,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 +495,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'])
if ($mid && count($items) > 0 && isset($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, $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

@@ -10,49 +10,49 @@ use Zotlabs\Lib\Zotfinger;
class Chanview extends \Zotlabs\Web\Controller {
function get() {
$observer = App::get_observer();
$xchan = null;
$r = null;
if($_REQUEST['hash']) {
$r = q("select * from xchan where xchan_hash = '%s'",
$r = q("select * from xchan where xchan_hash = '%s' and xchan_deleted = 0",
dbesc($_REQUEST['hash'])
);
}
if($_REQUEST['address']) {
$r = q("select * from xchan where xchan_addr = '%s'",
$r = q("select * from xchan where xchan_addr = '%s' and xchan_deleted = 0",
dbesc(punify($_REQUEST['address']))
);
}
elseif(local_channel() && intval($_REQUEST['cid'])) {
$r = q("SELECT abook.*, xchan.*
$r = q("SELECT abook.*, xchan.*
FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_channel = %d and abook_id = %d",
WHERE abook_channel = %d and abook_id = %d and xchan_deleted = 0",
intval(local_channel()),
intval($_REQUEST['cid'])
);
}
}
elseif($_REQUEST['url']) {
// if somebody re-installed they will have more than one xchan, use the most recent name date as this is
// the most useful consistently ascending table item we have.
$r = q("select * from xchan where xchan_url = '%s' order by xchan_name_date desc",
// the most useful consistently ascending table item we have.
$r = q("select * from xchan where xchan_url = '%s' and xchan_deleted = 0 order by xchan_name_date desc",
dbesc($_REQUEST['url'])
);
}
if($r) {
App::$poi = Libzot::zot_record_preferred($r, 'xchan_network');
}
// Here, let's see if we have an xchan. If we don't, how we proceed is determined by what
// info we do have. If it's a URL, we can offer to visit it directly. If it's a webbie or
// address, we can and should try to import it. If it's just a hash, we can't continue, but we
// info we do have. If it's a URL, we can offer to visit it directly. If it's a webbie or
// address, we can and should try to import it. If it's just a hash, we can't continue, but we
// probably wouldn't have a hash if we don't already have an xchan for this channel.
if(! App::$poi) {
logger('mod_chanview: fallback');
@@ -70,8 +70,8 @@ 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);
$r = q("select * from xchan where xchan_url = '%s'",
Libzot::import_xchan($zf['data']);
$r = q("select * from xchan where xchan_url = '%s' and xchan_deleted = 0",
dbesc($_REQUEST['url'])
);
if($r) {
@@ -80,7 +80,7 @@ class Chanview extends \Zotlabs\Web\Controller {
}
if(! $r) {
if(discover_by_webbie($_REQUEST['url'])) {
$r = q("select * from xchan where xchan_url = '%s'",
$r = q("select * from xchan where xchan_url = '%s' and xchan_deleted = 0",
dbesc($_REQUEST['url'])
);
if($r) {
@@ -90,7 +90,7 @@ class Chanview extends \Zotlabs\Web\Controller {
}
}
}
if(! App::$poi) {
notice( t('Channel not found.') . EOL);
return;
@@ -98,9 +98,9 @@ class Chanview extends \Zotlabs\Web\Controller {
$is_zot = false;
$connected = false;
$url = App::$poi['xchan_url'];
if(in_array(App::$poi['xchan_network'], ['zot', 'zot6'])) {
if(App::$poi['xchan_network'] === 'zot6') {
$is_zot = true;
}
if(local_channel()) {
@@ -111,29 +111,29 @@ class Chanview extends \Zotlabs\Web\Controller {
if($c)
$connected = true;
}
// We will load the chanview template if it's a foreign network,
// We will load the chanview template if it's a foreign network,
// just so that we can provide a connect button along with a profile
// photo. Chances are we can't load the remote profile into an iframe
// because of cross-domain security headers. So provide a link to
// the remote profile.
// the remote profile.
// If we are already connected, just go to the profile.
// Zot channels will usually have a connect link.
if($is_zot || $connected) {
if($is_zot && $observer) {
$url = zid($url);
}
goaway($url);
}
else {
else {
$o = replace_macros(get_markup_template('chanview.tpl'),array(
'$url' => $url,
'$full' => t('toggle full screen mode')
));
return $o;
}
}
}

View File

@@ -14,7 +14,7 @@ require_once('include/bookmarks.php');
class Chat extends Controller {
function init() {
$which = null;
if(argc() > 1)
$which = argv(1);
@@ -29,79 +29,77 @@ class Chat extends Controller {
notice( t('You must be logged in to see this page.') . EOL );
return;
}
$profile = 0;
$channel = App::get_channel();
if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
$which = $channel['channel_address'];
$profile = argv(1);
$profile = argv(1);
}
// Run profile_load() here to make sure the theme is set before
// we start loading content
profile_load($which,$profile);
}
function post() {
if($_POST['room_name'])
$room = strip_tags(trim($_POST['room_name']));
$room = strip_tags(trim($_POST['room_name']));
if((! $room) || (! local_channel()))
return;
$channel = App::get_channel();
if($_POST['action'] === 'drop') {
logger('delete chatroom');
Chatroom::destroy($channel,array('cr_name' => $room));
goaway(z_root() . '/chat/' . $channel['channel_address']);
}
$acl = new AccessList($channel);
$acl->set_from_array($_REQUEST);
$arr = $acl->get();
$arr['name'] = $room;
$arr['expire'] = intval($_POST['chat_expire']);
if(intval($arr['expire']) < 0)
$arr['expire'] = 0;
Chatroom::create($channel,$arr);
$x = q("select * from chatroom where cr_name = '%s' and cr_uid = %d limit 1",
dbesc($room),
intval(local_channel())
);
Libsync::build_sync_packet(0, array('chatroom' => $x));
if($x)
goaway(z_root() . '/chat/' . $channel['channel_address'] . '/' . $x[0]['cr_id']);
// that failed. Try again perhaps?
goaway(z_root() . '/chat/' . $channel['channel_address'] . '/new');
}
function get() {
if(! Apps::system_app_installed(App::$profile_uid, 'Chatrooms')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Chatrooms App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('Access Controlled Chatrooms');
return $o;
$papp = Apps::get_papp('Chatrooms');
return Apps::app_render($papp, 'module');
}
if(local_channel()) {
$channel = App::get_channel();
nav_set_selected('Chatrooms');
@@ -113,24 +111,24 @@ class Chat extends Controller {
notice( t('Permission denied.') . EOL);
return;
}
if(! perm_is_allowed(App::$profile['profile_uid'],$observer,'chat')) {
notice( t('Permission denied.') . EOL);
return;
}
if((argc() > 3) && intval(argv(2)) && (argv(3) === 'leave')) {
Chatroom::leave($observer,argv(2),$_SERVER['REMOTE_ADDR']);
goaway(z_root() . '/channel/' . argv(1));
}
if((argc() > 3) && intval(argv(2)) && (argv(3) === 'status')) {
$ret = array('success' => false);
$room_id = intval(argv(2));
if(! $room_id || ! $observer)
return;
$r = q("select * from chatroom where cr_id = %d limit 1",
intval($room_id)
);
@@ -139,7 +137,7 @@ class Chat extends Controller {
}
require_once('include/security.php');
$sql_extra = permissions_sql($r[0]['cr_uid']);
$x = q("select * from chatroom where cr_id = %d and cr_uid = %d $sql_extra limit 1",
intval($room_id),
intval($r[0]['cr_uid'])
@@ -155,9 +153,9 @@ class Chat extends Controller {
$ret['chatroom'] = $r[0]['cr_name'];
$ret['inroom'] = $y[0]['total'];
}
// figure out how to present a timestamp of the last activity, since we don't know the observer's timezone.
$z = q("select created from chat where chat_room = %d order by created desc limit 1",
intval($room_id)
);
@@ -166,13 +164,13 @@ class Chat extends Controller {
}
json_return_and_die($ret);
}
if(argc() > 2 && intval(argv(2))) {
$room_id = intval(argv(2));
$bookmark_link = get_bookmark_link($ob);
$x = Chatroom::enter($observer,$room_id,'online',$_SERVER['REMOTE_ADDR']);
if(! $x)
return;
@@ -180,26 +178,26 @@ class Chat extends Controller {
intval($room_id),
intval(App::$profile['profile_uid'])
);
if($x) {
$acl = new AccessList(false);
$acl->set($x[0]);
$private = $acl->is_private();
$room_name = $x[0]['cr_name'];
if($bookmark_link)
$bookmark_link .= '&url=' . z_root() . '/chat/' . argv(1) . '/' . argv(2) . '&title=' . urlencode($x[0]['cr_name']) . (($private) ? '&private=1' : '') . '&ischat=1';
$bookmark_link .= '&url=' . z_root() . '/chat/' . argv(1) . '/' . argv(2) . '&title=' . urlencode($x[0]['cr_name']) . (($private) ? '&private=1' : '') . '&ischat=1';
}
else {
notice( t('Room not found') . EOL);
return;
}
$cipher = get_pconfig(local_channel(),'system','default_cipher');
if(! $cipher)
$cipher = 'AES-128-CCM';
$o = replace_macros(get_markup_template('chat.tpl'),array(
'$is_owner' => ((local_channel() && local_channel() == $x[0]['cr_uid']) ? true : false),
'$room_name' => $room_name,
@@ -223,7 +221,7 @@ class Chat extends Controller {
}
require_once('include/conversation.php');
$o = '';
$acl = new AccessList($channel);
@@ -246,12 +244,12 @@ class Chat extends Controller {
'$deny_gid' => acl2json($channel_acl['deny_gid']),
'$lockstate' => $lockstate,
'$submit' => t('Submit')
));
}
$rooms = Chatroom::roomlist(App::$profile['profile_uid']);
$o .= replace_macros(get_markup_template('chatrooms.tpl'), array(
'$header' => sprintf( t('%1$s\'s Chatrooms'), App::$profile['fullname']),
'$name' => t('Name'),
@@ -259,15 +257,15 @@ class Chat extends Controller {
'$nickname' => App::$profile['channel_address'],
'$rooms' => $rooms,
'$norooms' => t('No chatrooms available'),
'$newroom' => t('Create New'),
'$newroom' => t('Add Room'),
'$is_owner' => ((local_channel() && local_channel() == App::$profile['profile_uid']) ? 1 : 0),
'$chatroom_new' => $chatroom_new,
'$expire' => t('Expiration'),
'$expire_unit' => t('min') //minutes
));
return $o;
}
}

View File

@@ -8,7 +8,11 @@ namespace Zotlabs\Module;
*/
use Sabre\DAV as SDAV;
use \Zotlabs\Storage;
use \Zotlabs\Web\Controller;
use \Zotlabs\Storage\BasicAuth;
use \Zotlabs\Storage\Directory;
use \Zotlabs\Storage\Browser;
// composer autoloader for SabreDAV
require_once('vendor/autoload.php');
@@ -20,7 +24,7 @@ require_once('include/attach.php');
* @brief Cloud Module.
*
*/
class Cloud extends \Zotlabs\Web\Controller {
class Cloud extends Controller {
/**
* @brief Fires up the SabreDAV server.
@@ -42,7 +46,7 @@ class Cloud extends \Zotlabs\Web\Controller {
$auth = new \Zotlabs\Storage\BasicAuth();
$auth = new BasicAuth();
$ob_hash = get_observer_hash();
@@ -72,7 +76,7 @@ class Cloud extends \Zotlabs\Web\Controller {
if($x !== \App::$query_string)
goaway(z_root() . '/' . $x);
$rootDirectory = new \Zotlabs\Storage\Directory('/', $auth);
$rootDirectory = new Directory('/', [], $auth);
// A SabreDAV server-object
$server = new SDAV\Server($rootDirectory);
@@ -85,7 +89,7 @@ class Cloud extends \Zotlabs\Web\Controller {
$is_readable = false;
// provide a directory view for the cloud in Hubzilla
$browser = new \Zotlabs\Storage\Browser($auth);
$browser = new Browser($auth);
$auth->setBrowserPlugin($browser);
$server->addPlugin($browser);
@@ -101,17 +105,17 @@ class Cloud extends \Zotlabs\Web\Controller {
// All we need to do now, is to fire up the server
$server->exec();
$server->start();
if($browser->build_page)
construct_page();
killme();
}
function DAVException($err) {
if($err instanceof \Sabre\DAV\Exception\NotFound) {
notice( t('Not found') . EOL);
}
@@ -119,14 +123,15 @@ class Cloud extends \Zotlabs\Web\Controller {
notice( t('Permission denied') . EOL);
}
elseif($err instanceof \Sabre\DAV\Exception\NotImplemented) {
notice( t('Please refresh page') . EOL);
// notice( t('Please refresh page') . EOL);
goaway(z_root() . '/' . \App::$query_string);
}
else {
notice( t('Unknown error') . EOL);
}
construct_page();
killme();
}

View File

@@ -18,11 +18,11 @@ class Connect extends Controller {
App::$error = 404;
return;
}
$r = q("select * from channel where channel_address = '%s' limit 1",
dbesc($which)
);
if($r)
App::$data['channel'] = $r[0];
@@ -30,36 +30,36 @@ class Connect extends Controller {
profile_load($which,'');
}
function post() {
if(! array_key_exists('channel', App::$data))
return;
$channel_id = App::$data['channel']['channel_id'];
$edit = ((local_channel() && (local_channel() == $channel_id)) ? true : false);
if($edit) {
$has_premium = ((App::$data['channel']['channel_pageflags'] & PAGE_PREMIUM) ? 1 : 0);
$premium = (($_POST['premium']) ? intval($_POST['premium']) : 0);
$text = escape_tags($_POST['text']);
if($has_premium != $premium) {
$r = q("update channel set channel_pageflags = ( channel_pageflags %s %d ) where channel_id = %d",
db_getfunc('^'),
intval(PAGE_PREMIUM),
intval(local_channel())
intval(local_channel())
);
\Zotlabs\Daemon\Master::Summon(array('Notifier','refresh_all',$channel_id));
}
set_pconfig($channel_id,'system','selltext',$text);
// reload the page completely to get fresh data
goaway(z_root() . '/' . App::$query_string);
}
$url = '';
$observer = App::get_observer();
if(($observer) && ($_POST['submit'] === t('Continue'))) {
@@ -70,18 +70,18 @@ class Connect extends Controller {
dbesc($observer['xchan_hash'])
);
if($r)
$url = $r[0]['hubloc_url'] . '/follow?f=&url=' . urlencode(channel_reddress(App::$data['channel']));
$url = $r[0]['hubloc_url'] . '/follow?f=&interactive=1&url=' . urlencode(channel_reddress(App::$data['channel']));
}
}
if($url)
goaway($url . '&confirm=1');
else
notice('Unable to connect to your home hub location.');
}
function get() {
if(! array_key_exists('channel', App::$data))
@@ -90,11 +90,11 @@ class Connect extends Controller {
$channel_id = App::$data['channel']['channel_id'];
$edit = ((local_channel() && (local_channel() == $channel_id)) ? true : false);
$text = get_pconfig($channel_id,'system','selltext');
if($edit) {
$o = replace_macros(get_markup_template('sellpage_edit.tpl'),array(
'$header' => t('Premium Channel Setup'),
'$address' => App::$data['channel']['channel_address'],
@@ -105,36 +105,36 @@ class Connect extends Controller {
'$lbl2' => t('Potential connections will then see the following text before proceeding:'),
'$desc2' => t('By continuing, I certify that I have complied with any instructions provided on this page.'),
'$submit' => t('Submit'),
));
return $o;
}
else {
if(! $text)
$text = t('(No specific instructions have been provided by the channel owner.)');
$submit = replace_macros(get_markup_template('sellpage_submit.tpl'), array(
'$continue' => t('Continue'),
'$continue' => t('Continue'),
'$address' => App::$data['channel']['channel_address']
));
$o = replace_macros(get_markup_template('sellpage_view.tpl'),array(
'$header' => t('Restricted or Premium Channel'),
'$desc' => t('This channel may require additional steps or acknowledgement of the following conditions prior to connecting:'),
'$text' => prepare_text($text),
'$text' => prepare_text($text),
'$desc2' => t('By continuing, I certify that I have complied with any instructions provided on this page.'),
'$submit' => $submit,
));
$arr = array('channel' => App::$data['channel'],'observer' => App::get_observer(), 'sellpage' => $o, 'submit' => $submit);
call_hooks('connect_premium', $arr);
$o = $arr['sellpage'];
}
return $o;
}
}

View File

@@ -2,32 +2,32 @@
namespace Zotlabs\Module;
use App;
use Zotlabs\Lib\Permcat;
require_once('include/socgraph.php');
require_once('include/selectors.php');
require_once('include/group.php');
class Connections extends \Zotlabs\Web\Controller {
function init() {
if(! local_channel())
return;
App::$profile_uid = local_channel();
$channel = App::get_channel();
if($channel)
head_set_icon($channel['xchan_photo_s']);
}
function get() {
$sort_type = 0;
$o = '';
if(! local_channel()) {
notice( t('Permission denied.') . EOL);
return login();
@@ -44,13 +44,13 @@ class Connections extends \Zotlabs\Web\Controller {
$pending = false;
$unconnected = false;
$all = false;
if(! $_REQUEST['aj'])
$_SESSION['return_url'] = App::$query_string;
$search_flags = "";
$head = '';
if(argc() == 2) {
switch(argv(1)) {
case 'active':
@@ -106,27 +106,28 @@ class Connections extends \Zotlabs\Web\Controller {
// $head = t('Unconnected');
// $unconnected = true;
// break;
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;
$head = t('Active');
break;
}
$sql_extra = $search_flags;
if(argv(1) === 'pending')
$sql_extra .= " and abook_ignored = 0 ";
}
else {
$sql_extra = " and abook_blocked = 0 ";
$unblocked = true;
}
switch($_REQUEST['order']) {
case 'name_desc':
$sql_order = 'xchan_name DESC';
@@ -142,32 +143,32 @@ class Connections extends \Zotlabs\Web\Controller {
}
$search = ((x($_REQUEST,'search')) ? notags(trim($_REQUEST['search'])) : '');
$tabs = array(
/*
array(
'label' => t('Suggestions'),
'url' => z_root() . '/suggest',
'url' => z_root() . '/suggest',
'sel' => '',
'title' => t('Suggest new connections'),
),
*/
'active' => array(
'label' => t('Active Connections'),
'url' => z_root() . '/connections/active',
'url' => z_root() . '/connections/active',
'sel' => ($active) ? 'active' : '',
'title' => t('Show active connections'),
),
'pending' => array(
'label' => t('New Connections'),
'url' => z_root() . '/connections/pending',
'url' => z_root() . '/connections/pending',
'sel' => ($pending) ? 'active' : '',
'title' => t('Show pending (new) connections'),
),
/*
array(
'label' => t('Unblocked'),
@@ -176,55 +177,55 @@ class Connections extends \Zotlabs\Web\Controller {
'title' => t('Only show unblocked connections'),
),
*/
'blocked' => array(
'label' => t('Blocked'),
'url' => z_root() . '/connections/blocked',
'sel' => ($blocked) ? 'active' : '',
'title' => t('Only show blocked connections'),
),
'ignored' => array(
'label' => t('Ignored'),
'url' => z_root() . '/connections/ignored',
'sel' => ($ignored) ? 'active' : '',
'title' => t('Only show ignored connections'),
),
'archived' => array(
'label' => t('Archived/Unreachable'),
'url' => z_root() . '/connections/archived',
'sel' => ($archived) ? 'active' : '',
'title' => t('Only show archived/unreachable connections'),
),
'hidden' => array(
'label' => t('Hidden'),
'url' => z_root() . '/connections/hidden',
'sel' => ($hidden) ? 'active' : '',
'title' => t('Only show hidden connections'),
),
// array(
// 'label' => t('Unconnected'),
// 'url' => z_root() . '/connections/unconnected',
// 'sel' => ($unconnected) ? 'active' : '',
// 'title' => t('Only show one-way connections'),
// ),
'all' => array(
'label' => t('All Connections'),
'url' => z_root() . '/connections',
'url' => z_root() . '/connections',
'sel' => ($all) ? 'active' : '',
'title' => t('Show all connections'),
),
);
//$tab_tpl = get_markup_template('common_tabs.tpl');
//$t = replace_macros($tab_tpl, array('$tabs'=>$tabs));
$searching = false;
if($search) {
$search_hdr = $search;
@@ -232,32 +233,40 @@ class Connections extends \Zotlabs\Web\Controller {
$searching = true;
}
$sql_extra .= (($searching) ? protect_sprintf(" AND xchan_name like '%$search_txt%' ") : "");
if($_REQUEST['gid']) {
$sql_extra .= " and xchan_hash in ( select xchan from pgrp_member where gid = " . intval($_REQUEST['gid']) . " and uid = " . intval(local_channel()) . " ) ";
}
$r = q("SELECT COUNT(abook.abook_id) AS total FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash
where abook_channel = %d and abook_self = 0 and xchan_deleted = 0 and xchan_orphan = 0 $sql_extra $sql_extra2 ",
$r = q("SELECT COUNT(abook.abook_id) AS total FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash
where abook_channel = %d and abook_self = 0 and xchan_deleted = 0 and xchan_orphan = 0 $sql_extra ",
intval(local_channel())
);
if($r) {
App::set_pager_total($r[0]['total']);
$total = $r[0]['total'];
}
$r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash
WHERE abook_channel = %d and abook_self = 0 and xchan_deleted = 0 and xchan_orphan = 0 $sql_extra $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'])
);
$roles = new Permcat(local_channel());
$roles_list = $roles->listing();
$roles_dict = [];
foreach ($roles_list as $role) {
$roles_dict[$role['name']] = $role['localname'];
}
$contacts = array();
if($r) {
vcard_query($r);
//vcard_query($r);
foreach($r as $rr) {
@@ -267,7 +276,7 @@ class Connections extends \Zotlabs\Web\Controller {
$phone = $rr['vcard']['tels'][0]['nr'];
else
$phone = '';
$status_str = '';
$status = array(
((intval($rr['abook_active'])) ? t('Active') : ''),
@@ -305,7 +314,7 @@ class Connections extends \Zotlabs\Web\Controller {
$perminfo['connperms'] .= t('Nothing');
}
foreach($status as $str) {
if(!$str)
continue;
@@ -313,19 +322,16 @@ class Connections extends \Zotlabs\Web\Controller {
$status_str .= ', ';
}
$status_str = rtrim($status_str, ', ');
$contacts[] = array(
'img_hover' => sprintf( t('%1$s [%2$s]'),$rr['xchan_name'],$rr['xchan_url']),
'edit_hover' => t('Edit connection'),
'edit' => t('Edit'),
'delete_hover' => t('Delete connection'),
'id' => $rr['abook_id'],
'thumb' => $rr['xchan_photo_m'],
'thumb' => $rr['xchan_photo_m'],
'name' => $rr['xchan_name'],
'classes' => ((intval($rr['abook_archived']) || intval($rr['abook_not_here'])) ? 'archived' : ''),
'link' => z_root() . '/connedit/' . $rr['abook_id'],
'deletelink' => z_root() . '/connedit/' . intval($rr['abook_id']) . '/drop',
'delete' => t('Delete'),
'url' => chanlink_hash($rr['xchan_hash']),
'webbie_label' => t('Channel address'),
'webbie' => $rr['xchan_addr'],
@@ -336,6 +342,7 @@ class Connections extends \Zotlabs\Web\Controller {
'phone' => $phone,
'status_label' => t('Status'),
'status' => $status_str,
'states' => $status,
'connected_label' => t('Connected'),
'connected' => datetime_convert('UTC',date_default_timezone_get(),$rr['abook_created'], 'c'),
'approve_hover' => t('Approve connection'),
@@ -348,13 +355,22 @@ class Connections extends \Zotlabs\Web\Controller {
'perminfo' => $perminfo,
'connect' => (intval($rr['abook_not_here']) ? t('Connect') : ''),
'follow' => z_root() . '/follow/?f=&url=' . urlencode($rr['xchan_hash']) . '&interactive=0',
'connect_hover' => t('Connect at this location')
'connect_hover' => t('Connect at this location'),
'role' => $roles_dict[$rr['abook_role']],
'pending' => intval($rr['abook_pending'])
);
}
}
}
$limit = service_class_fetch(local_channel(),'total_channels');
if($limit !== false) {
$abook_usage_message = sprintf( t("You have %1$.0f of %2$.0f allowed connections."), $$total, $limit);
}
else {
$abook_usage_message = '';
}
if($_REQUEST['aj']) {
if($contacts) {
$o = replace_macros(get_markup_template('contactsajax.tpl'),array(
@@ -370,27 +386,30 @@ class Connections extends \Zotlabs\Web\Controller {
}
else {
$o .= "<script> var page_query = '" . escape_tags(urlencode($_GET['q'])) . "'; var extra_args = '" . extra_query_args() . "' ; </script>";
$o .= replace_macros(get_markup_template('connections.tpl'),array(
$o .= replace_macros(get_markup_template('connections.tpl'), [
'$header' => t('Connections') . (($head) ? ': ' . $head : ''),
'$tabs' => $tabs,
'$total' => $total,
'$search' => $search_hdr,
'$label' => t('Search'),
'$role_label' => t('Contact role'),
'$desc' => t('Search your connections'),
'$finding' => (($searching) ? t('Connections search') . ": '" . $search . "'" : ""),
'$finding' => (($searching) ? t('Contact search') . ": '" . $search . "'" : ""),
'$submit' => t('Find'),
'$edit' => t('Edit'),
'$approve' => t('Approve'),
'$cmd' => App::$cmd,
'$contacts' => $contacts,
'$paginate' => paginate($a),
));
'$abook_usage_message' => $abook_usage_message,
'$group_label' => t('This is a group/forum channel')
]);
}
if(! $contacts)
$o .= '<div id="content-complete"></div>';
return $o;
}
}

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