Compare commits

...

132 Commits
6.0.1 ... 6.2

Author SHA1 Message Date
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
nobody
73b53675b1 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-07-06 05:02:52 -07:00
nobody
efda8aac1d Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-06-17 14:57:47 -07: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
nobody
686530c187 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-06-03 16:01:16 -07:00
nobody
462980c70a Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-05-31 14:36:14 -07:00
nobody
a96345401f Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-04-16 04:42:45 -07:00
nobody
9359fc065c Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-04-05 23:15:01 -07: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
nobody
0f89d2b8e0 some content fields found in the wild are actually arrays 2021-02-23 15:37:58 -08:00
nobody
fc88c306ab some minor issues uncovered during hubzilla->zap export testing 2021-02-22 17:23:08 -08:00
nobody
5664f5e0a2 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2021-02-18 21:42:15 -08: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
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
1090 changed files with 148551 additions and 67752 deletions

View File

@@ -1,3 +1,49 @@
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

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

@@ -65,9 +65,9 @@ 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'),
'tag_deliver' => t('Can forward direct messages to all my channel connections (forum)'),
'chat' => t('Can chat with me'),
'republish' => t('Can source my public posts in derived channels'),
'delegate' => t('Can administer my channel')

View File

@@ -48,13 +48,6 @@ class Cron {
db_quoteinterval('3 MINUTE')
);
// expire any expired mail
q("delete from mail where expires > '%s' and expires < %s ",
dbesc(NULL_DATE),
db_utcnow()
);
require_once('include/account.php');
remove_expired_registrations();

View File

@@ -126,7 +126,10 @@ class Onepoll {
$max = intval(get_config('system', 'max_imported_posts', 30));
if (intval($max)) {
$cl = get_xconfig($contact['abook_xchan'], 'activitypub', 'collections');
$cl = Activity::get_actor_collections($contact['abook_xchan']);
if(empty($cl)) {
$cl = get_xconfig($contact['abook_xchan'], 'activitypub', 'collections');
}
if (is_array($cl) && array_key_exists('outbox', $cl)) {
$url = $cl['outbox'];

View File

@@ -8,6 +8,8 @@ use Zotlabs\Access\PermissionRoles;
use Zotlabs\Access\Permissions;
use Zotlabs\Daemon\Master;
use Zotlabs\Web\HTTPSig;
use Zotlabs\Lib\XConfig;
use Zotlabs\Lib\Libzot;
require_once('include/event.php');
require_once('include/html2plain.php');
@@ -590,13 +592,11 @@ class Activity {
break;
case 'Mention':
$mention_type = substr($t['name'], 0, 1);
if ($mention_type === '!') {
$ret[] = ['ttype' => TERM_FORUM, 'url' => $t['href'], 'term' => escape_tags(substr($t['name'], 1))];
}
else {
$ret[] = ['ttype' => TERM_MENTION, 'url' => $t['href'], 'term' => escape_tags((substr($t['name'], 0, 1) === '@') ? substr($t['name'], 1) : $t['name'])];
}
$ret[] = ['ttype' => TERM_MENTION, 'url' => $t['href'], 'term' => escape_tags((substr($t['name'], 0, 1) === '@') ? substr($t['name'], 1) : $t['name'])];
break;
case 'Bookmark':
$ret[] = ['ttype' => TERM_BOOKMARK, 'url' => $t['href'], 'term' => escape_tags($t['name'])];
break;
default:
@@ -623,14 +623,14 @@ class Activity {
}
break;
case TERM_FORUM:
$ret[] = ['type' => 'Mention', 'href' => $t['url'], 'name' => '!' . $t['term']];
break;
case TERM_MENTION:
$ret[] = ['type' => 'Mention', 'href' => $t['url'], 'name' => '@' . $t['term']];
break;
case TERM_BOOKMARK:
$ret[] = ['type' => 'Bookmark', 'href' => $t['url'], 'name' => $t['term']];
break;
default:
break;
}
@@ -757,7 +757,9 @@ class Activity {
if (array_path_exists('object/id', $obj)) {
$obj['object'] = $obj['object']['id'];
}
unset($obj['cc']);
if (isset($obj['cc'])) {
unset($obj['cc']);
}
$obj['to'] = [ACTIVITY_PUBLIC_INBOX];
$ret['object'] = $obj;
}
@@ -1109,6 +1111,7 @@ class Activity {
call_hooks('encode_person', $arr);
$ret = $arr['encoded'];
return $ret;
}
@@ -1531,12 +1534,55 @@ class Activity {
return;
}
static function actor_store($url, $person_obj) {
static function actor_store($url, $person_obj, $force = false) {
if (!is_array($person_obj)) {
return;
}
/* not implemented
if (array_key_exists('movedTo',$person_obj) && $person_obj['movedTo'] && ! is_array($person_obj['movedTo'])) {
$tgt = self::fetch($person_obj['movedTo']);
if (is_array($tgt)) {
self::actor_store($person_obj['movedTo'],$tgt);
ActivityPub::move($person_obj['id'],$tgt);
}
return;
}
*/
$ap_hubloc = null;
$hublocs = self::get_actor_hublocs($url);
if ($hublocs) {
foreach ($hublocs as $hub) {
if ($hub['hubloc_network'] === 'activitypub') {
$ap_hubloc = $hub;
}
if ($hub['hubloc_network'] === 'zot6') {
Libzot::update_cached_hubloc($hub);
}
}
}
if ($ap_hubloc) {
// we already have a stored record. Determine if it needs updating.
if ($ap_hubloc['hubloc_updated'] < datetime_convert('UTC','UTC',' now - 3 days') || $force) {
$person_obj = self::fetch($url);
}
else {
return;
}
}
if (isset($person_obj['id'])) {
$url = $person_obj['id'];
}
if (! $url) {
return;
}
$inbox = $person_obj['inbox'];
// invalid identity
@@ -1545,6 +1591,9 @@ class Activity {
return;
}
// store the actor record in XConfig
XConfig::Set($url, 'system', 'actor_record', $person_obj);
$name = $person_obj['name'];
if (!$name) {
$name = $person_obj['preferredUsername'];
@@ -1556,13 +1605,21 @@ class Activity {
$icon = z_root() . '/' . get_default_profile_photo(300);
if ($person_obj['icon']) {
if (is_array($person_obj['icon'])) {
if (array_key_exists('url', $person_obj['icon']))
if (array_key_exists('url', $person_obj['icon'])) {
$icon = $person_obj['icon']['url'];
else
$icon = $person_obj['icon'][0]['url'];
}
else {
if (is_string($person_obj['icon'][0])) {
$icon = $person_obj['icon'][0];
}
elseif (array_key_exists('url', $person_obj['icon'][0])) {
$icon = $person_obj['icon'][0]['url'];
}
}
}
else
else {
$icon = $person_obj['icon'];
}
}
$links = false;
@@ -1595,20 +1652,6 @@ class Activity {
$profile = $url;
}
$collections = [];
if ($inbox) {
$collections['inbox'] = $inbox;
if (array_key_exists('outbox', $person_obj))
$collections['outbox'] = $person_obj['outbox'];
if (array_key_exists('followers', $person_obj))
$collections['followers'] = $person_obj['followers'];
if (array_key_exists('following', $person_obj))
$collections['following'] = $person_obj['following'];
if (array_key_exists('endpoints', $person_obj) && array_key_exists('sharedInbox', $person_obj['endpoints']))
$collections['sharedInbox'] = $person_obj['endpoints']['sharedInbox'];
}
if (array_key_exists('publicKey', $person_obj) && array_key_exists('publicKeyPem', $person_obj['publicKey'])) {
if ($person_obj['id'] === $person_obj['publicKey']['owner']) {
$pubkey = $person_obj['publicKey']['publicKeyPem'];
@@ -1633,7 +1676,7 @@ class Activity {
// Record exists. Cache existing records for one week at most
// then refetch to catch updated profile photos, names, etc.
$d = datetime_convert('UTC', 'UTC', 'now - 3 days');
if($r[0]['hubloc_updated'] > $d) {
if($r[0]['hubloc_updated'] > $d && !$force) {
return;
}
@@ -1694,10 +1737,6 @@ class Activity {
);
}
if ($collections) {
set_xconfig($url, 'activitypub', 'collections', $collections);
}
$photos = import_xchan_photo($icon, $url);
q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'",
dbescdate(datetime_convert('UTC', 'UTC', $photos[5])),
@@ -1776,12 +1815,27 @@ class Activity {
}
else {
if (!perm_is_allowed($channel['channel_id'], $observer_hash, 'send_stream') && !$is_sys_channel) {
logger('no permission');
logger('no send_stream permission');
return;
}
$s['owner_xchan'] = $s['author_xchan'] = $observer_hash;
}
if ($act->recips && (!in_array(ACTIVITY_PUBLIC_INBOX, $act->recips)))
$s['item_private'] = 1;
if (array_key_exists('directMessage', $act->obj) && intval($act->obj['directMessage'])) {
$s['item_private'] = 2;
}
if (intval($s['item_private']) === 2) {
if (!perm_is_allowed($channel['channel_id'], $observer_hash, 'post_mail')) {
logger('no post_mail permission');
return;
}
}
$abook = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($observer_hash),
intval($channel['channel_id'])
@@ -1930,14 +1984,6 @@ class Activity {
}
}
if ($act->recips && (!in_array(ACTIVITY_PUBLIC_INBOX, $act->recips)))
$s['item_private'] = 1;
if (array_key_exists('directMessage', $act->obj) && intval($act->obj['directMessage'])) {
$s['item_private'] = 2;
}
set_iconfig($s, 'activitypub', 'recips', $act->raw_recips);
if ($parent) {
set_iconfig($s, 'activitypub', 'rawmsg', $act->raw, 1);
@@ -2633,6 +2679,11 @@ class Activity {
$allowed = true;
}
if (intval($item['item_private']) === 2) {
if (!perm_is_allowed($channel['channel_id'], $observer_hash, 'post_mail')) {
$allowed = false;
}
}
if ($is_sys_channel) {
@@ -3496,4 +3547,53 @@ class Activity {
}
static function get_cached_actor($id) {
return (XConfig::Get($id,'system','actor_record'));
}
static function get_actor_hublocs($url, $options = 'all') {
$hublocs = false;
switch ($options) {
case 'activitypub':
$hublocs = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_hash = '%s' and hubloc_deleted = 0 ",
dbesc($url)
);
break;
case 'zot6':
$hublocs = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_id_url = '%s' and hubloc_deleted = 0 ",
dbesc($url)
);
break;
case 'all':
default:
$hublocs = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash where ( hubloc_id_url = '%s' OR hubloc_hash = '%s' ) and hubloc_deleted = 0 ",
dbesc($url),
dbesc($url)
);
break;
}
return $hublocs;
}
static function get_actor_collections($url) {
$ret = [];
$actor_record = XConfig::Get($url,'system','actor_record');
if (! $actor_record) {
return $ret;
}
foreach ( [ 'inbox','outbox','followers','following' ] as $collection) {
if (isset($actor_record[$collection]) && $actor_record[$collection]) {
$ret[$collection] = $actor_record[$collection];
}
}
if (array_path_exists('endpoints/sharedInbox',$actor_record) && $actor_record['endpoints']['sharedInbox']) {
$ret['sharedInbox'] = $actor_record['endpoints']['sharedInbox'];
}
return $ret;
}
}

View File

@@ -300,17 +300,8 @@ class ActivityStreams {
function get_actor($property, $base = '', $namespace = '') {
$x = $this->get_property_obj($property, $base, $namespace);
if ($this->is_url($x)) {
// SECURITY: If we have already stored the actor profile, re-generate it
// from cached data - don't refetch it from the network
$r = q("select * from xchan join hubloc on xchan_hash = hubloc_hash where hubloc_id_url = '%s'",
dbesc($x)
);
if ($r) {
$r = Libzot::zot_record_preferred($r);
$y = Activity::encode_person($r);
$y['cached'] = true;
$y = Activity::get_cached_actor($x);
if ($y) {
return $y;
}
}

View File

@@ -2,6 +2,7 @@
namespace Zotlabs\Lib;
use App;
use Zotlabs\Lib\Libsync;
require_once('include/plugin.php');
@@ -77,7 +78,8 @@ class Apps {
'Search',
'Help',
'Profile Photo',
'HQ'
'HQ',
'Post'
]);
/**
@@ -537,13 +539,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;
}
@@ -564,8 +600,6 @@ class Apps {
'$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'),
@@ -575,6 +609,7 @@ class Apps {
));
}
static public function app_install($uid,$app) {
if(! is_array($app)) {
@@ -1357,4 +1392,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

@@ -854,8 +854,8 @@ 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'], ['drop_media', true]), 75, true), ENT_QUOTES, 'UTF-8', false),
@@ -882,7 +882,7 @@ class Enotify {
$mid = basename($tt['link']);
$b64mid = ((strpos($mid, 'b64.') === 0) ? $mid : 'b64.' . base64url_encode($mid));
$b64mid = gen_link_id($mid);
$x = [
'notify_link' => (($tt['ntype'] === NOTIFY_MAIL) ? $tt['link'] : z_root() . '/notify/view/' . $tt['id']),
'name' => $tt['xname'],
@@ -910,7 +910,7 @@ class Enotify {
'when' => datetime_convert('UTC', date_default_timezone_get(), $rr['abook_created']),
'hclass' => ('notify-unseen'),
'message' => t('added your channel')
];
];
}

View File

@@ -1601,6 +1601,12 @@ class Libzot {
$friendofriend = true;
}
if (intval($arr['item_private']) === 2) {
if (!perm_is_allowed($channel['channel_id'], $sender, 'post_mail')) {
$allowed = false;
}
}
if (!$allowed) {
logger("permission denied for delivery to channel {$channel['channel_id']} {$channel['channel_address']}");
$DR->update('permission denied');
@@ -1910,16 +1916,18 @@ class Libzot {
// logger($AS->debug());
$r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' limit 1",
$r = q("select hubloc_hash, hubloc_network from hubloc where hubloc_id_url = '%s'",
dbesc($AS->actor['id'])
);
$r = self::zot_record_preferred($r);
if (!$r) {
$y = import_author_xchan(['url' => $AS->actor['id']]);
if ($y) {
$r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' limit 1",
$r = q("select hubloc_hash, hubloc_network from hubloc where hubloc_id_url = '%s'",
dbesc($AS->actor['id'])
);
$r = self::zot_record_preferred($r);
}
if (!$r) {
logger('FOF Activity: no actor');
@@ -1935,9 +1943,8 @@ class Libzot {
}
}
if ($r) {
$arr['author_xchan'] = $r[0]['hubloc_hash'];
$arr['author_xchan'] = $r['hubloc_hash'];
}
if ($signer) {
@@ -2583,21 +2590,26 @@ class Libzot {
$desturl = $x['url'];
$found_primary = false;
$r1 = q("select hubloc_url, hubloc_updated, site_dead from hubloc left join site on
hubloc_url = site_url where hubloc_guid = '%s' and hubloc_guid_sig = '%s' and hubloc_primary = 1 limit 1",
dbesc($x['id']),
dbesc($x['id_sig'])
);
if ($r1) {
$found_primary = true;
}
$r2 = q("select xchan_hash from xchan where xchan_guid = '%s' and xchan_guid_sig = '%s' limit 1",
dbesc($x['id']),
dbesc($x['id_sig'])
);
$site_dead = false;
$primary_dead = false;
if ($r1 && intval($r1[0]['site_dead'])) {
$site_dead = true;
$primary_dead = true;
}
// We have valid and somewhat fresh information. Always true if it is our own site.
@@ -2615,13 +2627,14 @@ class Libzot {
// cached entry and the identity is valid. It's just unreachable until they bring back their
// server from the grave or create another clone elsewhere.
if ($site_dead) {
logger('dead site - ignoring', LOGGER_DEBUG, LOG_INFO);
if ($primary_dead || ! $found_primary) {
logger('dead or unknown primary site - ignoring', LOGGER_DEBUG, LOG_INFO);
$r = q("select hubloc_id_url from hubloc left join site on hubloc_url = site_url
where hubloc_hash = '%s' and site_dead = 0",
dbesc($hash)
);
if ($r) {
logger('found another site that is not dead: ' . $r[0]['hubloc_url'], LOGGER_DEBUG, LOG_INFO);
$desturl = $r[0]['hubloc_url'];
@@ -3147,4 +3160,10 @@ class Libzot {
}
static function update_cached_hubloc($hubloc) {
if ($hubloc['hubloc_updated'] > datetime_convert('UTC','UTC','now - 1 week') || $hubloc['hubloc_url'] === z_root()) {
return;
}
self::refresh( [ 'hubloc_id_url' => $hubloc['hubloc_id_url'] ] );
}
}

View File

@@ -503,7 +503,7 @@ 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']) : '')
);
$arr = array('item' => $item, 'output' => $tmp_item);
@@ -842,7 +842,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)') ]

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>';

View File

@@ -1,6 +1,6 @@
<?php /** @file */
namespace Zotlabs\Module;
namespace Zotlabs\Module;
//require_once('include/apps.php');
@@ -9,10 +9,10 @@ use \Zotlabs\Lib as Zlib;
class Appman extends \Zotlabs\Web\Controller {
function post() {
if(! local_channel())
return;
if($_POST['url']) {
$arr = array(
'uid' => intval($_REQUEST['uid']),
@@ -32,30 +32,30 @@ 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))
info( t('App installed.') . EOL);
goaway(z_root() . '/apps');
return; //not reached
}
$papp = Zlib\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))
info( t('App installed.') . EOL);
}
if($_POST['delete']) {
Zlib\Apps::app_destroy(local_channel(),$papp);
}
@@ -72,17 +72,21 @@ class Appman extends \Zotlabs\Web\Controller {
Zlib\Apps::app_feature(local_channel(), $papp, $_POST['pin']);
}
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;
@@ -130,11 +134,11 @@ class Appman extends \Zotlabs\Web\Controller {
}
$embed = array('embed', t('Embed code'), Zlib\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 +158,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

@@ -48,10 +48,8 @@ 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');

View File

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

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');

View File

@@ -873,10 +873,8 @@ class Cdav extends Controller {
if((argv(1) === 'addressbook') && (! Apps::system_app_installed(local_channel(), 'CardDAV'))) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('CardDAV App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('CalDAV capable addressbook');
return $o;
$papp = Apps::get_papp('CardDAV');
return Apps::app_render($papp, 'module');
}
App::$profile_uid = local_channel();

View File

@@ -74,7 +74,8 @@ class Channel extends Controller {
if ($sigdata && $sigdata['signer'] && $sigdata['header_valid']) {
$data = json_encode(Libzot::zotinfo(['address' => $channel['channel_address'], 'target_url' => $sigdata['signer']]));
$s = q("select site_crypto, hubloc_sitekey from site left join hubloc on hubloc_url = site_url where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
$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'])
);
@@ -107,13 +108,11 @@ class Channel extends Controller {
// Somebody may attempt an ActivityStreams fetch on one of our message permalinks
// Make it do the right thing.
$mid = ((x($_REQUEST, 'mid')) ? $_REQUEST['mid'] : '');
if ($mid && strpos($mid, 'b64.') === 0) {
$decoded = @base64url_decode(substr($mid, 4));
if ($decoded) {
$mid = $decoded;
}
$mid = ((x($_REQUEST, 'mid')) ? unpack_link_id($_REQUEST['mid']) : '');
if ($mid === false) {
http_status_exit(404, 'Not found');
}
if ($mid) {
$obj = null;
if (strpos($mid, z_root() . '/item/') === 0) {
@@ -158,15 +157,19 @@ class Channel extends Controller {
profile_load($which, $profile);
// Add Opengraph markup
$mid = ((x($_REQUEST, 'mid')) ? $_REQUEST['mid'] : '');
if (strpos($mid, 'b64.') === 0)
$mid = @base64url_decode(substr($mid, 4));
$mid = ((x($_REQUEST, 'mid')) ? unpack_link_id($_REQUEST['mid']) : '');
if ($mid)
if ($mid === false) {
notice(t('Malformed message id.') . EOL);
return;
}
if ($mid) {
$r = q("SELECT * FROM item WHERE mid = '%s' AND uid = %d AND item_private = 0 LIMIT 1",
dbesc($mid),
intval($channel['channel_id'])
);
}
opengraph_add_meta((isset($r) && count($r) ? $r[0] : []), $channel);
}
@@ -177,12 +180,11 @@ class Channel extends Controller {
$category = $datequery = $datequery2 = '';
$mid = ((x($_REQUEST, 'mid')) ? $_REQUEST['mid'] : '');
if (strpos($mid, 'b64.') === 0)
$decoded = @base64url_decode(substr($mid, 4));
if (isset($decoded))
$mid = $decoded;
$mid = ((x($_REQUEST, 'mid')) ? unpack_link_id($_REQUEST['mid']) : '');
if ($mid === false) {
notice(t('Malformed message id.') . EOL);
return;
}
$datequery = ((x($_GET, 'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : '');
$datequery2 = ((x($_GET, 'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : '');
@@ -226,7 +228,7 @@ class Channel extends Controller {
if (!$update) {
nav_set_selected('Channel Home');
nav_set_selected('Channel');
// search terms header
if ($search) {
@@ -433,8 +435,8 @@ class Channel extends Controller {
if ((!$update) && (!$load)) {
if (isset($decoded))
$mid = 'b64.' . base64url_encode($mid);
//if we got a decoded hash we must encode it again before handing to javascript
$mid = gen_link_id($mid);
// This is ugly, but we can't pass the profile_uid through the session to the ajax updater,
// because browser prefetching might change it on us. We have to deliver it with the page.

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

@@ -19,13 +19,13 @@ class Defperms extends Controller {
*/
function init() {
if(! local_channel())
return;
if(! Apps::system_app_installed(local_channel(), 'Default Permissions'))
return;
$r = q("SELECT abook.*, xchan.*
FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_self = 1 and abook_channel = %d LIMIT 1",
@@ -37,39 +37,39 @@ class Defperms extends Controller {
$channel = App::get_channel();
if($channel)
head_set_icon($channel['xchan_photo_s']);
head_set_icon($channel['xchan_photo_s']);
}
/* @brief Evaluate posted values and set changes
*
*/
function post() {
if(! local_channel())
return;
if(! Apps::system_app_installed(local_channel(), 'Default Permissions'))
return;
$contact_id = intval(argv(1));
if(! $contact_id)
return;
$channel = App::get_channel();
$orig_record = q("SELECT * FROM abook WHERE abook_id = %d AND abook_channel = %d LIMIT 1",
intval($contact_id),
intval(local_channel())
);
if(! $orig_record) {
notice( t('Could not access contact record.') . EOL);
goaway(z_root() . '/connections');
return; // NOTREACHED
}
if(intval($orig_record[0]['abook_self'])) {
$autoperms = intval($_POST['autoperms']);
@@ -79,8 +79,8 @@ class Defperms extends Controller {
$autoperms = null;
$is_self = false;
}
$all_perms = \Zotlabs\Access\Permissions::Perms();
if($all_perms) {
@@ -105,15 +105,15 @@ class Defperms extends Controller {
}
}
if(! is_null($autoperms))
if(! is_null($autoperms))
set_pconfig($channel['channel_id'],'system','autoperms',$autoperms);
notice( t('Settings updated.') . EOL);
// Refresh the structure in memory with the new data
$r = q("SELECT abook.*, xchan.*
FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_channel = %d and abook_id = %d LIMIT 1",
@@ -123,28 +123,28 @@ class Defperms extends Controller {
if($r) {
App::$poi = $r[0];
}
$this->defperms_clone($a);
goaway(z_root() . '/defperms');
return;
}
/* @brief Clone connection
*
*
*/
function defperms_clone(&$a) {
if(! App::$poi)
return;
$channel = App::get_channel();
$r = q("SELECT abook.*, xchan.*
FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_channel = %d and abook_id = %d LIMIT 1",
@@ -154,30 +154,30 @@ class Defperms extends Controller {
if($r) {
App::$poi = array_shift($r);
}
$clone = App::$poi;
unset($clone['abook_id']);
unset($clone['abook_account']);
unset($clone['abook_channel']);
$abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']);
if($abconfig)
$clone['abconfig'] = $abconfig;
Libsync::build_sync_packet(0 /* use the current local_channel */, array('abook' => array($clone)));
}
/* @brief Generate content of connection default permissions page
*
*
*/
function get() {
$sort_type = 0;
$o = '';
if(! local_channel()) {
notice( t('Permission denied.') . EOL);
return login();
@@ -186,17 +186,15 @@ class Defperms extends Controller {
if(! Apps::system_app_installed(local_channel(), 'Default Permissions')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Default Permissions App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('Set custom default permissions for new connections');
return $o;
$papp = Apps::get_papp('Default Permissions');
return Apps::app_render($papp, 'module');
}
$section = ((array_key_exists('section',$_REQUEST)) ? $_REQUEST['section'] : '');
$channel = App::get_channel();
$yes_no = array(t('No'),t('Yes'));
$connect_perms = \Zotlabs\Access\Permissions::connect_perms(local_channel());
$o .= "<script>function connectDefaultShare() {
@@ -210,28 +208,28 @@ class Defperms extends Controller {
}
}
$o .= " }\n</script>\n";
if(App::$poi) {
$sections = [];
$self = false;
$tpl = get_markup_template('defperms.tpl');
$perms = array();
$channel = App::get_channel();
$contact = App::$poi;
$global_perms = \Zotlabs\Access\Permissions::Perms();
$hidden_perms = [];
foreach($global_perms as $k => $v) {
$thisperm = get_abconfig(local_channel(),$contact['abook_xchan'],'my_perms',$k);
$checkinherited = \Zotlabs\Access\PermissionLimits::Get(local_channel(),$k);
$inherited = (($checkinherited & PERMS_SPECIFIC) ? false : true);
@@ -241,7 +239,7 @@ class Defperms extends Controller {
$hidden_perms[] = [ 'perms_' . $k, intval($thisperm) ];
}
}
$pcat = new \Zotlabs\Lib\Permcat(local_channel());
$pcatlist = $pcat->listing();
$permcats = [];
@@ -272,13 +270,13 @@ class Defperms extends Controller {
'$contact_id' => $contact['abook_id'],
'$name' => $contact['xchan_name'],
]);
$arr = array('contact' => $contact,'output' => $o);
call_hooks('contact_edit', $arr);
return $arr['output'];
}
}
}
}

View File

@@ -1,6 +1,8 @@
<?php
namespace Zotlabs\Module;
use App;
require_once("include/bbcode.php");
require_once('include/security.php');
require_once('include/conversation.php');
@@ -34,11 +36,20 @@ class Display extends \Zotlabs\Web\Controller {
}
}
if($_REQUEST['mid'])
if($_REQUEST['mid']) {
$item_hash = $_REQUEST['mid'];
}
if(! $item_hash) {
\App::$error = 404;
$item_hash = unpack_link_id($item_hash);
if ($item_hash === false) {
App::$error = 400;
notice(t('Malformed message id.') . EOL);
return;
}
if(!$item_hash) {
App::$error = 404;
notice( t('Item not found.') . EOL);
return;
}
@@ -47,7 +58,7 @@ class Display extends \Zotlabs\Web\Controller {
if(local_channel() && (! $update)) {
$channel = \App::get_channel();
$channel = App::get_channel();
$channel_acl = array(
'allow_cid' => $channel['channel_allow_cid'],
@@ -92,11 +103,6 @@ class Display extends \Zotlabs\Web\Controller {
$target_item = null;
if(strpos($item_hash,'b64.') === 0)
$decoded = @base64url_decode(substr($item_hash,4));
if($decoded)
$item_hash = $decoded;
$r = q("select id, uid, mid, parent, parent_mid, thr_parent, verb, item_type, item_deleted, author_xchan, item_blocked from item where mid = '%s' limit 1",
dbesc($item_hash)
);
@@ -110,7 +116,7 @@ class Display extends \Zotlabs\Web\Controller {
);
if($x) {
// not yet ready for prime time
// \App::$poi = $x[0];
// App::$poi = $x[0];
}
//if the item is to be moderated redirect to /moderate
@@ -189,17 +195,15 @@ class Display extends \Zotlabs\Web\Controller {
// if the target item is not a post (eg a like) we want to address its thread parent
//$mid = ((($target_item['verb'] == ACTIVITY_LIKE) || ($target_item['verb'] == ACTIVITY_DISLIKE)) ? $target_item['thr_parent'] : $target_item['mid']);
$mid = $target_item['mid'];
// if we got a decoded hash we must encode it again before handing to javascript
if($decoded)
$mid = 'b64.' . base64url_encode($mid);
$mid = gen_link_id($target_item['mid']);
$o .= '<div id="live-display"></div>' . "\r\n";
$o .= "<script> var profile_uid = " . ((intval(local_channel())) ? local_channel() : (-1))
. "; var netargs = '?f='; var profile_page = " . \App::$pager['page'] . "; </script>\r\n";
. "; var netargs = '?f='; var profile_page = " . App::$pager['page'] . "; </script>\r\n";
\App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array(
App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array(
'$baseurl' => z_root(),
'$pgtype' => 'display',
'$uid' => '0',
@@ -215,7 +219,7 @@ class Display extends \Zotlabs\Web\Controller {
'$dm' => '0',
'$nouveau' => '0',
'$wall' => '0',
'$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1),
'$page' => ((App::$pager['page'] != 1) ? App::$pager['page'] : 1),
'$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0),
'$search' => '',
'$xchan' => '',
@@ -233,7 +237,7 @@ class Display extends \Zotlabs\Web\Controller {
head_add_link([
'rel' => 'alternate',
'type' => 'application/json+oembed',
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string),
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . App::$query_string),
'title' => 'oembed'
]);
@@ -355,7 +359,7 @@ class Display extends \Zotlabs\Web\Controller {
}
$o .= '</noscript>';
\App::$page['title'] = (($items[0]['title']) ? $items[0]['title'] . " - " . \App::$page['title'] : \App::$page['title']);
App::$page['title'] = (($items[0]['title']) ? $items[0]['title'] . " - " . App::$page['title'] : App::$page['title']);
$o .= conversation($items, 'display', $update, 'client');
}
@@ -368,12 +372,12 @@ class Display extends \Zotlabs\Web\Controller {
'$version' => xmlify(\Zotlabs\Lib\System::get_project_version()),
'$generator' => xmlify(\Zotlabs\Lib\System::get_platform_name()),
'$generator_uri' => 'https://hubzilla.org',
'$feed_id' => xmlify(\App::$cmd),
'$feed_id' => xmlify(App::$cmd),
'$feed_title' => xmlify(t('Article')),
'$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now', ATOM_TIME)),
'$author' => '',
'$owner' => '',
'$profile_page' => xmlify(z_root() . '/display/' . $target_item['mid']),
'$profile_page' => xmlify(z_root() . '/display/' . gen_link_id($target_item['mid'])),
));
$x = [ 'xml' => $atom, 'channel' => $channel, 'observer_hash' => $observer_hash, 'params' => $params ];

View File

@@ -12,24 +12,12 @@ class Dreport extends \Zotlabs\Web\Controller {
}
$table = 'item';
$channel = \App::get_channel();
$mid = ((argc() > 1) ? unpack_link_id(argv(1)) : '');
$mid = ((argc() > 1) ? argv(1) : '');
$encoded_mid = '';
if(strpos($mid,'b64.') === 0) {
$encoded_mid = $mid;
$mid = @base64url_decode(substr($mid,4));
}
if($mid === 'push') {
$table = 'push';
$mid = ((argc() > 2) ? argv(2) : '');
if(strpos($mid,'b64.') === 0) {
$encoded_mid = $mid;
$mid = @base64url_decode(substr($mid,4));
}
$mid = ((argc() > 2) ? unpack_link_id(argv(2)) : '');
if($mid) {
$i = q("select id from item where mid = '%s' and uid = %d and ( author_xchan = '%s' or ( owner_xchan = '%s' and item_wall = 1 )) ",
@@ -43,18 +31,9 @@ class Dreport extends \Zotlabs\Web\Controller {
}
}
sleep(3);
goaway(z_root() . '/dreport/' . (($encoded_mid) ? $encoded_mid : $mid));
goaway(z_root() . '/dreport/' . gen_link_id($mid));
}
if($mid === 'mail') {
$table = 'mail';
$mid = ((argc() > 2) ? argv(2) : '');
if(strpos($mid,'b64.') === 0)
$mid = @base64url_decode(substr($mid,4));
}
if(! $mid) {
notice( t('Invalid message') . EOL);
return;
@@ -68,12 +47,6 @@ class Dreport extends \Zotlabs\Web\Controller {
dbesc($channel['channel_hash'])
);
break;
case 'mail':
$i = q("select id from mail where mid = '%s' and from_xchan = '%s'",
dbesc($mid),
dbesc($channel['channel_hash'])
);
break;
default:
break;
}
@@ -131,15 +104,6 @@ class Dreport extends \Zotlabs\Web\Controller {
case 'recipient not found':
$r[$x]['dreport_result'] = t('recipient not found');
break;
case 'mail recalled':
$r[$x]['dreport_result'] = t('mail recalled');
break;
case 'duplicate mail received':
$r[$x]['dreport_result'] = t('duplicate mail received');
break;
case 'mail delivered':
$r[$x]['dreport_result'] = t('mail delivered');
break;
default:
$r[$x]['gravity'] = 1;
break;

View File

@@ -26,7 +26,7 @@ class Group extends Controller {
}
function post() {
if(! local_channel()) {
notice( t('Permission denied.') . EOL);
return;
@@ -35,10 +35,10 @@ class Group extends Controller {
if(! Apps::system_app_installed(local_channel(), 'Privacy Groups')) {
return;
}
if((argc() == 2) && (argv(1) === 'new')) {
check_form_security_token_redirectOnErr('/group/new', 'group_edit');
$name = notags(trim($_POST['groupname']));
$public = intval($_POST['public']);
$r = group_add(local_channel(),$name,$public);
@@ -49,11 +49,11 @@ class Group extends Controller {
notice( t('Could not create privacy group.') . EOL );
}
goaway(z_root() . '/group');
}
if((argc() == 2) && (intval(argv(1)))) {
check_form_security_token_redirectOnErr('/group', 'group_edit');
$r = q("SELECT * FROM pgrp WHERE id = %d AND uid = %d LIMIT 1",
intval(argv(1)),
intval(local_channel())
@@ -61,12 +61,12 @@ class Group extends Controller {
if(! $r) {
notice( t('Privacy group not found.') . EOL );
goaway(z_root() . '/connections');
}
$group = $r[0];
$groupname = notags(trim($_POST['groupname']));
$public = intval($_POST['public']);
$hookinfo = [ 'pgrp_extras' => '', 'group'=>$group['id'] ];
call_hooks ('privacygroup_extras_post',$hookinfo);
@@ -83,18 +83,14 @@ class Group extends Controller {
Libsync::build_sync_packet(local_channel(),null,true);
}
goaway(z_root() . '/group/' . argv(1) . '/' . argv(2));
}
return;
return;
}
function get() {
$change = false;
logger('mod_group: ' . App::$cmd,LOGGER_DEBUG);
if(! local_channel()) {
notice( t('Permission denied') . EOL);
return;
@@ -103,12 +99,14 @@ class Group extends Controller {
if(! Apps::system_app_installed(local_channel(), 'Privacy Groups')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Privacy Groups App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('Management of privacy groups');
return $o;
$papp = Apps::get_papp('Privacy Groups');
return Apps::app_render($papp, 'module');
}
logger('mod_group: ' . App::$cmd,LOGGER_DEBUG);
$change = false;
// Switch to text mode interface if we have more than 'n' contacts or group members
$switchtotext = get_pconfig(local_channel(),'system','groupedit_image_limit');
if($switchtotext === false)
@@ -166,16 +164,16 @@ class Group extends Controller {
$context = array('$submit' => t('Submit'));
$tpl = get_markup_template('group_edit.tpl');
if((argc() == 3) && (argv(1) === 'drop')) {
check_form_security_token_redirectOnErr('/group', 'group_drop', 't');
if(intval(argv(2))) {
$r = q("SELECT gname FROM pgrp WHERE id = %d AND uid = %d LIMIT 1",
intval(argv(2)),
intval(local_channel())
);
if($r)
if($r)
$result = group_rmv(local_channel(),$r[0]['gname']);
if($result) {
$hookinfo = [ 'pgrp_extras' => '', 'group' => argv(2) ];
@@ -188,23 +186,23 @@ class Group extends Controller {
goaway(z_root() . '/group');
// NOTREACHED
}
if((argc() > 2) && intval(argv(1)) && argv(2)) {
check_form_security_token_ForbiddenOnErr('group_member_change', 't');
$r = q("SELECT abook_xchan from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 limit 1",
dbesc(base64url_decode(argv(2))),
intval(local_channel())
);
if(count($r))
$change = base64url_decode(argv(2));
}
if((argc() > 1) && (intval(argv(1)))) {
require_once('include/acl_selectors.php');
$r = q("SELECT * FROM pgrp WHERE id = %d AND uid = %d AND deleted = 0 LIMIT 1",
intval(argv(1)),
@@ -215,28 +213,28 @@ class Group extends Controller {
goaway(z_root() . '/connections');
}
$group = $r[0];
$members = group_get_members($group['id']);
$preselected = array();
if(count($members)) {
foreach($members as $member)
if(! in_array($member['xchan_hash'],$preselected))
$preselected[] = $member['xchan_hash'];
}
if($change) {
if(in_array($change,$preselected)) {
group_rmv_member(local_channel(),$group['gname'],$change);
}
else {
group_add_member(local_channel(),$group['gname'],$change);
}
$members = group_get_members($group['id']);
$preselected = array();
if(count($members)) {
foreach($members as $member)
@@ -260,19 +258,19 @@ class Group extends Controller {
'$form_security_token_drop' => get_form_security_token("group_drop"),
'$pgrp_extras' => $pgrp_extras,
);
}
if(! isset($group))
return;
$groupeditor = array(
'label_members' => t('Group members'),
'members' => array(),
'label_contacts' => t('Not in this group'),
'contacts' => array(),
);
$sec_token = addslashes(get_form_security_token('group_member_change'));
$textmode = (($switchtotext && (count($members) > $switchtotext)) ? true : 'card');
foreach($members as $member) {
@@ -284,11 +282,11 @@ class Group extends Controller {
else
group_rmv_member(local_channel(),$group['gname'],$member['xchan_hash']);
}
$r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d AND abook_self = 0 and abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 order by xchan_name asc",
intval(local_channel())
);
if(count($r)) {
$textmode = (($switchtotext && (count($r) > $switchtotext)) ? true : 'card');
foreach($r as $member) {
@@ -299,20 +297,20 @@ class Group extends Controller {
}
}
}
$context['$groupeditor'] = $groupeditor;
$context['$desc'] = t('Click a channel to toggle membership');
$context['$pgrp_extras'] = $pgrp_extras;
if($change) {
$tpl = get_markup_template('groupeditor.tpl');
echo replace_macros($tpl, $context);
killme();
}
return replace_macros($tpl, $context);
}
}

View File

@@ -23,15 +23,21 @@ class Hq extends \Zotlabs\Web\Controller {
function get($update = 0, $load = false) {
if(!local_channel())
if(!local_channel()) {
return;
}
if(argc() > 1 && argv(1) !== 'load') {
$item_hash = argv(1);
$item_hash = unpack_link_id(argv(1));
}
if(isset($_REQUEST['mid'])) {
$item_hash = $_REQUEST['mid'];
$item_hash = unpack_link_id($_REQUEST['mid']);
}
if($item_hash === false) {
notice(t('Malformed message id.') . EOL);
return;
}
$item_normal = item_normal();
@@ -41,22 +47,17 @@ class Hq extends \Zotlabs\Web\Controller {
$r = q("SELECT mid FROM item
WHERE uid = %d $item_normal
AND mid = parent_mid
AND item_private IN (0, 1)
ORDER BY created DESC LIMIT 1",
intval(local_channel())
);
if($r[0]['mid']) {
$item_hash = 'b64.' . base64url_encode($r[0]['mid']);
$item_hash = $r[0]['mid'];
}
}
if($item_hash) {
if(strpos($item_hash,'b64.') === 0)
$decoded = @base64url_decode(substr($item_hash,4));
if($decoded)
$item_hash = $decoded;
$target_item = null;
$r = q("select id, uid, mid, parent_mid, thr_parent, verb, item_type, item_deleted, item_blocked from item where mid = '%s' limit 1",
@@ -124,10 +125,9 @@ class Hq extends \Zotlabs\Web\Controller {
if($target_item) {
// if the target item is not a post (eg a like) we want to address its thread parent
//$mid = ((($target_item['verb'] == ACTIVITY_LIKE) || ($target_item['verb'] == ACTIVITY_DISLIKE)) ? $target_item['thr_parent'] : $target_item['mid']);
$mid = $target_item['mid'];
// if we got a decoded hash we must encode it again before handing to javascript
if($decoded)
$mid = 'b64.' . base64url_encode($mid);
$mid = gen_link_id($target_item['mid']);
}
else {
$mid = '';

View File

@@ -306,9 +306,8 @@ class Invite extends Controller {
if(! Apps::system_app_installed(local_channel(), 'Invite')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = 'ZAI0102E,' . t('Invite App') . ' (' . t('Not Installed') . ')' . EOL;
return $o;
$papp = Apps::get_papp('Invite');
return Apps::app_render($papp, 'module');
}
if (! (get_config('system','invitation_also') || get_config('system','invitation_only')) ) {

View File

@@ -1377,6 +1377,10 @@ class Item extends Controller {
return $post;
if($return_path) {
if($return_path === 'hq') {
goaway(z_root() . '/hq/' . gen_link_id($datarray['mid']));
}
goaway(z_root() . "/" . $return_path);
}

View File

@@ -28,9 +28,9 @@ class Lang extends Controller {
}
}
$lc = x($_POST['zinlc']) && preg_match('/^\?\?|[a-z]{2,2}[x_\-]{0,1}[a-zA-Z]{0,2}$/', $_POST['zinlc'])
$lc = x($_POST['zinlc']) && preg_match('/^\?\?|[a-z]{2,2}[x_\-]{0,1}[a-zA-Z]{0,2}$/', $_POST['zinlc'])
? $_POST['zinlc'] : '';
$lcs= x($_POST['zinlcs']) && preg_match('/^[a-z,_\-]{0,191}$/', $_POST['zinlcs'])
$lcs= x($_POST['zinlcs']) && preg_match('/^[a-z,_\-]{0,191}$/', $_POST['zinlcs'])
? $_POST['zinlcs'] : '';
if ($isajax) {
@@ -57,12 +57,10 @@ class Lang extends Controller {
if(local_channel()) {
if(! Apps::system_app_installed(local_channel(), 'Language')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Language App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('Change UI language');
return $o;
//Do not display any associated widgets at this point
App::$pdl = '';
$papp = Apps::get_papp('Language');
return Apps::app_render($papp, 'module');
}
}
@@ -70,5 +68,5 @@ class Lang extends Controller {
return lang_selector();
}
}

View File

@@ -5,37 +5,37 @@ namespace Zotlabs\Module;
class Linkinfo extends \Zotlabs\Web\Controller {
function get() {
logger('linkinfo: ' . print_r($_REQUEST,true));
$text = null;
$str_tags = '';
$process_oembed = true;
$process_oembed = true;
$br = "\n";
if(x($_GET,'binurl'))
$url = trim(hex2bin($_GET['binurl']));
else
$url = trim($_GET['url']);
if(substr($url,0,1) === '!') {
$process_oembed = false;
$url = substr($url,1);
}
$url = strip_zids($url);
if((substr($url,0,1) != '/') && (substr($url,0,4) != 'http'))
$url = 'http://' . $url;
if($_GET['title'])
$title = strip_tags(trim($_GET['title']));
if($_GET['description'])
$text = strip_tags(trim($_GET['description']));
if($_GET['tags']) {
$arr_tags = str_getcsv($_GET['tags']);
if(count($arr_tags)) {
@@ -43,23 +43,25 @@ class Linkinfo extends \Zotlabs\Web\Controller {
$str_tags = $br . implode(' ',$arr_tags) . $br;
}
}
logger('linkinfo: ' . $url);
// Replace plink URL with 'share' tag if possible
preg_match("/(mid=b64\.|display\/|posts\/)([\w\-]+)(&.+)?$/", $url, $mid);
if (!empty($mid) && $mid[1] == 'mid=b64.')
$mid[2] = base64_decode($mid[2]);
// Replace plink URL with 'share' tag if possible
preg_match("/(mid=b64\.|display\/|posts\/)([\w\-]+)(&.+)?$/", $url, $mid);
$r = q("SELECT id FROM item WHERE mid = '%s' AND uid = %d AND item_private = 0 LIMIT 1",
dbesc((empty($mid) ? $url : $mid[2])),
intval(local_channel())
);
if ($r) {
echo "[share=" . $r[0]['id'] . "][/share]";
killme();
}
if (!empty($mid)) {
$mid[2] = unpack_link_id($mid[2]);
}
$r = q("SELECT id FROM item WHERE mid = '%s' AND uid = %d AND item_private = 0 LIMIT 1",
dbesc((empty($mid) ? $url : $mid[2])),
intval(local_channel())
);
if ($r) {
echo "[share=" . $r[0]['id'] . "][/share]";
killme();
}
$result = z_fetch_url($url,false,0,array('novalidate' => true, 'nobody' => true));
if($result['success']) {
@@ -108,13 +110,13 @@ class Linkinfo extends \Zotlabs\Web\Controller {
}
}
}
$template = $br . '#^[url=%s]%s[/url]%s' . $br;
$arr = array('url' => $url, 'text' => '');
call_hooks('parse_link', $arr);
if(strlen($arr['text'])) {
echo $arr['text'];
killme();
@@ -127,28 +129,28 @@ class Linkinfo extends \Zotlabs\Web\Controller {
killme();
}
}
if($url && $title && $text) {
$text = $br . '[quote]' . trim($text) . '[/quote]' . $br;
$title = str_replace(array("\r","\n"),array('',''),$title);
$result = sprintf($template,$url,($title) ? $title : $url,$text) . $str_tags;
logger('linkinfo (unparsed): returns: ' . $result);
echo $result;
killme();
}
$siteinfo = self::parseurl_getsiteinfo($url);
// If the site uses this platform, use zrl rather than url so they get zids sent to them by default
if(is_matrix_url($url))
$template = str_replace('url','zrl',$template);
if($siteinfo["title"] == "") {
echo sprintf($template,$url,$url,'') . $str_tags;
killme();
@@ -156,19 +158,19 @@ class Linkinfo extends \Zotlabs\Web\Controller {
$text = $siteinfo["text"];
$title = $siteinfo["title"];
}
$image = "";
if(is_array($siteinfo["images"]) && count($siteinfo["images"])){
/* Execute below code only if image is present in siteinfo */
$total_images = 0;
$max_images = get_config('system','max_bookmark_images');
if($max_images === false)
$max_images = 2;
else
$max_images = intval($max_images);
foreach ($siteinfo["images"] as $imagedata) {
if ($url) {
$image .= sprintf('[url=%s]', $url);
@@ -183,57 +185,57 @@ class Linkinfo extends \Zotlabs\Web\Controller {
break;
}
}
if(strlen($text)) {
$text = $br.'[quote]'.trim($text).'[/quote]'.$br ;
}
if($image) {
$text = $br.$br.$image.$text;
}
$title = str_replace(array("\r","\n"),array('',''),$title);
$result = sprintf($template,$url,($title) ? $title : $url,$text) . $str_tags;
logger('linkinfo: returns: ' . $result, LOGGER_DEBUG);
echo trim($result);
killme();
}
public static function deletexnode(&$doc, $node) {
$xpath = new \DomXPath($doc);
$list = $xpath->query("//".$node);
foreach ($list as $child)
$child->parentNode->removeChild($child);
}
public static function completeurl($url, $scheme) {
$urlarr = parse_url($url);
if (isset($urlarr["scheme"]))
return($url);
$schemearr = parse_url($scheme);
$complete = $schemearr["scheme"]."://".$schemearr["host"];
if ($schemearr["port"] != "")
$complete .= ":".$schemearr["port"];
if(strpos($urlarr['path'],'/') !== 0)
$complete .= '/';
$complete .= $urlarr["path"];
if ($urlarr["query"] != "")
$complete .= "?".$urlarr["query"];
if ($urlarr["fragment"] != "")
$complete .= "#".$urlarr["fragment"];
return($complete);
}
@@ -251,7 +253,7 @@ class Linkinfo extends \Zotlabs\Web\Controller {
$p = substr($m,strpos($m,'/')+1);
// get the channel to check permissions
$u = channelx_by_nick($nick);
if($u && $p) {
@@ -272,18 +274,18 @@ class Linkinfo extends \Zotlabs\Web\Controller {
return EMPTY_STR;
}
public static function parseurl_getsiteinfo($url) {
$siteinfo = array();
$result = z_fetch_url($url,false,0,array('novalidate' => true));
if(! $result['success'])
return $siteinfo;
$header = $result['header'];
$body = $result['body'];
// Check codepage in HTTP headers or HTML if not exist
$cp = (preg_match('/Content-Type: text\/html; charset=(.+)\r\n/i', $header, $o) ? $o[1] : '');
if(empty($cp))
@@ -291,10 +293,10 @@ class Linkinfo extends \Zotlabs\Web\Controller {
$body = mb_convert_encoding($body, 'UTF-8', $cp);
$body = mb_convert_encoding($body, 'HTML-ENTITIES', "UTF-8");
$doc = new \DOMDocument();
@$doc->loadHTML($body);
self::deletexnode($doc, 'style');
self::deletexnode($doc, 'script');
self::deletexnode($doc, 'option');
@@ -306,14 +308,14 @@ class Linkinfo extends \Zotlabs\Web\Controller {
self::deletexnode($doc, 'h6');
self::deletexnode($doc, 'ol');
self::deletexnode($doc, 'ul');
$xpath = new \DomXPath($doc);
//$list = $xpath->query("head/title");
$list = $xpath->query("//title");
foreach ($list as $node)
$siteinfo["title"] = html_entity_decode($node->nodeValue, ENT_QUOTES, "UTF-8");
//$list = $xpath->query("head/meta[@name]");
$list = $xpath->query("//meta[@name]");
foreach ($list as $node) {
@@ -321,9 +323,9 @@ class Linkinfo extends \Zotlabs\Web\Controller {
if ($node->attributes->length)
foreach ($node->attributes as $attribute)
$attr[$attribute->name] = $attribute->value;
$attr["content"] = html_entity_decode($attr["content"], ENT_QUOTES, "UTF-8");
switch (strtolower($attr["name"])) {
case "fulltitle":
$siteinfo["title"] = trim($attr["content"]);
@@ -365,7 +367,7 @@ class Linkinfo extends \Zotlabs\Web\Controller {
break;
}
}
//$list = $xpath->query("head/meta[@property]");
$list = $xpath->query("//meta[@property]");
foreach ($list as $node) {
@@ -373,9 +375,9 @@ class Linkinfo extends \Zotlabs\Web\Controller {
if ($node->attributes->length)
foreach ($node->attributes as $attribute)
$attr[$attribute->name] = $attribute->value;
$attr["content"] = html_entity_decode($attr["content"], ENT_QUOTES, "UTF-8");
switch (strtolower($attr["property"])) {
case "og:image":
$siteinfo["image"] = $attr["content"];
@@ -388,7 +390,7 @@ class Linkinfo extends \Zotlabs\Web\Controller {
break;
}
}
if ($siteinfo["image"] == "") {
$list = $xpath->query("//img[@src]");
foreach ($list as $node) {
@@ -396,10 +398,10 @@ class Linkinfo extends \Zotlabs\Web\Controller {
if ($node->attributes->length)
foreach ($node->attributes as $attribute)
$attr[$attribute->name] = $attribute->value;
$src = self::completeurl($attr["src"], $url);
$photodata = @getimagesize($src);
if (($photodata) && ($photodata[0] > 150) and ($photodata[1] > 150)) {
if ($photodata[0] > 300) {
$photodata[1] = round($photodata[1] * (300 / $photodata[0]));
@@ -413,36 +415,36 @@ class Linkinfo extends \Zotlabs\Web\Controller {
"width"=>$photodata[0],
"height"=>$photodata[1]);
}
}
} else {
$src = self::completeurl($siteinfo["image"], $url);
unset($siteinfo["image"]);
$photodata = @getimagesize($src);
if (($photodata) && ($photodata[0] > 10) and ($photodata[1] > 10))
$siteinfo["images"][] = array("src"=>$src,
"width"=>$photodata[0],
"height"=>$photodata[1]);
}
if ($siteinfo["text"] == "") {
$text = "";
$list = $xpath->query("//div[@class='article']");
foreach ($list as $node)
if (strlen($node->nodeValue) > 40)
$text .= " ".trim($node->nodeValue);
if ($text == "") {
$list = $xpath->query("//div[@class='content']");
foreach ($list as $node)
if (strlen($node->nodeValue) > 40)
$text .= " ".trim($node->nodeValue);
}
// If none text was found then take the paragraph content
if ($text == "") {
$list = $xpath->query("//p");
@@ -450,21 +452,21 @@ class Linkinfo extends \Zotlabs\Web\Controller {
if (strlen($node->nodeValue) > 40)
$text .= " ".trim($node->nodeValue);
}
if ($text != "") {
$text = trim(str_replace(array("\n", "\r"), array(" ", " "), $text));
while (strpos($text, " "))
$text = trim(str_replace(" ", " ", $text));
$text = substr(html_entity_decode($text, ENT_QUOTES, "UTF-8"), 0, 350);
$siteinfo["text"] = rtrim(substr($text, 0, strrpos($text, " ")), "?.,:;!-") . '...';
}
}
return($siteinfo);
}
private static function arr_add_hashes(&$item,$k) {
$item = '#' . $item;

View File

@@ -157,7 +157,7 @@ class Manage extends \Zotlabs\Web\Controller {
}
$o = replace_macros(get_markup_template('channels.tpl'), array(
'$header' => t('Channel Manager'),
'$header' => t('Channels'),
'$msg_selected' => t('Current Channel'),
'$selected' => local_channel(),
'$desc' => ((count($channels) > 1 || $delegates) ? t('Switch to one of your channels by selecting it.') : ''),

View File

@@ -0,0 +1,50 @@
<?php
namespace Zotlabs\Module;
use App;
use Zotlabs\Web\Controller;
use Zotlabs\Lib\System;
class Manifest extends Controller {
function init() {
$ret = [
'name' => ucfirst(System::get_platform_name()),
'short_name' => ucfirst(System::get_platform_name()),
'icons' => [
[ 'src' => '/images/app/hz-72.png', 'sizes' => '72x72', 'type' => 'image/png' ],
[ 'src' => '/images/app/hz-96.png', 'sizes' => '96x96', 'type' => 'image/png' ],
[ 'src' => '/images/app/hz-128.png', 'sizes' => '128x128', 'type' => 'image/png' ],
[ 'src' => '/images/app/hz-144.png', 'sizes' => '144x144', 'type' => 'image/png' ],
[ 'src' => '/images/app/hz-152.png', 'sizes' => '152x152', 'type' => 'image/png' ],
[ 'src' => '/images/app/hz-192.png', 'sizes' => '192x192', 'type' => 'image/png' ],
[ 'src' => '/images/app/hz-348.png', 'sizes' => '384x384', 'type' => 'image/png' ],
[ 'src' => '/images/app/hz-512.png', 'sizes' => '512x512', 'type' => 'image/png' ],
[ 'src' => '/images/app/hz.svg', 'sizes' => '64x64', 'type' => 'image/xml+svg' ]
],
'scope' => '/',
'start_url' => z_root(),
'display' => 'standalone',
'orientation' => 'any',
'share_target' => [
'action' => '/rpost',
'method' => 'POST',
'enctype' => 'multipart/form-data',
'params' => [
'title' => 'title',
'text' => 'body',
'url' => 'url',
'files' => [
[ 'name' => 'userfile',
'accept' => [ 'image/*', 'audio/*', 'video/*', 'text/*', 'application/*' ]
]
]
]
]
];
json_return_and_die($ret,'application/manifest+json');
}
}

View File

@@ -14,36 +14,36 @@ require_once('include/items.php');
class Mood extends Controller {
function init() {
if(! local_channel())
return;
if(! Apps::system_app_installed(local_channel(), 'Mood')) {
return;
}
$uid = local_channel();
$channel = App::get_channel();
$verb = notags(trim($_GET['verb']));
if(! $verb)
if(! $verb)
return;
$verbs = get_mood_verbs();
if(! array_key_exists($verb,$verbs))
return;
$activity = ACTIVITY_MOOD . '#' . urlencode($verb);
$parent = ((x($_GET,'parent')) ? intval($_GET['parent']) : 0);
logger('mood: verb ' . $verb, LOGGER_DEBUG);
if($parent) {
$r = q("select mid, owner_xchan, private, allow_cid, allow_gid, deny_cid, deny_gid
$r = q("select mid, owner_xchan, private, allow_cid, allow_gid, deny_cid, deny_gid
from item where id = %d and parent = %d and uid = %d limit 1",
intval($parent),
intval($parent),
@@ -59,24 +59,24 @@ class Mood extends Controller {
}
}
else {
$private = 0;
$allow_cid = $channel['channel_allow_cid'];
$allow_gid = $channel['channel_allow_gid'];
$deny_cid = $channel['channel_deny_cid'];
$deny_gid = $channel['channel_deny_gid'];
}
$poster = App::get_observer();
$uuid = item_message_id();
$mid = z_root() . '/item/' . $uuid;
$action = sprintf( t('%1$s is %2$s','mood'), '[zrl=' . $poster['xchan_url'] . ']' . $poster['xchan_name'] . '[/zrl]' , $verbs[$verb]);
$action = sprintf( t('%1$s is %2$s','mood'), '[zrl=' . $poster['xchan_url'] . ']' . $poster['xchan_name'] . '[/zrl]' , $verbs[$verb]);
$arr = array();
$arr['aid'] = get_account_id();
$arr['uid'] = $uid;
$arr['uuid'] = $uuid;
@@ -97,31 +97,31 @@ class Mood extends Controller {
$arr['item_unseen'] = 1;
if(! $parent_mid)
$item['item_thread_top'] = 1;
if ((! $arr['plink']) && intval($arr['item_thread_top'])) {
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']);
}
$post = item_store($arr);
$item_id = $post['item_id'];
if($item_id) {
\Zotlabs\Daemon\Master::Summon(array('Notifier','activity', $item_id));
}
call_hooks('post_local_end', $arr);
if($_SESSION['return_url'])
goaway(z_root() . '/' . $_SESSION['return_url']);
return;
}
function get() {
if(! local_channel()) {
notice( t('Permission denied.') . EOL);
return;
@@ -130,26 +130,24 @@ class Mood extends Controller {
if(! Apps::system_app_installed(local_channel(), 'Mood')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Mood App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('Set your current mood and tell your friends');
return $o;
$papp = Apps::get_papp('Mood');
return Apps::app_render($papp, 'module');
}
nav_set_selected('Mood');
$parent = ((x($_GET,'parent')) ? intval($_GET['parent']) : '0');
$verbs = get_mood_verbs();
$shortlist = array();
foreach($verbs as $k => $v)
if($v !== 'NOTRANSLATION')
$shortlist[] = array($k,$v);
$tpl = get_markup_template('mood_content.tpl');
$o = replace_macros($tpl,array(
'$title' => t('Mood'),
'$desc' => t('Set your current mood and tell your friends'),
@@ -157,9 +155,9 @@ class Mood extends Controller {
'$parent' => $parent,
'$submit' => t('Submit'),
));
return $o;
}
}

View File

@@ -289,8 +289,8 @@ class Network extends \Zotlabs\Web\Controller {
// This is for threaded view cid queries (e.g. if a forum is selected from the forum filter)
$ttype = (($pf) ? TERM_FORUM : TERM_MENTION);
$p1 = q("SELECT DISTINCT parent FROM item WHERE uid = " . intval(local_channel()) . " AND ( author_xchan = '" . dbesc($cid_r[0]['abook_xchan']) . "' OR owner_xchan = '" . dbesc($cid_r[0]['abook_xchan']) . "' ) $item_normal ");
$p2 = q("SELECT oid AS parent FROM term WHERE uid = " . intval(local_channel()) . " AND ttype = $ttype AND term = '" . dbesc($cid_r[0]['xchan_name']) . "'");
$p1 = dbq("SELECT DISTINCT parent FROM item WHERE uid = " . intval(local_channel()) . " AND ( author_xchan = '" . dbesc($cid_r[0]['abook_xchan']) . "' OR owner_xchan = '" . dbesc($cid_r[0]['abook_xchan']) . "' ) $item_normal ");
$p2 = dbq("SELECT oid AS parent FROM term WHERE uid = " . intval(local_channel()) . " AND ttype = $ttype AND term = '" . dbesc($cid_r[0]['xchan_name']) . "'");
$p_str = ids_to_querystr(array_merge($p1, $p2), 'parent');
if(! $p_str)
@@ -465,7 +465,7 @@ class Network extends \Zotlabs\Web\Controller {
if($nouveau && $load) {
// "New Item View" - show all items unthreaded in reverse created date order
$items = q("SELECT item.*, item.id AS item_id, created FROM item
$items = dbq("SELECT item.*, item.id AS item_id, created FROM item
left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
$net_query
WHERE true $uids $item_normal
@@ -494,7 +494,7 @@ class Network extends \Zotlabs\Web\Controller {
if($load) {
// Fetch a page full of parent items for this page
$r = q("SELECT item.parent AS item_id FROM item
$r = dbq("SELECT item.parent AS item_id FROM item
left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
$net_query
WHERE true $uids $item_thread_top $item_normal
@@ -508,26 +508,23 @@ class Network extends \Zotlabs\Web\Controller {
else {
// this is an update
$r = q("SELECT item.parent AS item_id FROM item
$r = dbq("SELECT item.parent AS item_id FROM item
left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
$net_query
WHERE true $uids $item_normal_update $simple_update
and (abook.abook_blocked = 0 or abook.abook_flags is null)
$sql_extra3 $sql_extra $sql_options $sql_nets $net_query2"
$sql_extra3 $sql_extra $sql_options $sql_nets $net_query2 "
);
}
// Then fetch all the children of the parents that are on this page
if($r) {
$parents_str = ids_to_querystr($r, 'item_id');
$items = q("SELECT item.*, item.id AS item_id FROM item
$items = dbq("SELECT item.*, item.id AS item_id FROM item
WHERE true $uids $item_normal
AND item.parent IN ( %s )
$sql_extra ",
dbesc($parents_str)
AND item.parent IN ( $parents_str )
$sql_extra "
);
xchan_query($items, true);

View File

@@ -51,11 +51,9 @@ class Notes extends Controller {
if(! Apps::system_app_installed(local_channel(), 'Notes')) {
//Do not display any associated widgets at this point
App::$pdl = EMPTY_STR;
$o = '<b>' . t('Notes App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('A simple notes app with a widget (note: notes are not encrypted)');
return $o;
App::$pdl = '';
$papp = Apps::get_papp('Notes');
return Apps::app_render($papp, 'module');
}
$w = new \Zotlabs\Widget\Notes;

View File

@@ -17,22 +17,22 @@ class Oauth extends Controller {
if(! Apps::system_app_installed(local_channel(), 'OAuth Apps Manager'))
return;
if(x($_POST,'remove')){
check_form_security_token_redirectOnErr('/oauth', 'oauth');
$key = $_POST['remove'];
q("DELETE FROM tokens WHERE id='%s' AND uid=%d",
dbesc($key),
local_channel());
goaway(z_root()."/oauth");
return;
return;
}
if((argc() > 1) && (argv(1) === 'edit' || argv(1) === 'add') && x($_POST,'submit')) {
check_form_security_token_redirectOnErr('oauth', 'oauth');
$name = ((x($_POST,'name')) ? escape_tags($_POST['name']) : '');
$key = ((x($_POST,'key')) ? escape_tags($_POST['key']) : '');
$secret = ((x($_POST,'secret')) ? escape_tags($_POST['secret']) : '');
@@ -48,7 +48,7 @@ class Oauth extends Controller {
$ok = false;
notice( t('Key and Secret are required') . EOL);
}
if($ok) {
if ($_POST['submit']==t("Update")){
$r = q("UPDATE clients SET
@@ -96,13 +96,11 @@ class Oauth extends Controller {
if(! Apps::system_app_installed(local_channel(), 'OAuth Apps Manager')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('OAuth Apps Manager App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('OAuth authentication tokens for mobile and remote apps');
return $o;
$papp = Apps::get_papp('OAuth Apps Manager');
return Apps::app_render($papp, 'module');
}
if((argc() > 1) && (argv(1) === 'add')) {
$tpl = get_markup_template("oauth_edit.tpl");
$o .= replace_macros($tpl, array(
@@ -118,18 +116,18 @@ class Oauth extends Controller {
));
return $o;
}
if((argc() > 2) && (argv(1) === 'edit')) {
$r = q("SELECT * FROM clients WHERE client_id='%s' AND uid=%d",
dbesc(argv(2)),
local_channel());
if (!count($r)){
notice(t('Application not found.'));
return;
}
$app = $r[0];
$tpl = get_markup_template("oauth_edit.tpl");
$o .= replace_macros($tpl, array(
'$form_security_token' => get_form_security_token("oauth"),
@@ -144,26 +142,26 @@ class Oauth extends Controller {
));
return $o;
}
if((argc() > 2) && (argv(1) === 'delete')) {
check_form_security_token_redirectOnErr('/oauth', 'oauth', 't');
$r = q("DELETE FROM clients WHERE client_id='%s' AND uid=%d",
dbesc(argv(2)),
local_channel());
goaway(z_root()."/oauth");
return;
return;
}
$r = q("SELECT clients.*, tokens.id as oauth_token, (clients.uid=%d) AS my
$r = q("SELECT clients.*, tokens.id as oauth_token, (clients.uid=%d) AS my
FROM clients
LEFT JOIN tokens ON clients.client_id=tokens.client_id
WHERE clients.uid IN (%d,0)",
local_channel(),
local_channel());
$tpl = get_markup_template("oauth.tpl");
$o .= replace_macros($tpl, array(
'$form_security_token' => get_form_security_token("oauth"),
@@ -178,7 +176,7 @@ class Oauth extends Controller {
'$apps' => $r,
));
return $o;
}
}

View File

@@ -16,11 +16,11 @@ class Oauth2 extends Controller {
if(! Apps::system_app_installed(local_channel(), 'OAuth2 Apps Manager'))
return;
if(x($_POST,'remove')){
check_form_security_token_redirectOnErr('oauth2', 'oauth2');
$name = ((x($_POST,'name')) ? escape_tags(trim($_POST['name'])) : '');
logger("REMOVE! ".$name." uid: ".local_channel());
logger("REMOVE! ".$name." uid: ".local_channel());
$key = $_POST['remove'];
q("DELETE FROM oauth_authorization_codes WHERE client_id='%s' AND user_id=%d",
dbesc($name),
@@ -35,13 +35,13 @@ class Oauth2 extends Controller {
intval(local_channel())
);
goaway(z_root()."/oauth2");
return;
return;
}
if((argc() > 1) && (argv(1) === 'edit' || argv(1) === 'add') && x($_POST,'submit')) {
check_form_security_token_redirectOnErr('oauth2', 'oauth2');
$name = ((x($_POST,'name')) ? escape_tags(trim($_POST['name'])) : '');
$secret = ((x($_POST,'secret')) ? escape_tags(trim($_POST['secret'])) : '');
$redirect = ((x($_POST,'redirect')) ? escape_tags(trim($_POST['redirect'])) : '');
@@ -53,7 +53,7 @@ class Oauth2 extends Controller {
$ok = false;
notice( t('Name and Secret are required') . EOL);
}
if($ok) {
if ($_POST['submit']==t("Update")){
$r = q("UPDATE oauth_clients SET
@@ -61,7 +61,7 @@ class Oauth2 extends Controller {
client_secret = '%s',
redirect_uri = '%s',
grant_types = '%s',
scope = '%s',
scope = '%s',
user_id = %d
WHERE client_id='%s' and user_id = %s",
dbesc($name),
@@ -102,12 +102,10 @@ class Oauth2 extends Controller {
if(! Apps::system_app_installed(local_channel(), 'OAuth2 Apps Manager')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('OAuth2 Apps Manager App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('OAuth2 authenticatication tokens for mobile and remote apps');
return $o;
$papp = Apps::get_papp('OAuth2 Apps Manager');
return Apps::app_render($papp, 'module');
}
if((argc() > 1) && (argv(1) === 'add')) {
$tpl = get_markup_template("oauth2_edit.tpl");
$o .= replace_macros($tpl, array(
@@ -123,20 +121,20 @@ class Oauth2 extends Controller {
));
return $o;
}
if((argc() > 2) && (argv(1) === 'edit')) {
$r = q("SELECT * FROM oauth_clients WHERE client_id='%s' AND user_id= %d",
dbesc(argv(2)),
intval(local_channel())
);
if (! $r){
notice(t('OAuth2 Application not found.'));
return;
}
$app = $r[0];
$tpl = get_markup_template("oauth2_edit.tpl");
$o .= replace_macros($tpl, array(
'$form_security_token' => get_form_security_token("oauth2"),
@@ -151,10 +149,10 @@ class Oauth2 extends Controller {
));
return $o;
}
if((argc() > 2) && (argv(1) === 'delete')) {
check_form_security_token_redirectOnErr('oauth2', 'oauth2', 't');
$r = q("DELETE FROM oauth_clients WHERE client_id = '%s' AND user_id = %d",
dbesc(argv(2)),
intval(local_channel())
@@ -172,11 +170,11 @@ class Oauth2 extends Controller {
intval(local_channel())
);
goaway(z_root()."/oauth2");
return;
return;
}
$r = q("SELECT oauth_clients.*, oauth_access_tokens.access_token as oauth_token, (oauth_clients.user_id = %d) AS my
$r = q("SELECT oauth_clients.*, oauth_access_tokens.access_token as oauth_token, (oauth_clients.user_id = %d) AS my
FROM oauth_clients
LEFT JOIN oauth_access_tokens ON oauth_clients.client_id=oauth_access_tokens.client_id AND
oauth_clients.user_id=oauth_access_tokens.user_id
@@ -184,7 +182,7 @@ class Oauth2 extends Controller {
intval(local_channel()),
intval(local_channel())
);
$tpl = get_markup_template("oauth2.tpl");
$o .= replace_macros($tpl, array(
'$form_security_token' => get_form_security_token("oauth2"),
@@ -199,7 +197,7 @@ class Oauth2 extends Controller {
'$apps' => $r,
));
return $o;
}
}

View File

@@ -77,8 +77,11 @@ class Oep extends \Zotlabs\Web\Controller {
$res = $matches[2];
}
if(strpos($res,'b64.') === 0) {
$res = base64url_decode(substr($res,4));
$res = unpack_link_id($res);
if ($res === false) {
notice(t('Malformed message id.') . EOL);
return;
}
$item_normal = item_normal();

View File

@@ -32,14 +32,14 @@ class Owa extends Controller {
$keyId = $sigblock['keyId'];
if ($keyId) {
$r = q("SELECT * FROM hubloc LEFT JOIN xchan ON hubloc_hash = xchan_hash
WHERE hubloc_id_url = '%s'",
WHERE hubloc_id_url = '%s' AND xchan_pubkey != '' ",
dbesc($keyId)
);
if (! $r) {
$found = discover_by_webbie(str_replace('acct:','',$keyId));
if ($found) {
$r = q("SELECT * FROM hubloc LEFT JOIN xchan ON hubloc_hash = xchan_hash
WHERE hubloc_id_url = '%s'",
WHERE hubloc_id_url = '%s' AND xchan_pubkey != '' ",
dbesc($keyId)
);
}

View File

@@ -27,10 +27,10 @@ class Pdledit extends Controller {
info( t('Layout updated.') . EOL);
goaway(z_root() . '/pdledit/' . $_REQUEST['module']);
}
function get() {
if(! local_channel()) {
notice( t('Permission denied.') . EOL);
return;
@@ -39,10 +39,8 @@ class Pdledit extends Controller {
if(! Apps::system_app_installed(local_channel(), 'PDL Editor')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('PDL Editor App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('Provides the ability to edit system page layouts');
return $o;
$papp = Apps::get_papp('PDL Editor');
return Apps::app_render($papp, 'module');
}
if(argc() > 2 && argv(2) === 'reset') {
@@ -68,7 +66,7 @@ class Pdledit extends Controller {
$edited[] = substr(str_replace('.pdl','',$rv['k']),4);
}
}
$files = glob('Zotlabs/Module/*.php');
if($files) {
foreach($files as $f) {
@@ -81,21 +79,21 @@ class Pdledit extends Controller {
}
$o .= '</div>';
// list module pdl files
return $o;
}
$t = get_pconfig(local_channel(),'system',$module);
$s = file_get_contents(theme_include($module));
if(! $t) {
$t = $s;
}
}
if(! $t) {
notice( t('Layout not found.') . EOL);
return '';
}
$o = replace_macros(get_markup_template('pdledit.tpl'),array(
'$header' => t('Edit System Page Description'),
'$mname' => t('Module Name:'),
@@ -107,8 +105,8 @@ class Pdledit extends Controller {
'$content' => htmlspecialchars($t,ENT_COMPAT,'UTF-8'),
'$submit' => t('Submit')
));
return $o;
}
}

View File

@@ -40,16 +40,16 @@ class Permcats extends Controller {
}
}
}
\Zotlabs\Lib\Permcat::update(local_channel(),$name,$pcarr);
Libsync::build_sync_packet();
info( t('Permission category saved.') . EOL);
return;
}
function get() {
@@ -59,16 +59,14 @@ class Permcats extends Controller {
if(! Apps::system_app_installed(local_channel(), 'Permission Categories')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Permission Categories App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('Create custom connection permission limits');
return $o;
$papp = Apps::get_papp('Permission Categories');
return Apps::app_render($papp, 'module');
}
$channel = App::get_channel();
if(argc() > 1)
$name = hex2bin(argv(1));
if(argc() > 1)
$name = hex2bin(argv(1));
if(argc() > 2 && argv(2) === 'drop') {
\Zotlabs\Lib\Permcat::delete(local_channel(),$name);
@@ -130,5 +128,5 @@ class Permcats extends Controller {
));
return $o;
}
}

View File

@@ -37,7 +37,7 @@ class Pin extends \Zotlabs\Web\Controller {
http_status_exit(404, 'Not found');
}
$midb64 = 'b64.' . base64url_encode($r[0]['mid']);
$midb64 = gen_link_id($r[0]['mid']);
$pinned = (in_array($midb64, get_pconfig($r[0]['uid'], 'pinned', $r[0]['item_type'], [])) ? true : false);
switch(argv(1)) {

View File

@@ -9,11 +9,11 @@ use Zotlabs\Web\Controller;
*
* Poke, prod, finger, or otherwise do unspeakable things to somebody - who must be a connection in your address book
* This function can be invoked with the required arguments (verb and cid and private and possibly parent) silently via ajax or
* other web request. You must be logged in and connected to a channel.
* other web request. You must be logged in and connected to a channel.
* If the required arguments aren't present, we'll display a simple form to choose a recipient and a verb.
* parent is a special argument which let's you attach this activity as a comment to an existing conversation, which
* may have started with somebody else poking (etc.) somebody, but this isn't necessary. This can be used in the adult
* plugin version to have entire conversations where Alice poked Bob, Bob fingered Alice, Alice hugged Bob, etc.
* plugin version to have entire conversations where Alice poked Bob, Bob fingered Alice, Alice hugged Bob, etc.
*
* private creates a private conversation with the recipient. Otherwise your channel's default post privacy is used.
*
@@ -25,41 +25,41 @@ require_once('include/items.php');
class Poke extends Controller {
function init() {
if(! local_channel())
return;
if(! Apps::system_app_installed(local_channel(), 'Poke')) {
return;
}
$uid = local_channel();
$channel = App::get_channel();
$verb = notags(trim($_REQUEST['verb']));
if(! $verb)
if(! $verb)
return;
$verbs = get_poke_verbs();
if(! array_key_exists($verb,$verbs))
return;
$activity = ACTIVITY_POKE . '#' . urlencode($verbs[$verb][0]);
$contact_id = intval($_REQUEST['cid']);
$xchan = trim($_REQUEST['xchan']);
if(! ($contact_id || $xchan))
return;
$parent = ((x($_REQUEST,'parent')) ? intval($_REQUEST['parent']) : 0);
logger('poke: verb ' . $verb . ' contact ' . $contact_id, LOGGER_DEBUG);
if($contact_id) {
$r = q("SELECT * FROM abook left join xchan on xchan_hash = abook_xchan where abook_id = %d and abook_channel = %d LIMIT 1",
intval($contact_id),
@@ -71,17 +71,17 @@ class Poke extends Controller {
dbesc($xchan . '%')
);
}
if(! $r) {
logger('poke: no target.');
return;
}
$target = $r[0];
$parent_item = null;
if($parent) {
$r = q("select mid, item_private, owner_xchan, allow_cid, allow_gid, deny_cid, deny_gid
$r = q("select mid, item_private, owner_xchan, allow_cid, allow_gid, deny_cid, deny_gid
from item where id = %d and parent = %d and uid = %d limit 1",
intval($parent),
intval($parent),
@@ -98,18 +98,18 @@ class Poke extends Controller {
}
}
elseif($contact_id) {
$item_private = ((x($_GET,'private')) ? intval($_GET['private']) : 0);
$allow_cid = (($item_private) ? '<' . $target['abook_xchan']. '>' : $channel['channel_allow_cid']);
$allow_gid = (($item_private) ? '' : $channel['channel_allow_gid']);
$deny_cid = (($item_private) ? '' : $channel['channel_deny_cid']);
$deny_gid = (($item_private) ? '' : $channel['channel_deny_gid']);
}
$arr = array();
$arr['item_wall'] = 1;
@@ -124,7 +124,7 @@ class Poke extends Controller {
$arr['item_private'] = $item_private;
$arr['obj_type'] = ACTIVITY_OBJ_PERSON;
$arr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t($verbs[$verb][0]) . ' ' . '[zrl=' . $target['xchan_url'] . ']' . $target['xchan_name'] . '[/zrl]';
$obj = array(
'type' => ACTIVITY_OBJ_PERSON,
'title' => $target['xchan_name'],
@@ -134,25 +134,25 @@ class Poke extends Controller {
array('rel' => 'photo', 'type' => $target['xchan_photo_mimetype'], 'href' => $target['xchan_photo_l'])
),
);
$arr['obj'] = json_encode($obj);
$arr['item_origin'] = 1;
$arr['item_wall'] = 1;
$arr['item_unseen'] = 1;
if(! $parent_item)
$item['item_thread_top'] = 1;
post_activity_item($arr);
return;
}
function get() {
if(! local_channel()) {
notice( t('Permission denied.') . EOL);
return;
@@ -161,19 +161,17 @@ class Poke extends Controller {
if(! Apps::system_app_installed(local_channel(), 'Poke')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Poke App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('Poke somebody in your addressbook');
return $o;
$papp = Apps::get_papp('Poke');
return Apps::app_render($papp, 'module');
}
nav_set_selected('Poke');
$name = '';
$id = '';
if(intval($_REQUEST['c'])) {
$r = q("select abook_id, xchan_name from abook left join xchan on abook_xchan = xchan_hash
$r = q("select abook_id, xchan_name from abook left join xchan on abook_xchan = xchan_hash
where abook_id = %d and abook_channel = %d limit 1",
intval($_REQUEST['c']),
intval(local_channel())
@@ -183,17 +181,17 @@ class Poke extends Controller {
$id = $r[0]['abook_id'];
}
}
$parent = ((x($_REQUEST,'parent')) ? intval($_REQUEST['parent']) : '0');
$verbs = get_poke_verbs();
$shortlist = array();
foreach($verbs as $k => $v)
if($v[1] !== 'NOTRANSLATION')
$shortlist[] = array($k,$v[1]);
$poke_basic = get_config('system','poke_basic');
if($poke_basic) {
$title = t('Poke');
@@ -203,7 +201,7 @@ class Poke extends Controller {
$title = t('Poke/Prod');
$desc = t('Poke, prod or do other things to somebody');
}
$o = replace_macros(get_markup_template('poke_content.tpl'),array(
'$title' => $title,
'$poke_basic' => $poke_basic,
@@ -218,8 +216,8 @@ class Poke extends Controller {
'$name' => $name,
'$id' => $id
));
return $o;
}
}

View File

@@ -16,10 +16,8 @@ class Pubstream extends \Zotlabs\Web\Controller {
if(! Apps::system_app_installed(local_channel(), 'Public Stream')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Public Stream App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('The unmoderated public stream of this hub');
return $o;
$papp = Apps::get_papp('Public Stream');
return Apps::app_render($papp, 'module');
}
}
@@ -44,19 +42,16 @@ class Pubstream extends \Zotlabs\Web\Controller {
$site_firehose = false;
}
$mid = ((x($_REQUEST,'mid')) ? $_REQUEST['mid'] : '');
$hashtags = ((x($_REQUEST,'tag')) ? $_REQUEST['tag'] : '');
if(strpos($mid,'b64.') === 0)
$decoded = @base64url_decode(substr($mid,4));
if($decoded)
$mid = $decoded;
$mid = ((x($_REQUEST, 'mid')) ? unpack_link_id($_REQUEST['mid']) : '');
if ($mid === false) {
notice(t('Malformed message id.') . EOL);
return;
}
$hashtags = ((x($_REQUEST,'tag')) ? $_REQUEST['tag'] : '');
$item_normal = item_normal();
$item_normal_update = item_normal_update();
$net = ((array_key_exists('net',$_REQUEST)) ? escape_tags($_REQUEST['net']) : '');
$net = ((array_key_exists('net',$_REQUEST)) ? escape_tags($_REQUEST['net']) : '');
$title = replace_macros(get_markup_template("section_title.tpl"),array(
'$title' => (($hashtags) ? '#' . htmlspecialchars($hashtags, ENT_COMPAT,'UTF-8') : '')
@@ -65,15 +60,15 @@ class Pubstream extends \Zotlabs\Web\Controller {
$o = (($hashtags) ? $title : '');
if(local_channel() && (! $update)) {
$channel = \App::get_channel();
$channel_acl = array(
'allow_cid' => $channel['channel_allow_cid'],
'allow_gid' => $channel['channel_allow_gid'],
'deny_cid' => $channel['channel_deny_cid'],
'allow_cid' => $channel['channel_allow_cid'],
'allow_gid' => $channel['channel_allow_gid'],
'deny_cid' => $channel['channel_deny_cid'],
'deny_gid' => $channel['channel_deny_gid']
);
);
$x = array(
'is_owner' => true,
@@ -94,12 +89,12 @@ class Pubstream extends \Zotlabs\Web\Controller {
'jotnets' => true,
'reset' => t('Reset form')
);
$o .= '<div id="jot-popup">';
$o .= status_editor($a,$x,false,'Pubstream');
$o .= '</div>';
}
if(! $update && !$load) {
nav_set_selected(t('Public Stream'));
@@ -110,15 +105,14 @@ class Pubstream extends \Zotlabs\Web\Controller {
$maxheight = get_config('system','home_divmore_height');
if(! $maxheight)
$maxheight = 400;
$o .= '<div id="live-pubstream"></div>' . "\r\n";
$o .= "<script> var profile_uid = " . ((intval(local_channel())) ? local_channel() : (-1))
. "; var profile_page = " . \App::$pager['page']
$o .= "<script> var profile_uid = " . ((intval(local_channel())) ? local_channel() : (-1))
. "; var profile_page = " . \App::$pager['page']
. "; divmore_height = " . intval($maxheight) . "; </script>\r\n";
//if we got a decoded hash we must encode it again before handing to javascript
if($decoded)
$mid = 'b64.' . base64url_encode($mid);
//if we got a decoded hash we must encode it again before handing to javascript
$mid = gen_link_id($mid);
\App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array(
'$baseurl' => z_root(),
@@ -151,7 +145,7 @@ class Pubstream extends \Zotlabs\Web\Controller {
'$dbegin' => ''
));
}
if($update && ! $load) {
// only setup pagination on initial page view
$pager_sql = '';
@@ -160,10 +154,10 @@ class Pubstream extends \Zotlabs\Web\Controller {
\App::set_pager_itemspage(10);
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start']));
}
require_once('include/channel.php');
require_once('include/security.php');
if($site_firehose) {
$uids = " and item.uid in ( " . stream_perms_api_uids(PERMS_PUBLIC) . " ) and item_private = 0 and item_wall = 1 ";
}
@@ -173,7 +167,7 @@ class Pubstream extends \Zotlabs\Web\Controller {
$sql_extra = item_permissions_sql($sys['channel_id']);
\App::$data['firehose'] = intval($sys['channel_id']);
}
if(get_config('system','public_list_mode'))
$page_mode = 'list';
else
@@ -184,7 +178,7 @@ class Pubstream extends \Zotlabs\Web\Controller {
$sql_extra .= protect_sprintf(term_query('item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG));
}
$net_query = (($net) ? " left join xchan on xchan_hash = author_xchan " : '');
$net_query = (($net) ? " left join xchan on xchan_hash = author_xchan " : '');
$net_query2 = (($net) ? " and xchan_network = '" . protect_sprintf(dbesc($net)) . "' " : '');
$abook_uids = " and abook.abook_channel = " . intval(\App::$profile['profile_uid']) . " ";
@@ -196,13 +190,13 @@ class Pubstream extends \Zotlabs\Web\Controller {
//logger('update: ' . $update . ' load: ' . $load);
if($update) {
$ordering = get_config('system', 'pubstream_ordering', 'commented');
if($load) {
if($mid) {
$r = q("SELECT parent AS item_id FROM item
left join abook on item.author_xchan = abook.abook_xchan
left join abook on item.author_xchan = abook.abook_xchan
$net_query
WHERE mid = '%s' $uids $item_normal
and (abook.abook_blocked = 0 or abook.abook_flags is null)
@@ -212,7 +206,7 @@ class Pubstream extends \Zotlabs\Web\Controller {
}
else {
// Fetch a page full of parent items for this page
$r = q("SELECT item.id AS item_id FROM item
$r = dbq("SELECT item.id AS item_id FROM item
left join abook on ( item.author_xchan = abook.abook_xchan $abook_uids )
$net_query
WHERE true $uids and item.item_thread_top = 1 $item_normal
@@ -234,7 +228,7 @@ class Pubstream extends \Zotlabs\Web\Controller {
);
}
else {
$r = q("SELECT parent AS item_id FROM item
$r = dbq("SELECT parent AS item_id FROM item
left join abook on item.author_xchan = abook.abook_xchan
$net_query
WHERE true $uids $item_normal_update
@@ -247,20 +241,19 @@ class Pubstream extends \Zotlabs\Web\Controller {
// Then fetch all the children of the parents that are on this page
$parents_str = '';
if($r) {
$parents_str = ids_to_querystr($r,'item_id');
$items = q("SELECT item.*, item.id AS item_id FROM item
$items = dbq("SELECT item.*, item.id AS item_id FROM item
WHERE true $uids $item_normal
AND item.parent IN ( %s )
$sql_extra ",
dbesc($parents_str)
AND item.parent IN ( $parents_str )
$sql_extra"
);
// use effective_uid param of xchan_query to help sort out comment permission
// for sys_channel owned items.
// for sys_channel owned items.
xchan_query($items,true,(($sys) ? local_channel() : 0));
$items = fetch_post_tags($items,true);
@@ -269,9 +262,9 @@ class Pubstream extends \Zotlabs\Web\Controller {
else {
$items = array();
}
}
// fake it
$mode = (($hashtags) ? 'search' : 'pubstream');
@@ -279,13 +272,13 @@ class Pubstream extends \Zotlabs\Web\Controller {
if($mid)
$o .= '<div id="content-complete"></div>';
if(($items) && (! $update))
$o .= alt_pager(count($items));
$_SESSION['loadtime'] = datetime_convert();
return $o;
}
}

View File

@@ -15,7 +15,7 @@ class Randprof extends \Zotlabs\Web\Controller {
$x = random_profile();
if($x)
goaway(chanlink_hash($x));
/** FIXME this doesn't work at the moment as a fallback */
goaway(z_root() . '/profile');
}
@@ -25,13 +25,11 @@ class Randprof extends \Zotlabs\Web\Controller {
if(! Apps::system_app_installed(local_channel(), 'Random Channel')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Random Channel App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('Visit a random channel in the $Projectname network');
return $o;
$papp = Apps::get_papp('Random Channel');
return Apps::app_render($papp, 'module');
}
}
}
}

View File

@@ -66,6 +66,73 @@ class Rpost extends \Zotlabs\Web\Controller {
nav_set_selected('Post');
if (local_channel() && array_key_exists('userfile',$_FILES)) {
$channel = App::get_channel();
$observer = App::get_observer();
$def_album = get_pconfig($channel['channel_id'],'system','photo_path');
$def_attach = get_pconfig($channel['channel_id'],'system','attach_path');
$r = attach_store($channel, (($observer) ? $observer['xchan_hash'] : ''), '', [
'source' => 'editor',
'visible' => 0,
'album' => $def_album,
'directory' => $def_attach,
'flags' => 1, // indicates temporary permissions are created
'allow_cid' => '<' . $channel['channel_hash'] . '>'
]);
if (! $r['success']) {
notice( $r['message'] . EOL);
}
$s = EMPTY_STR;
if (intval($r['data']['is_photo'])) {
$s .= "\n\n" . $r['body'] . "\n\n";
}
$url = z_root() . '/cloud/' . $channel['channel_address'] . '/' . $r['data']['display_path'];
if (strpos($r['data']['filetype'],'video') === 0) {
$s .= "\n\n" . '[zvideo]' . $url . '[/zvideo]' . "\n\n";
}
if (strpos($r['data']['filetype'],'audio') === 0) {
$s .= "\n\n" . '[zaudio]' . $url . '[/zaudio]' . "\n\n";
}
if ($r['data']['filetype'] === 'image/svg+xml') {
$x = @file_get_contents('store/' . $channel['channel_address'] . '/' . $r['data']['os_path']);
if ($x) {
$bb = svg2bb($x);
if ($bb) {
$s .= "\n\n" . $bb;
}
else {
logger('empty return from svgbb');
}
}
else {
logger('unable to read svg data file: ' . 'store/' . $channel['channel_address'] . '/' . $r['data']['os_path']);
}
}
if ($r['data']['filetype'] === 'text/calendar') {
$content = @file_get_contents('store/' . $channel['channel_address'] . '/' . $r['data']['os_path']);
if ($content) {
$ev = ical_to_ev($content);
if ($ev) {
$s .= "\n\n" . format_event_bbcode($ev[0]) . "\n\n";
}
}
}
$s .= "\n\n" . '[attachment]' . $r['data']['hash'] . ',' . $r['data']['revision'] . '[/attachment]' . "\n";
$_REQUEST['body'] = ((array_key_exists('body',$_REQUEST)) ? $_REQUEST['body'] . $s : $s);
}
// If we have saved rpost session variables, but nothing in the current $_REQUEST, recover the saved variables
if((! array_key_exists('body',$_REQUEST)) && (array_key_exists('rpost',$_SESSION))) {

View File

@@ -215,7 +215,7 @@ class Search extends Controller {
}
if ($r) {
$str = ids_to_querystr($r, 'item_id');
$r = q("select *, id as item_id from item where id in ( " . $str . ") order by created desc ");
$r = dbq("select *, id as item_id from item where id in ( " . $str . ") order by created desc");
}
}
else {

View File

@@ -24,7 +24,6 @@ class Display {
$preload_images = ((x($_POST,'preload_images')) ? intval($_POST['preload_images']) : 0);
$channel_menu = ((x($_POST,'channel_menu')) ? intval($_POST['channel_menu']) : 0);
$user_scalable = ((x($_POST,'user_scalable')) ? intval($_POST['user_scalable']) : 0);
$nosmile = ((x($_POST,'nosmile')) ? intval($_POST['nosmile']) : 0);
$title_tosource = ((x($_POST,'title_tosource')) ? intval($_POST['title_tosource']) : 0);
@@ -46,7 +45,6 @@ class Display {
set_pconfig(local_channel(),'system','itemspage', $itemspage);
set_pconfig(local_channel(),'system','no_smilies',1-intval($nosmile));
set_pconfig(local_channel(),'system','title_tosource',$title_tosource);
set_pconfig(local_channel(),'system','channel_menu', $channel_menu);
set_pconfig(local_channel(),'system','start_menu', $start_menu);
$newschema = '';
@@ -197,7 +195,6 @@ class Display {
'$ajaxint' => array('browser_update', t("Update browser every xx seconds"), $browser_update, t('Minimum of 10 seconds, no maximum')),
'$itemspage' => array('itemspage', t("Maximum number of conversations to load at any time:"), $itemspage, t('Maximum of 30 items')),
'$nosmile' => array('nosmile', t("Show emoticons (smilies) as images"), 1-intval($nosmile), '', $yes_no),
'$channel_menu' => [ 'channel_menu', t('Provide channel menu in navigation bar'), get_pconfig(local_channel(),'system','channel_menu',get_config('system','channel_menu',0)), t('Default: channel menu located in app menu'),$yes_no ],
'$title_tosource' => array('title_tosource', t("Link post titles to source"), $title_tosource, '', $yes_no),
'$theme_config' => $theme_config,
'$start_menu' => ['start_menu', t('New Member Links'), $start_menu, t('Display new member quick links menu'), $yes_no]

View File

@@ -13,7 +13,7 @@ class Sources extends Controller {
if(! Apps::system_app_installed(local_channel(), 'Channel Sources'))
return;
$source = intval($_REQUEST['source']);
$xchan = escape_tags($_REQUEST['xchan']);
$abook = intval($_REQUEST['abook']);
@@ -22,21 +22,21 @@ class Sources extends Controller {
$frequency = $_REQUEST['frequency'];
$name = escape_tags($_REQUEST['name']);
$tags = escape_tags($_REQUEST['tags']);
$channel = \App::get_channel();
if($name == '*')
$xchan = '*';
if($abook) {
$r = q("select abook_xchan from abook where abook_id = %d and abook_channel = %d limit 1",
intval($abook),
intval(local_channel())
);
if($r)
if($r)
$xchan = $r[0]['abook_xchan'];
}
if(! $xchan) {
notice ( t('Failed to create source. No channel selected.') . EOL);
return;
@@ -69,27 +69,25 @@ class Sources extends Controller {
if($r) {
info( t('Source updated.') . EOL);
}
}
}
function get() {
if(! local_channel()) {
notice( t('Permission denied.') . EOL);
return;
}
if(! Apps::system_app_installed(local_channel(), 'Channel Sources')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Sources App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('Automatically import channel content from other channels or feeds');
return $o;
$papp = Apps::get_papp('Channel Sources');
return Apps::app_render($papp, 'module');
}
// list sources
if(argc() == 1) {
$r = q("select source.*, xchan.* from source left join xchan on src_xchan = xchan_hash where src_channel_id = %d",
@@ -111,23 +109,23 @@ class Sources extends Controller {
));
return $o;
}
if(argc() == 2 && argv(1) === 'new') {
// TODO add the words 'or RSS feed' and corresponding code to manage feeds and frequency
$o = replace_macros(get_markup_template('sources_new.tpl'), array(
'$title' => t('New Source'),
'$desc' => t('Import all or selected content from the following channel into this channel and distribute it according to your channel settings.'),
'$words' => array( 'words', t('Only import content with these words (one per line)'),'',t('Leave blank to import all public content')),
'$name' => array( 'name', t('Channel Name'), '', '', '', 'autocomplete="off"'),
'$tags' => array('tags', t('Add the following categories to posts imported from this source (comma separated)'),'',t('Optional')),
'$resend' => [ 'resend', t('Resend posts with this channel as author'), 0, t('Copyrights may apply'), [ t('No'), t('Yes') ]],
'$resend' => [ 'resend', t('Resend posts with this channel as author'), 0, t('Copyrights may apply'), [ t('No'), t('Yes') ]],
'$submit' => t('Submit')
));
return $o;
}
if(argc() == 2 && intval(argv(1))) {
// edit source
$r = q("select source.*, xchan.* from source left join xchan on src_xchan = xchan_hash where src_id = %d and src_channel_id = %d limit 1",
@@ -144,9 +142,9 @@ class Sources extends Controller {
notice( t('Source not found.') . EOL);
return '';
}
$r[0]['src_patt'] = htmlspecialchars($r[0]['src_patt'], ENT_QUOTES,'UTF-8');
$o = replace_macros(get_markup_template('sources_edit.tpl'), array(
'$title' => t('Edit Source'),
'$drop' => t('Delete Source'),
@@ -156,15 +154,15 @@ class Sources extends Controller {
'$xchan' => $r[0]['src_xchan'],
'$abook' => $x[0]['abook_id'],
'$tags' => array('tags', t('Add the following categories to posts imported from this source (comma separated)'),$r[0]['src_tag'],t('Optional')),
'$resend' => [ 'resend', t('Resend posts with this channel as author'), get_abconfig(local_channel(), $r[0]['xchan_hash'],'system','rself'), t('Copyrights may apply'), [ t('No'), t('Yes') ]],
'$resend' => [ 'resend', t('Resend posts with this channel as author'), get_abconfig(local_channel(), $r[0]['xchan_hash'],'system','rself'), t('Copyrights may apply'), [ t('No'), t('Yes') ]],
'$name' => array( 'name', t('Channel Name'), $r[0]['xchan_name'], ''),
'$submit' => t('Submit')
));
return $o;
}
if(argc() == 3 && intval(argv(1)) && argv(2) === 'drop') {
$r = q("select * from source where src_id = %d and src_channel_id = %d limit 1",
intval(argv(1)),
@@ -182,12 +180,12 @@ class Sources extends Controller {
info( t('Source removed') . EOL);
else
notice( t('Unable to remove source.') . EOL);
goaway(z_root() . '/sources');
}
// shouldn't get here.
}
}

View File

@@ -560,7 +560,7 @@ class Sse_bs extends Controller {
$b64mids = [];
foreach($mids as $mid)
$b64mids[] = 'b64.' . base64url_encode($mid);
$b64mids[] = gen_link_id($mid);
$forums[$x]['notify_link'] = z_root() . '/network/?f=&pf=1&unseen=1&cid=' . $forums[$x]['abook_id'];
$forums[$x]['name'] = $forums[$x]['xchan_name'];

View File

@@ -36,10 +36,8 @@ class Suggest extends \Zotlabs\Web\Controller {
if(! Apps::system_app_installed(local_channel(), 'Suggest Channels')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Suggest Channels App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('Suggestions for channels in the $Projectname network you might be interested in');
return $o;
$papp = Apps::get_papp('Suggest Channels');
return Apps::app_render($papp, 'module');
}
$o = '';

View File

@@ -46,7 +46,7 @@ class Tokens extends Controller {
return;
}
if($atoken_id) {
$r = q("update atoken set atoken_name = '%s', atoken_token = '%s', atoken_expires = '%s'
$r = q("update atoken set atoken_name = '%s', atoken_token = '%s', atoken_expires = '%s'
where atoken_id = %d and atoken_uid = %d",
dbesc($name),
dbesc($token),
@@ -80,12 +80,12 @@ class Tokens extends Controller {
}
}
}
info( t('Token saved.') . EOL);
return;
}
function get() {
@@ -95,10 +95,8 @@ class Tokens extends Controller {
if(! Apps::system_app_installed(local_channel(), 'Guest Access')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Guest Access App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('Create access tokens so that non-members can access private content');
return $o;
$papp = Apps::get_papp('Guest Access');
return Apps::app_render($papp, 'module');
}
$channel = App::get_channel();
@@ -128,7 +126,7 @@ class Tokens extends Controller {
$t = q("select * from atoken where atoken_uid = %d",
intval(local_channel())
);
);
$desc = t('Use this form to create temporary access identifiers to share things with non-members. These identities may be used in Access Control Lists and visitors may login using these credentials to access private content.');
@@ -189,5 +187,5 @@ class Tokens extends Controller {
));
return $o;
}
}

View File

@@ -24,26 +24,26 @@ class Uexport extends Controller {
if(argc() > 1 && intval(argv(1)) > 1900) {
$year = intval(argv(1));
}
if(argc() > 2 && intval(argv(2)) > 0 && intval(argv(2)) <= 12) {
$month = intval(argv(2));
}
header('content-type: application/json');
header('content-disposition: attachment; filename="' . $channel['channel_address'] . (($year) ? '-' . $year : '') . (($month) ? '-' . $month : '') . (($_REQUEST['sections']) ? '-' . $_REQUEST['sections'] : '') . '.json"' );
if($year) {
echo json_encode(identity_export_year(local_channel(),$year,$month, $zap_compat));
killme();
}
if(argc() > 1 && argv(1) === 'basic') {
echo json_encode(identity_basic_export(local_channel(),$sections, $zap_compat));
killme();
}
// Warning: this option may consume a lot of memory
if(argc() > 1 && argv(1) === 'complete') {
$sections = get_default_export_sections();
$sections[] = 'items';
@@ -52,20 +52,18 @@ class Uexport extends Controller {
}
}
}
function get() {
if(! Apps::system_app_installed(local_channel(), 'Channel Export')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Channel Export App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('Export your channel');
return $o;
$papp = Apps::get_papp('Channel Export');
return Apps::app_render($papp, 'module');
}
$y = datetime_convert('UTC',date_default_timezone_get(),'now','Y');
$yearurl = z_root() . '/uexport/' . $y;
$janurl = z_root() . '/uexport/' . $y . '/1';
$impurl = '/import_items';
@@ -77,14 +75,14 @@ class Uexport extends Controller {
'$full' => t('Export your channel information and recent content to a JSON backup that can be restored or imported to another server hub. This backs up all of your connections, permissions, profile data and several months of posts. This file may be VERY large. Please be patient - it may take several minutes for this download to begin.'),
'$by_year' => t('Export your posts from a given year.'),
'$extra' => t('You may also export your posts and conversations for a particular year or month. Adjust the date in your browser location bar to select other dates. If the export fails (possibly due to memory exhaustion on your server hub), please try again selecting a more limited date range.'),
'$extra2' => sprintf( t('To select all posts for a given year, such as this year, visit <a href="%1$s">%2$s</a>'),$yearurl,$yearurl),
'$extra3' => sprintf( t('To select all posts for a given month, such as January of this year, visit <a href="%1$s">%2$s</a>'),$janurl,$janurl),
'$extra4' => sprintf( t('These content files may be imported or restored by visiting <a href="%1$s">%2$s</a> on any site containing your channel. For best results please import or restore these in date order (oldest first).'),$impurl,$impurl)
));
return $o;
}
}

View File

@@ -44,10 +44,8 @@ class Webpages extends Controller {
if(! Apps::system_app_installed(App::$profile_uid, 'Webpages')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Webpages App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('Provide managed web pages on your channel');
return $o;
$papp = Apps::get_papp('Webpages');
return Apps::app_render($papp, 'module');
}
nav_set_selected('Webpages');

View File

@@ -48,10 +48,8 @@ class Wiki extends Controller {
if(! Apps::system_app_installed(App::$profile_uid, 'Wiki')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Wiki App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('Provide a wiki for your channel');
return $o;
$papp = Apps::get_papp('Wiki');
return Apps::app_render($papp, 'module');
}

27
Zotlabs/Update/_1248.php Normal file
View File

@@ -0,0 +1,27 @@
<?php
namespace Zotlabs\Update;
class _1248 {
function run() {
q("START TRANSACTION");
// remove possible bogus entries from xconfig
$r = dbq("DELETE FROM xconfig WHERE xchan = ''");
// remove gnu social app - it has been moved to addons unmaintained
$r1 = dbq("DELETE FROM app WHERE app_plugin = 'gnusoc'");
if($r && $r1) {
q("COMMIT");
return UPDATE_SUCCESS;
}
q("ROLLBACK");
return UPDATE_FAILED;
}
}

View File

@@ -35,7 +35,7 @@ class Activity {
}
}
foreach($contributors as $k => $v) {
$arr[] = [ 'author_xchan' => $k, 'total' => $v ];
$arr[] = [ 'author_xchan' => $k, 'total' => $v ];
}
usort($arr,'total_sort');
xchan_query($arr);
@@ -43,19 +43,19 @@ class Activity {
$x = [ 'entries' => $arr ];
call_hooks('activity_widget',$x);
$arr = $x['entries'];
$arr = $x['entries'];
if($arr) {
$o .= '<div class="widget">';
$o .= '<h3>' . t('Activity','widget') . '</h3><ul class="nav nav-pills flex-column">';
$o .= '<h3>' . t('Activity','widget') . '</h3><ul class="nav rounded-pill flex-column">';
foreach($arr as $rv) {
$o .= '<li class="nav-item"><a class="nav-link" href="network?f=&xchan=' . urlencode($rv['author_xchan']) . '" ><span class="badge badge-secondary float-right">' . ((intval($rv['total'])) ? intval($rv['total']) : '') . '</span><img src="' . $rv['author']['xchan_photo_s'] . '" class="menu-img-1" /> ' . $rv['author']['xchan_name'] . '</a></li>';
$o .= '<li class="nav-item"><a class="nav-link" href="network?f=&xchan=' . urlencode($rv['author_xchan']) . '" ><span class="badge bg-secondary float-end">' . ((intval($rv['total'])) ? intval($rv['total']) : '') . '</span><img src="' . $rv['author']['xchan_photo_s'] . '" class="menu-img-1" /> ' . $rv['author']['xchan_name'] . '</a></li>';
}
$o .= '</ul></div>';
}
return $o;
}
}
}

View File

@@ -40,7 +40,7 @@ class Appcategories {
$terms[] = array('name' => $rr['term'], 'selected' => (($selected == $rr['term']) ? 'selected' : ''));
return replace_macros(get_markup_template('categories_widget.tpl'),array(
'$title' => t('Categories'),
'$title' => t('App Categories'),
'$desc' => '',
'$sel_all' => (($selected == '') ? 'selected' : ''),
'$all' => t('Everything'),

View File

@@ -6,12 +6,11 @@ namespace Zotlabs\Widget;
class Appstore {
function widget($arr) {
$store = ((argc() > 1 && argv(1) === 'available') ? 1 : 0);
return replace_macros(get_markup_template('appstore.tpl'), [
return replace_macros(get_markup_template('appstore.tpl'), [
'$title' => t('App Collections'),
'$options' => [
[ z_root() . '/apps', t('Installed apps'), 1 - $store ],
[ z_root() . '/apps/available', t('Available Apps'), $store ]
[z_root() . '/apps', t('Installed apps'), ((argc() == 1 && argv(0) === 'apps') ? 1 : 0)],
[z_root() . '/apps/available', t('Available Apps'), ((argc() > 1 && argv(1) === 'available') ? 1 : 0)]
]
]);
}

View File

@@ -34,7 +34,7 @@ class Forums {
intval(local_channel())
);
if($x2) {
if($x2) {
$xf = ids_to_querystr($x2,'xchan',true);
// private forums
@@ -47,7 +47,7 @@ class Forums {
}
}
$sql_extra = (($xf) ? " and ( xchan_hash in (" . $xf . ") or xchan_pubforum = 1 ) " : " and xchan_pubforum = 1 ");
$sql_extra = (($xf) ? " and ( xchan_hash in (" . $xf . ") or xchan_pubforum = 1 ) " : " and xchan_pubforum = 1 ");
@@ -64,7 +64,7 @@ class Forums {
// There also should be a way to update this via ajax.
for($x = 0; $x < count($r1); $x ++) {
$r = q("select sum(item_unseen) as unseen from item
$r = q("select sum(item_unseen) as unseen from item
where uid = %d and owner_xchan = '%s' and item_unseen = 1 $perms_sql ",
intval(local_channel()),
dbesc($r1[$x]['xchan_hash'])
@@ -109,12 +109,12 @@ class Forums {
}
}
}
if($unseen && (! intval($rr['unseen'])))
continue;
$o .= '<li class="nav-item"><a class="nav-link" href="' . $link . '" ><span class="badge badge-secondary float-right">' . ((intval($rr['unseen'])) ? intval($rr['unseen']) : '') . '</span><img class ="menu-img-1" src="' . $rr['xchan_photo_s'] . '" /> ' . $rr['xchan_name'] . '</a></li>';
$o .= '<li class="nav-item"><a class="nav-link" href="' . $link . '" ><span class="badge bg-secondary float-end">' . ((intval($rr['unseen'])) ? intval($rr['unseen']) : '') . '</span><img class ="menu-img-1" src="' . $rr['xchan_photo_s'] . '" /> ' . $rr['xchan_name'] . '</a></li>';
}
$o .= '</ul></div>';
}

View File

@@ -40,15 +40,15 @@ class Pinned {
$observer = \App::get_observer();
foreach($items as $item) {
$midb64 = 'b64.' . base64url_encode($item['mid']);
$midb64 = gen_link_id($item['mid']);
if(isset($observer['xchan_hash']) && in_array($observer['xchan_hash'], get_pconfig($item['uid'], 'pinned_hide', $midb64, [])))
continue;
$author = channelx_by_hash($item['author_xchan']);
$owner = channelx_by_hash($item['owner_xchan']);
$profile_avatar = $author['xchan_photo_m'];
$profile_link = chanlink_hash($item['author_xchan']);
$profile_name = $author['xchan_name'];
@@ -71,7 +71,7 @@ class Pinned {
$isevent = true;
}
}
$consensus = (intval($item['item_consensus']) ? true : false);
if($consensus) {
$conv_responses['agree'] = [ 'title' => t('Agree','title') ];
@@ -87,7 +87,7 @@ class Pinned {
$verified = (intval($item['item_verified']) ? t('Message signature validated') : '');
$forged = ((! intval($item['item_verified']) && $item['sig']) ? t('Message signature incorrect') : '');
$shareable = ((local_channel() && \App::$profile_uid == local_channel() && $item['item_private'] != 1) ? true : false);
if ($shareable) {
// This actually turns out not to be possible in some protocol stacks without opening up hundreds of new issues.
@@ -102,9 +102,9 @@ class Pinned {
$is_new = boolval(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0);
$body = prepare_body($item,true);
$str = [
'item_type' => intval($item['item_type']),
'item_type' => intval($item['item_type']),
'body' => $body['html'],
'tags' => $body['tags'],
'categories' => $body['categories'],
@@ -115,7 +115,7 @@ class Pinned {
'id' => $item['id'],
'mids' => json_encode([ $midb64 ]),
'isevent' => $isevent,
'attend' => $attend,
'attend' => $attend,
'consensus' => $consensus,
'conlabels' => ($canvote ? $conlabels : []),
'canvote' => $canvote,
@@ -158,55 +158,55 @@ class Pinned {
'modal_dismiss' => t('Close'),
'responses' => $conv_responses
];
$tpl = get_markup_template('pinned_item.tpl');
$tpl = get_markup_template('pinned_item.tpl');
$ret['html'] .= replace_macros($tpl, $str);
}
return $ret;
}
/*
* @brief List pinned items depend on type
*
* @param $types
* @return array of pinned items
*
*/
*/
private function list($types) {
if(empty($types) || (! is_array($types)))
return [];
$item_types = array_intersect($this->allowed_types, $types);
if(empty($item_types))
return [];
$mids_list = [];
foreach($item_types as $type) {
$mids = get_pconfig($this->uid, 'pinned', $type, []);
foreach($mids as $mid) {
if(! empty($mid) && strpos($mid,'b64.') === 0)
$mids_list[] = @base64url_decode(substr($mid,4));
if(!empty($mid))
$mids_list[] = unpack_link_id($mid);
}
}
if(empty($mids_list))
return [];
$r = q("SELECT * FROM item WHERE mid IN ( '%s' ) AND uid = %d AND id = parent AND item_private = 0 ORDER BY created DESC",
dbesc(implode(",", $mids_list)),
intval($this->uid)
);
if($r)
return $r;
return [];
}
/*
* @brief List activities on item
*
@@ -214,7 +214,7 @@ class Pinned {
* @param array $conv_responses
* @return array
*
*/
*/
private function activity($item, &$conv_responses) {
foreach(array_keys($conv_responses) as $verb) {
@@ -256,23 +256,23 @@ class Pinned {
unset($conv_responses[$verb]);
continue;
}
$conv_responses[$verb]['count'] = count($r);
$conv_responses[$verb]['button'] = get_response_button_text($verb, $conv_responses[$verb]['count']);
foreach($r as $rr) {
$author = q("SELECT * FROM xchan WHERE xchan_hash = '%s' LIMIT 1",
dbesc($rr['author_xchan'])
);
$name = (($author && $author[0]['xchan_name']) ? $author[0]['xchan_name'] : t('Unknown'));
$conv_responses[$verb]['list'][] = (($rr['author_xchan'] && $author && $author[0]['xchan_photo_s']) ?
'<a class="dropdown-item" href="' . chanlink_hash($rr['author_xchan']) . '">' . '<img class="menu-img-1" src="' . zid($author[0]['xchan_photo_s']) . '" alt="' . urlencode($name) . '" /> ' . $name . '</a>' :
'<a class="dropdown-item" href="' . chanlink_hash($rr['author_xchan']) . '">' . '<img class="menu-img-1" src="' . zid($author[0]['xchan_photo_s']) . '" alt="' . urlencode($name) . '" /> ' . $name . '</a>' :
'<a class="dropdown-item" href="#" class="disabled">' . $name . '</a>'
);
}
}
$conv_responses['count'] = count($conv_responses);
}
}

View File

@@ -1,4 +1,4 @@
version: 1
version: 2
url: $baseurl/affinity
requires: local_channel
name: Affinity Tool

View File

@@ -1,6 +1,7 @@
version: 2
version: 3
url: $baseurl/articles/$nick
name: Articles
requires: local_channel
photo: icon:file-text-o
categories: nav_featured_app, Productivity
desc: Create interactive articles

View File

@@ -1,6 +1,7 @@
version: 2
version: 3
url: $baseurl/bookmarks
requires: local_channel
name: Bookmarks
photo: icon:bookmark
categories: Productivity
desc: This app enables you to bookmark links from posts or comments and provides a simple management interface

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -1,5 +1,6 @@
version: 2
version: 3
url: https://framagit.org/hubzilla/core/issues
name: Report Bug
photo: icon:bug
categories: System
desc: Provides a link to the Hubzilla bug tracker.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -1,6 +1,7 @@
version: 1
version: 2
url: $baseurl/cdav/calendar, $baseurl/settings/calendar
requires: local_channel
name: Calendar
photo: icon:calendar
categories: Productivity, nav_featured_app
desc: DAV capable calendar

View File

@@ -1,6 +1,7 @@
version: 2
version: 3
url: $baseurl/cdav/addressbook
requires: local_channel
name: CardDAV
photo: icon:vcard-o
categories: Productivity, Personal
desc: DAV capable addressbook

View File

@@ -1,6 +1,7 @@
version: 2
version: 3
url: $baseurl/cards/$nick
name: Cards
requires: local_channel
photo: icon:list
categories: nav_featured_app, Productivity
desc: Create interactive personal planning cards.

View File

@@ -1,6 +1,7 @@
version: 2
version: 3
url: $baseurl/channel/$nick, $baseurl/settings/channel_home
requires: local_channel
name: Channel Home
photo: icon:home
categories: nav_featured_app, Personal
desc: Your channel homepage featuring your personal posts.

View File

@@ -1,6 +1,7 @@
version: 2
version: 3
url: $baseurl/chat/$nick
requires: local_channel
name: Chatrooms
photo: icon:comments-o
categories: Productivity
desc: Access controlled personal chatrooms.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -1,6 +1,7 @@
version: 2
version: 3
url: $baseurl/connections, $baseurl/settings/connections
requires: local_channel
name: Connections
photo: icon:users
categories: nav_featured_app, Networking
desc: Manage your connections.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -1,6 +1,7 @@
version: 2
version: 3
url: $baseurl/defperms
requires: local_channel, custom_role
name: Default Permissions
photo: icon:unlock-alt
categories: Access Control
desc: Set custom default permissions for new connections.

View File

@@ -1,5 +1,6 @@
version: 2
version: 3
url: $baseurl/directory, $baseurl/settings/directory
name: Directory
photo: icon:sitemap
categories: nav_featured_app, Networking
desc: Members directory of the Zot network.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -1,6 +1,7 @@
version: 2
version: 3
url: $baseurl/group
requires: local_channel
name: Privacy Groups
photo: icon:users
categories: Networking
desc: A tool to create and manage privacy groups.

View File

@@ -1,5 +1,6 @@
version: 2
version: 3
url: $baseurl/help
name: Help
photo: icon:question
categories: nav_featured_app, System
desc: The Hubzilla help pages.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

View File

@@ -1,6 +1,7 @@
version: 1
version: 2
url: $baseurl/hq
requires: local_channel
name: HQ
photo: icon:user-circle-o
categories: nav_pinned_app
desc: The default landing page after login. It provides a quick overview over recent posts and direct messages.

View File

@@ -1,6 +1,7 @@
version: 2
version: 3
url: $baseurl/invite
requires: local_channel
name: Invite
photo: icon:user-plus
categories: Networking
desc: Send invite emails with an invite token. This app only works if your hub is configured to allow invites.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -1,5 +1,6 @@
version: 5.6
version: 3
url: $baseurl/lang
name: Language
photo: icon:language
categories: System
desc: A simple language selector.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

View File

@@ -1,6 +1,7 @@
version: 2
version: 3
url: $baseurl/mood
requires: local_channel
name: Mood
photo: icon:smile-o
categories: Social
desc: Set your current mood and tell your friends.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

View File

@@ -1,6 +1,7 @@
version: 2
version: 3
url: $baseurl/network, $baseurl/settings/network
requires: local_channel
name: Network
photo: icon:th
categories: nav_featured_app, Networking
desc: Your network activity in a traditional timeline view.

View File

@@ -1,6 +1,7 @@
version: 2
version: 3
url: $baseurl/notes
requires: local_channel
name: Notes
photo: icon:sticky-note-o
categories: Personal, Productivity
desc: A simple notes app. It provides a dedicated notes app and a widget which can be added to other pages.

View File

@@ -1,6 +1,7 @@
version: 2
version: 3
url: $baseurl/oauth
requires: local_channel
name: OAuth Apps Manager
photo: icon:chevron-circle-up
categories: Access Control
desc: Manage OAuth authentication tokens for mobile and remote apps.

View File

@@ -1,6 +1,7 @@
version: 2
version: 3
url: $baseurl/oauth2
requires: local_channel
name: OAuth2 Apps Manager
photo: icon:chevron-circle-up
categories: Access Control
desc: Manage OAuth2 authentication tokens for mobile and remote apps.

View File

@@ -1,6 +1,7 @@
version: 2
version: 3
url: $baseurl/pdledit
requires: local_channel
name: PDL Editor
photo: icon:object-group
categories: Appearance
desc: An editor for system page layouts.

View File

@@ -1,6 +1,7 @@
version: 2
version: 3
url: $baseurl/permcats
requires: local_channel
name: Permission Categories
photo: icon:unlock-alt
categories: Access Control
desc: Create and manage custom connection permission limits.

View File

@@ -1,6 +1,7 @@
version: 2
version: 3
url: $baseurl/photos/$nick, $baseurl/settings/photos
requires: local_channel
name: Photos
photo: icon:photo
categories: nav_featured_app, Multimedia
desc: A simple tool to view and manage your photos.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -1,6 +1,7 @@
version: 2
version: 3
url: $baseurl/poke
requires: local_channel
name: Poke
photo: icon:hand-o-right
categories: Social
desc: Poke somebody in your addressbook.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

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