aboutsummaryrefslogtreecommitdiffstats
path: root/Zotlabs
diff options
context:
space:
mode:
authorMario Vavti <mario@mariovavti.com>2022-03-29 11:42:53 +0200
committerMario Vavti <mario@mariovavti.com>2022-03-29 11:42:53 +0200
commit0784cd593a39a4fc297e8a82f7e79bc8019a0868 (patch)
tree22182afb37cf460f8208fff9d276a0672add3185 /Zotlabs
parent0e2e9321025f87fe9587f3d183adaea6185e4e20 (diff)
parent9c5d2ee5630dd7033904039dcd1e92db8821b644 (diff)
downloadvolse-hubzilla-0784cd593a39a4fc297e8a82f7e79bc8019a0868.tar.gz
volse-hubzilla-0784cd593a39a4fc297e8a82f7e79bc8019a0868.tar.bz2
volse-hubzilla-0784cd593a39a4fc297e8a82f7e79bc8019a0868.zip
Merge branch '7.2RC'7.2
Diffstat (limited to 'Zotlabs')
-rw-r--r--Zotlabs/Daemon/Gprobe.php28
-rw-r--r--Zotlabs/Lib/AccessList.php49
-rw-r--r--Zotlabs/Lib/Activity.php360
-rw-r--r--Zotlabs/Lib/ActivityStreams.php8
-rw-r--r--Zotlabs/Lib/Crypto.php4
-rw-r--r--Zotlabs/Lib/Enotify.php6
-rw-r--r--Zotlabs/Lib/LDSignatures.php11
-rw-r--r--Zotlabs/Lib/Libzot.php103
-rw-r--r--Zotlabs/Lib/MessageFilter.php214
-rw-r--r--Zotlabs/Module/Directory.php12
-rw-r--r--Zotlabs/Module/Hq.php5
-rw-r--r--Zotlabs/Module/Item.php3
-rw-r--r--Zotlabs/Module/Network.php20
-rw-r--r--Zotlabs/Module/Pdledit_gui.php553
-rw-r--r--Zotlabs/Module/Settings/Calendar.php10
-rw-r--r--Zotlabs/Module/Settings/Channel.php6
-rw-r--r--Zotlabs/Module/Settings/Channel_home.php10
-rw-r--r--Zotlabs/Module/Settings/Connections.php10
-rw-r--r--Zotlabs/Module/Settings/Directory.php10
-rw-r--r--Zotlabs/Module/Settings/Editor.php10
-rw-r--r--Zotlabs/Module/Settings/Events.php10
-rw-r--r--Zotlabs/Module/Settings/Manage.php10
-rw-r--r--Zotlabs/Module/Settings/Network.php8
-rw-r--r--Zotlabs/Module/Settings/Photos.php12
-rw-r--r--Zotlabs/Module/Settings/Privacy.php2
-rw-r--r--Zotlabs/Module/Settings/Profiles.php4
-rw-r--r--Zotlabs/Photo/PhotoDriver.php10
-rw-r--r--Zotlabs/Web/HTTPSig.php61
-rw-r--r--Zotlabs/Web/WebServer.php3
-rw-r--r--Zotlabs/Widget/Activity.php5
-rw-r--r--Zotlabs/Widget/Activity_filter.php7
-rw-r--r--Zotlabs/Widget/Activity_order.php8
-rw-r--r--Zotlabs/Widget/Admin.php5
-rw-r--r--Zotlabs/Widget/Affinity.php12
-rw-r--r--Zotlabs/Widget/Album.php8
-rw-r--r--Zotlabs/Widget/Appcategories.php6
-rw-r--r--Zotlabs/Widget/Appcloud.php6
-rw-r--r--Zotlabs/Widget/Appstore.php6
-rw-r--r--Zotlabs/Widget/Archive.php6
-rw-r--r--Zotlabs/Widget/Bookmarkedchats.php9
-rw-r--r--Zotlabs/Widget/Catcloud.php9
-rw-r--r--Zotlabs/Widget/Catcloud_wall.php6
-rw-r--r--Zotlabs/Widget/Categories.php6
-rw-r--r--Zotlabs/Widget/Cdav.php10
-rw-r--r--Zotlabs/Widget/Chatroom_list.php6
-rw-r--r--Zotlabs/Widget/Chatroom_members.php6
-rw-r--r--Zotlabs/Widget/Clock.php5
-rw-r--r--Zotlabs/Widget/Collections.php54
-rw-r--r--Zotlabs/Widget/Common_friends.php8
-rw-r--r--Zotlabs/Widget/Cover_photo.php6
-rw-r--r--Zotlabs/Widget/Design_tools.php8
-rw-r--r--Zotlabs/Widget/Dirsort.php6
-rw-r--r--Zotlabs/Widget/Dirtags.php6
-rw-r--r--Zotlabs/Widget/Eventstools.php19
-rw-r--r--Zotlabs/Widget/Filer.php7
-rw-r--r--Zotlabs/Widget/Findpeople.php5
-rw-r--r--Zotlabs/Widget/Follow.php7
-rw-r--r--Zotlabs/Widget/Forums.php35
-rw-r--r--Zotlabs/Widget/Fullprofile.php6
-rw-r--r--Zotlabs/Widget/Helpindex.php7
-rw-r--r--Zotlabs/Widget/Hq_controls.php7
-rw-r--r--Zotlabs/Widget/Item.php8
-rw-r--r--Zotlabs/Widget/Menu_preview.php6
-rw-r--r--Zotlabs/Widget/Messages.php27
-rw-r--r--Zotlabs/Widget/Newmember.php9
-rw-r--r--Zotlabs/Widget/Notes.php11
-rw-r--r--Zotlabs/Widget/Notifications.php6
-rw-r--r--Zotlabs/Widget/Permcats.php7
-rw-r--r--Zotlabs/Widget/Photo.php6
-rw-r--r--Zotlabs/Widget/Photo_albums.php6
-rw-r--r--Zotlabs/Widget/Photo_rand.php11
-rw-r--r--Zotlabs/Widget/Pinned.php9
-rw-r--r--Zotlabs/Widget/Portfolio.php10
-rw-r--r--Zotlabs/Widget/Privacygroups.php7
-rw-r--r--Zotlabs/Widget/Profile.php7
-rw-r--r--Zotlabs/Widget/Pubsites.php16
-rw-r--r--Zotlabs/Widget/Pubtagcloud.php5
-rw-r--r--Zotlabs/Widget/Random_block.php5
-rw-r--r--Zotlabs/Widget/Rating.php6
-rw-r--r--Zotlabs/Widget/Savedsearch.php6
-rw-r--r--Zotlabs/Widget/Settings_menu.php5
-rw-r--r--Zotlabs/Widget/Shortprofile.php18
-rw-r--r--Zotlabs/Widget/Sitesearch.php6
-rw-r--r--Zotlabs/Widget/Suggestedchats.php10
-rw-r--r--Zotlabs/Widget/Suggestions.php13
-rw-r--r--Zotlabs/Widget/Tagcloud.php5
-rw-r--r--Zotlabs/Widget/Tagcloud_wall.php6
-rw-r--r--Zotlabs/Widget/Tasklist.php9
-rw-r--r--Zotlabs/Widget/Tokens.php6
-rw-r--r--Zotlabs/Widget/Vcard.php5
-rw-r--r--Zotlabs/Widget/Website_portation_tools.php7
-rw-r--r--Zotlabs/Widget/Wiki_list.php5
-rw-r--r--Zotlabs/Widget/Wiki_page_history.php8
-rw-r--r--Zotlabs/Widget/Wiki_pages.php10
-rw-r--r--Zotlabs/Widget/Zcard.php5
95 files changed, 1661 insertions, 484 deletions
diff --git a/Zotlabs/Daemon/Gprobe.php b/Zotlabs/Daemon/Gprobe.php
index 29efcf475..1124ead54 100644
--- a/Zotlabs/Daemon/Gprobe.php
+++ b/Zotlabs/Daemon/Gprobe.php
@@ -15,19 +15,31 @@ class Gprobe {
return;
$url = hex2bin($argv[1]);
+ $is_webbie = false;
+ $r = null;
- if (!strpos($url, '@'))
- return;
+ if (filter_var($url, FILTER_VALIDATE_EMAIL)) {
+ $is_webbie = true;
- $r = q("select * from hubloc where hubloc_addr = '%s' and hubloc_network = 'zot6' limit 1",
- dbesc($url)
- );
+ $r = q("select * from hubloc where hubloc_addr = '%s' and hubloc_network = 'zot6' limit 1",
+ dbesc($url)
+ );
+ }
+ elseif (filter_var($url, FILTER_VALIDATE_URL)) {
+ $r = q("select * from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
+ dbesc($url)
+ );
+ }
if (!$r) {
- $href = Webfinger::zot_url(punify($url));
- if ($href) {
- $zf = Zotfinger::exec($href, null);
+ if ($is_webbie) {
+ $url = Webfinger::zot_url(punify($url));
}
+
+ if ($url) {
+ $zf = Zotfinger::exec($url, null);
+ }
+
if (is_array($zf) && array_path_exists('signature/signer', $zf) && $zf['signature']['signer'] === $href && intval($zf['signature']['header_valid'])) {
Libzot::import_xchan($zf['data']);
}
diff --git a/Zotlabs/Lib/AccessList.php b/Zotlabs/Lib/AccessList.php
index 026148c9f..f4b762eaa 100644
--- a/Zotlabs/Lib/AccessList.php
+++ b/Zotlabs/Lib/AccessList.php
@@ -311,55 +311,6 @@ class AccessList {
return $o;
}
-/* deprecated
- static function widget($every = "connections", $each = "lists", $edit = false, $group_id = 0, $cid = '', $mode = 1) {
-
- $groups = [];
-
- $r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
- intval($_SESSION['uid'])
- );
- $member_of = [];
- if ($cid) {
- $member_of = self::containing(local_channel(), $cid);
- }
-
- if ($r) {
- foreach ($r as $rr) {
- $selected = (($group_id == $rr['id']) ? ' group-selected' : '');
-
- if ($edit) {
- $groupedit = ['href' => "lists/" . $rr['id'], 'title' => t('edit')];
- }
- else {
- $groupedit = null;
- }
-
- $groups[] = [
- 'id' => $rr['id'],
- 'enc_cid' => base64url_encode($cid),
- 'cid' => $cid,
- 'text' => $rr['gname'],
- 'selected' => $selected,
- 'href' => (($mode == 0) ? $each . '?f=&gid=' . $rr['id'] : $each . "/" . $rr['id']) . ((x($_GET, 'new')) ? '&new=' . $_GET['new'] : '') . ((x($_GET, 'order')) ? '&order=' . $_GET['order'] : ''),
- 'edit' => $groupedit,
- 'ismember' => in_array($rr['id'], $member_of),
- ];
- }
- }
-
- return replace_macros(get_markup_template('group_side.tpl'), [
- '$title' => t('Privacy Groups'),
- '$edittext' => t('Edit group'),
- '$createtext' => t('Create new group'),
- '$ungrouped' => (($every === 'contacts') ? t('Channels not in any privacy group') : ''),
- '$groups' => $groups,
- '$add' => t('Add'),
- ]);
-
- }
-*/
-
static function expand($g) {
if (!(is_array($g) && count($g))) {
return [];
diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php
index e51922c86..0c25605e7 100644
--- a/Zotlabs/Lib/Activity.php
+++ b/Zotlabs/Lib/Activity.php
@@ -501,7 +501,7 @@ class Activity {
$ret['attributedTo'] = $i['author']['xchan_url'];
- if ($i['id'] != $i['parent']) {
+ if ($i['mid'] !== $i['parent_mid']) {
$ret['inReplyTo'] = ((strpos($i['thr_parent'], 'http') === 0) ? $i['thr_parent'] : z_root() . '/item/' . urlencode($i['thr_parent']));
}
@@ -608,10 +608,10 @@ class Activity {
$ptr = [$ptr];
}
foreach ($ptr as $t) {
- if (!array_key_exists('type', $t))
+ if (is_array($t) && !array_key_exists('type', $t))
$t['type'] = 'Hashtag';
- if (array_key_exists('href', $t) && array_key_exists('name', $t)) {
+ if (is_array($t) && array_key_exists('href', $t) && array_key_exists('name', $t)) {
switch ($t['type']) {
case 'Hashtag':
$ret[] = ['ttype' => TERM_HASHTAG, 'url' => $t['href'], 'term' => escape_tags((substr($t['name'], 0, 1) === '#') ? substr($t['name'], 1) : $t['name'])];
@@ -875,7 +875,7 @@ class Activity {
}
}
- if ($i['id'] != $i['parent']) {
+ if ($i['mid'] !== $i['parent_mid']) {
$reply = true;
// inReplyTo needs to be set in the activity for followup actions (Like, Dislike, Announce, etc.),
@@ -1154,9 +1154,10 @@ class Activity {
$ret['url'] = $p['xchan_url'];
$ret['publicKey'] = [
- 'id' => $p['xchan_url'],
- 'owner' => $p['xchan_url'],
- 'publicKeyPem' => $p['xchan_pubkey']
+ 'id' => $p['xchan_url'],
+ 'owner' => $p['xchan_url'],
+ 'signatureAlgorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
+ 'publicKeyPem' => $p['xchan_pubkey']
];
if ($c) {
@@ -1599,6 +1600,25 @@ class Activity {
return;
}
+ public static function drop($channel, $observer, $act) {
+ $r = q(
+ "select * from item where mid = '%s' and uid = %d limit 1",
+ dbesc((is_array($act->obj)) ? $act->obj['id'] : $act->obj),
+ intval($channel['channel_id'])
+ );
+
+ if (!$r) {
+ return;
+ }
+
+ if (in_array($observer, [$r[0]['author_xchan'], $r[0]['owner_xchan']])) {
+ drop_item($r[0]['id'], false);
+ } elseif (in_array($act->actor['id'], [$r[0]['author_xchan'], $r[0]['owner_xchan']])) {
+ drop_item($r[0]['id'], false);
+ }
+ }
+
+
static function actor_store($url, $person_obj, $force = false) {
if (!is_array($person_obj)) {
@@ -1618,6 +1638,7 @@ class Activity {
$ap_hubloc = null;
$hublocs = self::get_actor_hublocs($url);
+ $has_zot_hubloc = false;
if ($hublocs) {
foreach ($hublocs as $hub) {
@@ -1625,6 +1646,7 @@ class Activity {
$ap_hubloc = $hub;
}
if ($hub['hubloc_network'] === 'zot6') {
+ $has_zot_hubloc = true;
Libzot::update_cached_hubloc($hub);
}
}
@@ -1648,16 +1670,18 @@ class Activity {
return;
}
- $inbox = $person_obj['inbox'];
+ $inbox = $person_obj['inbox'] ?? null;
- // invalid identity
+ // invalid AP identity
if (!$inbox || strpos($inbox, z_root()) !== false) {
return;
}
// store the actor record in XConfig
- XConfig::Set($url, 'system', 'actor_record', $person_obj);
+
+ // we already store this in Activity::fetch()
+ // XConfig::Set($url, 'system', 'actor_record', $person_obj);
$name = $person_obj['name'];
if (!$name) {
@@ -1814,12 +1838,12 @@ class Activity {
// Adding zot discovery urls to the actor record will cause federation to fail with the 20-30 projects which don't accept arrays in the url field.
$actor_protocols = self::get_actor_protocols($person_obj);
- if (in_array('zot6', $actor_protocols)) {
+ if (!$has_zot_hubloc && in_array('zot6', $actor_protocols)) {
$zx = q("select * from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6'",
dbesc($url)
);
- if (!$zx && $webfinger_addr) {
- Master::Summon(['Gprobe', bin2hex($webfinger_addr)]);
+ if (!$zx) {
+ Master::Summon(['Gprobe', bin2hex($url)]);
}
}
@@ -1922,11 +1946,6 @@ class Activity {
}
}
- $abook = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
- dbesc($observer_hash),
- intval($channel['channel_id'])
- );
-
$content = self::get_content($act->obj);
if (!$content) {
@@ -2004,15 +2023,23 @@ class Activity {
}
if ($channel['channel_system']) {
- if (!MessageFilter::evaluate($s, get_config('system', 'pubstream_incl'), get_config('system', 'pubstream_excl'))) {
+ $incl = get_config('system','pubstream_incl');
+ $excl = get_config('system','pubstream_excl');
+
+ if(($incl || $excl) && !MessageFilter::evaluate($s, $incl, $excl)) {
logger('post is filtered');
return;
}
}
+ $abook = q("select * from abook where (abook_xchan = '%s' OR abook_xchan = '%s') and abook_channel = %d ",
+ dbesc($s['author_xchan']),
+ dbesc($s['owner_xchan']),
+ intval($channel['channel_id'])
+ );
if ($abook) {
- if (!post_is_importable($s, $abook[0])) {
+ if (!post_is_importable($channel['channel_id'], $s, $abook)) {
logger('post is filtered');
return;
}
@@ -2221,6 +2248,21 @@ class Activity {
static function decode_note($act) {
+ $response_activity = false;
+
+ $s = [];
+
+ // These activities should have been handled separately in the Inbox module and should not be turned into posts
+
+ if (
+ in_array($act->type, ['Follow', 'Accept', 'Reject', 'Create', 'Update']) &&
+ is_array($act->obj) &&
+ array_key_exists('type', $act->obj) &&
+ ($act->obj['type'] === 'Follow' || ActivityStreams::is_an_actor($act->obj['type']))
+ ) {
+ return false;
+ }
+
// Within our family of projects, Follow/Unfollow of a thread is an internal activity which should not be transmitted,
// hence if we receive it - ignore or reject it.
// Unfollow is not defined by ActivityStreams, which prefers Undo->Follow.
@@ -2230,22 +2272,31 @@ class Activity {
return false;
}
- $response_activity = false;
+ if (!isset($act->actor['id'])) {
+ logger('No actor!');
+ return false;
+ }
- $s = [];
+ // ensure we store the original actor
+ self::actor_store($act->actor['id'], $act->actor);
+
+ $s['owner_xchan'] = $act->actor['id'];
+ $s['author_xchan'] = $act->actor['id'];
if (is_array($act->obj)) {
$content = self::get_content($act->obj);
}
- $s['owner_xchan'] = $act->actor['id'];
- $s['author_xchan'] = $act->actor['id'];
+ $s['mid'] = ((is_array($act->obj) && isset($act->obj['id'])) ? $act->obj['id'] : $act->obj);
- // ensure we store the original actor
- self::actor_store($act->actor['id'], $act->actor);
+ if (!$s['mid']) {
+ return false;
+ }
+
+ // Friendica sends the diaspora guid in a nonstandard field via AP
+ // If no uuid is provided we will create an uuid v5 from the mid
+ $s['uuid'] = ((is_array($act->obj) && isset($act->obj['diaspora:guid'])) ? $act->obj['diaspora:guid'] : uuid_from_url($s['mid']));
- $s['mid'] = $act->obj['id'];
- $s['uuid'] = $act->obj['diaspora:guid'];
$s['parent_mid'] = $act->parent_id;
if (array_key_exists('published', $act->data)) {
@@ -2269,13 +2320,18 @@ class Activity {
$s['expires'] = datetime_convert('UTC', 'UTC', $act->obj['expires']);
}
+ if ($act->type === 'Invite' && is_array($act->obj) && array_key_exists('type', $act->obj) && $act->obj['type'] === 'Event') {
+ $s['mid'] = $s['parent_mid'] = $act->id;
+ }
+
if (ActivityStreams::is_response_activity($act->type)) {
$response_activity = true;
$s['mid'] = $act->id;
- // $s['parent_mid'] = $act->obj['id'];
- $s['uuid'] = $act->data['diaspora:guid'];
+ $s['uuid'] = ((is_array($act->data) && isset($act->data['diaspora:guid'])) ? $act->data['diaspora:guid'] : uuid_from_url($s['mid']));
+
+ $s['parent_mid'] = ((is_array($act->obj) && isset($act->obj['id'])) ? $act->obj['id'] : $act->obj);
// over-ride the object timestamp with the activity
@@ -2288,8 +2344,8 @@ class Activity {
}
$obj_actor = ((isset($act->obj['actor'])) ? $act->obj['actor'] : $act->get_actor('attributedTo', $act->obj));
- // ensure we store the original actor
+ // ensure we store the original actor
self::actor_store($obj_actor['id'], $obj_actor);
$mention = self::get_actor_bbmention($obj_actor['id']);
@@ -2318,13 +2374,41 @@ class Activity {
}
if ($act->type === 'Announce') {
- $content['content'] = sprintf(t('&#x1f501; Repeated %1$s\'s %2$s'), $mention, $act->obj['type']);
+ $s['author_xchan'] = $obj_actor['id'];
+ $s['mid'] = $act->obj['id'];
+ $s['parent_mid'] = $act->obj['id'];
}
if ($act->type === 'emojiReaction') {
$content['content'] = (($act->tgt && $act->tgt['type'] === 'Image') ? '[img=32x32]' . $act->tgt['url'] . '[/img]' : '&#x' . $act->tgt['name'] . ';');
}
}
+ $s['item_thread_top'] = 0;
+ $s['comment_policy'] = 'authenticated';
+
+ if ($s['mid'] === $s['parent_mid']) {
+ $s['item_thread_top'] = 1;
+
+ // it is a parent node - decode the comment policy info if present
+ if (isset($act->obj['commentPolicy'])) {
+ $until = strpos($act->obj['commentPolicy'], 'until=');
+ if ($until !== false) {
+ $s['comments_closed'] = datetime_convert('UTC', 'UTC', substr($act->obj['commentPolicy'], $until + 6));
+ if ($s['comments_closed'] < datetime_convert()) {
+ $s['nocomment'] = true;
+ }
+ }
+
+ $remainder = substr($act->obj['commentPolicy'], 0, (($until) ? $until : strlen($act->obj['commentPolicy'])));
+ if ($remainder) {
+ $s['comment_policy'] = $remainder;
+ }
+ if (!(isset($item['comment_policy']) && strlen($item['comment_policy']))) {
+ $s['comment_policy'] = 'contacts';
+ }
+ }
+ }
+
if (!array_key_exists('created', $s))
$s['created'] = datetime_convert();
@@ -2335,6 +2419,16 @@ class Activity {
$s['summary'] = self::bb_content($content, 'summary');
$s['body'] = ((self::bb_content($content, 'bbcode') && (!$response_activity)) ? self::bb_content($content, 'bbcode') : self::bb_content($content, 'content'));
+ if (isset($act->obj['quoteUrl'])) {
+ $quote_bbcode = self::get_quote_bbcode($act->obj['quoteUrl']);
+
+ if ($s['body']) {
+ $s['body'] .= "\r\n\r\n";
+ }
+
+ $s['body'] .= $quote_bbcode;
+ }
+
$s['verb'] = self::activity_decode_mapper($act->type);
// Mastodon does not provide update timestamps when updating poll tallies which means race conditions may occur here.
@@ -2351,6 +2445,12 @@ class Activity {
$s['obj_type'] = ACTIVITY_OBJ_COMMENT;
}
+ $s['obj'] = $act->obj;
+ if (is_array($s['obj']) && array_path_exists('actor/id', $s['obj'])) {
+ $s['obj']['actor'] = $s['obj']['actor']['id'];
+ }
+
+/*
$eventptr = null;
if ($act->obj['type'] === 'Invite' && array_path_exists('object/type', $act->obj) && $act->obj['object']['type'] === 'Event') {
@@ -2371,19 +2471,19 @@ class Activity {
$s['obj']['asld'] = $eventptr;
$s['obj']['type'] = ACTIVITY_OBJ_EVENT;
$s['obj']['id'] = $eventptr['id'];
- $s['obj']['title'] = $eventptr['name'];
+ $s['obj']['title'] = html2plain($eventptr['name']);
if (strpos($act->obj['startTime'], 'Z'))
$s['obj']['adjust'] = true;
else
- $s['obj']['adjust'] = false;
+ $s['obj']['adjust'] = true;
$s['obj']['dtstart'] = datetime_convert('UTC', 'UTC', $eventptr['startTime']);
if ($act->obj['endTime'])
$s['obj']['dtend'] = datetime_convert('UTC', 'UTC', $eventptr['endTime']);
else
$s['obj']['nofinish'] = true;
- $s['obj']['description'] = $eventptr['content'];
+ $s['obj']['description'] = html2bbcode($eventptr['content']);
if (array_path_exists('location/content', $eventptr))
$s['obj']['location'] = $eventptr['location']['content'];
@@ -2392,6 +2492,7 @@ class Activity {
else {
$s['obj'] = $act->obj;
}
+*/
$generator = $act->get_property_obj('generator');
if ((!$generator) && (!$response_activity)) {
@@ -2431,7 +2532,7 @@ class Activity {
if (array_key_exists('type', $act->obj)) {
if ($act->obj['type'] === 'Note' && $s['attach']) {
- $s['body'] .= self::bb_attach($s['attach'], $s['body']);
+ $s['body'] = self::bb_attach($s['attach'], $s['body']) . $s['body'];
}
if ($act->obj['type'] === 'Question' && in_array($act->type, ['Create', 'Update'])) {
@@ -2459,31 +2560,57 @@ class Activity {
'video/webm'
];
- $mps = [];
+ $mps = [];
+ $poster = null;
+ $ptr = null;
+
+ // try to find a poster to display on the video element
+
+ if (array_key_exists('icon',$act->obj)) {
+ if (is_array($act->obj['icon'])) {
+ if (array_key_exists(0,$act->obj['icon'])) {
+ $ptr = $act->obj['icon'];
+ }
+ else {
+ $ptr = [ $act->obj['icon'] ];
+ }
+ }
+ if ($ptr) {
+ foreach ($ptr as $foo) {
+ if (is_array($foo) && array_key_exists('type',$foo) && $foo['type'] === 'Image' && is_string($foo['url'])) {
+ $poster = $foo['url'];
+ }
+ }
+ }
+ }
+
+ $tag = (($poster) ? '[video poster=&quot;' . $poster . '&quot;]' : '[video]' );
$ptr = null;
- if (array_key_exists('url', $act->obj)) {
+ if (array_key_exists('url',$act->obj)) {
if (is_array($act->obj['url'])) {
- if (array_key_exists(0, $act->obj['url'])) {
+ if (array_key_exists(0,$act->obj['url'])) {
$ptr = $act->obj['url'];
}
else {
- $ptr = [$act->obj['url']];
+ $ptr = [ $act->obj['url'] ];
}
- foreach ($ptr as $vurl) {
- // peertube uses the non-standard element name 'mimeType' here
- if (array_key_exists('mimeType', $vurl)) {
- if (in_array($vurl['mimeType'], $vtypes)) {
- if (!array_key_exists('width', $vurl)) {
- $vurl['width'] = 0;
- }
- $mps[] = $vurl;
+ // handle peertube's weird url link tree if we find it here
+ // 0 => html link, 1 => application/x-mpegURL with 'tag' set to an array of actual media links
+ foreach ($ptr as $idex) {
+ if (is_array($idex) && array_key_exists('mediaType',$idex)) {
+ if ($idex['mediaType'] === 'application/x-mpegURL' && isset($idex['tag']) && is_array($idex['tag'])) {
+ $ptr = $idex['tag'];
+ break;
}
}
- elseif (array_key_exists('mediaType', $vurl)) {
+ }
+
+ foreach ($ptr as $vurl) {
+ if (array_key_exists('mediaType',$vurl)) {
if (in_array($vurl['mediaType'], $vtypes)) {
- if (!array_key_exists('width', $vurl)) {
- $vurl['width'] = 0;
+ if (! array_key_exists('height',$vurl)) {
+ $vurl['height'] = 0;
}
$mps[] = $vurl;
}
@@ -2491,17 +2618,18 @@ class Activity {
}
}
if ($mps) {
- usort($mps, [__CLASS__, 'vid_sort']);
+ usort($mps,[ '\Zotlabs\Lib\Activity', 'vid_sort' ]);
foreach ($mps as $m) {
- if (intval($m['width']) < 500 && self::media_not_in_body($m['href'], $s['body'])) {
- $s['body'] .= "\n\n" . '[video]' . $m['href'] . '[/video]';
+ if (intval($m['height']) < 500 && Activity::media_not_in_body($m['href'],$s['body'])) {
+ $s['body'] = $tag . $m['href'] . '[/video]' . "\n\n" . $s['body'];
break;
}
}
}
- elseif (is_string($act->obj['url']) && self::media_not_in_body($act->obj['url'], $s['body'])) {
- $s['body'] .= "\n\n" . '[video]' . $act->obj['url'] . '[/video]';
+ elseif (is_string($act->obj['url']) && Activity::media_not_in_body($act->obj['url'],$s['body'])) {
+ $s['body'] = $tag . $act->obj['url'] . '[/video]' . "\n\n" . $s['body'];
}
+
}
}
@@ -2525,13 +2653,13 @@ class Activity {
}
foreach ($ptr as $vurl) {
if (in_array($vurl['mediaType'], $atypes) && self::media_not_in_body($vurl['href'], $s['body'])) {
- $s['body'] .= "\n\n" . '[audio]' . $vurl['href'] . '[/audio]';
+ $s['body'] = '[audio]' . $vurl['href'] . '[/audio]' . "\n\n" . $s['body'];
break;
}
}
}
elseif (is_string($act->obj['url']) && self::media_not_in_body($act->obj['url'], $s['body'])) {
- $s['body'] .= "\n\n" . '[audio]' . $act->obj['url'] . '[/audio]';
+ $s['body'] = '[audio]' . $act->obj['url'] . '[/audio]' . "\n\n" . $s['body'];
}
}
@@ -2606,7 +2734,6 @@ class Activity {
}
}
-
if (in_array($act->obj['type'], ['Note', 'Article', 'Page'])) {
$ptr = null;
@@ -2744,12 +2871,6 @@ class Activity {
return;
}*/
- // TODO: this his handled in pubcrawl atm.
- // very unpleasant and imperfect way of determining a Mastodon DM
- /*if ($act->raw_recips && array_key_exists('to',$act->raw_recips) && is_array($act->raw_recips['to']) && count($act->raw_recips['to']) === 1 && $act->raw_recips['to'][0] === channel_url($channel) && ! $act->raw_recips['cc']) {
- $item['item_private'] = 2;
- }*/
-
if ($item['parent_mid'] && $item['parent_mid'] !== $item['mid']) {
$is_child_node = true;
}
@@ -2914,19 +3035,23 @@ class Activity {
return;
if ($channel['channel_system']) {
- if (!MessageFilter::evaluate($item, get_config('system', 'pubstream_incl'), get_config('system', 'pubstream_excl'))) {
+ $incl = get_config('system','pubstream_incl');
+ $excl = get_config('system','pubstream_excl');
+
+ if(($incl || $excl) && !MessageFilter::evaluate($item, $incl, $excl)) {
logger('post is filtered');
return;
}
}
- $abook = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
- dbesc($observer_hash),
+ $abook = q("select * from abook where ( abook_xchan = '%s' OR abook_xchan = '%s') and abook_channel = %d ",
+ dbesc($item['author_xchan']),
+ dbesc($item['owner_xchan']),
intval($channel['channel_id'])
);
if ($abook) {
- if (!post_is_importable($item, $abook[0])) {
+ if (!post_is_importable($channel['channel_id'], $item, $abook)) {
logger('post is filtered');
return;
}
@@ -2996,6 +3121,19 @@ class Activity {
$item['thr_parent'] = $parent[0]['parent_mid'];
}
$item['parent_mid'] = $parent[0]['parent_mid'];
+ //$item['item_private'] = $parent[0]['item_private'];
+
+ }
+
+ // An ugly and imperfect way to recognise a mastodon direct message
+ if (
+ $item['item_private'] === 1 &&
+ !isset($act->raw_recips['cc']) &&
+ is_array($act->raw_recips['to']) &&
+ in_array(channel_url($channel), $act->raw_recips['to']) &&
+ !in_array($act->actor['followers'], $act->raw_recips['to'])
+ ) {
+ $item['item_private'] = 2;
}
// TODO: not implemented
@@ -3006,6 +3144,12 @@ class Activity {
intval($item['uid'])
);
if ($r) {
+
+ // If we already have the item, dismiss its announce
+ if ($act->type === 'Announce') {
+ return;
+ }
+
if ($item['edited'] > $r[0]['edited']) {
$item['id'] = $r[0]['id'];
$x = item_store_update($item);
@@ -3022,12 +3166,12 @@ class Activity {
logger('topfetch', LOGGER_DEBUG);
// if the thread owner is a connnection, we will already receive any additional comments to their posts
// but if they are not we can try to fetch others in the background
- $x = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash
+ $connected = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_channel = %d and abook_xchan = '%s' LIMIT 1",
intval($channel['channel_id']),
dbesc($parent[0]['owner_xchan'])
);
- if (!$x) {
+ if (!$connected) {
// determine if the top-level post provides a replies collection
if ($parent[0]['obj']) {
$parent[0]['obj'] = json_decode($parent[0]['obj'], true);
@@ -3279,6 +3423,7 @@ class Activity {
}
+/* this is deprecated and not used anymore
static function announce_note($channel, $observer_hash, $act) {
$s = [];
@@ -3409,6 +3554,7 @@ class Activity {
}
}
+*/
static function like_note($channel, $observer_hash, $act) {
@@ -3629,7 +3775,49 @@ class Activity {
$event['nofinish'] = true;
}
}
+/*
+ $eventptr = null;
+
+ if ($act->obj['type'] === 'Invite' && array_path_exists('object/type', $act->obj) && $act->obj['object']['type'] === 'Event') {
+ $eventptr = $act->obj['object'];
+ $s['mid'] = $s['parent_mid'] = $act->obj['id'];
+ }
+
+ if ($act->obj['type'] === 'Event') {
+ if ($act->type === 'Invite') {
+ $s['mid'] = $s['parent_mid'] = $act->id;
+ }
+ $eventptr = $act->obj;
+ }
+
+ if ($eventptr) {
+
+ $s['obj'] = [];
+ $s['obj']['asld'] = $eventptr;
+ $s['obj']['type'] = ACTIVITY_OBJ_EVENT;
+ $s['obj']['id'] = $eventptr['id'];
+ $s['obj']['title'] = html2plain($eventptr['name']);
+
+ if (strpos($act->obj['startTime'], 'Z'))
+ $s['obj']['adjust'] = true;
+ else
+ $s['obj']['adjust'] = true;
+
+ $s['obj']['dtstart'] = datetime_convert('UTC', 'UTC', $eventptr['startTime']);
+ if ($act->obj['endTime'])
+ $s['obj']['dtend'] = datetime_convert('UTC', 'UTC', $eventptr['endTime']);
+ else
+ $s['obj']['nofinish'] = true;
+ $s['obj']['description'] = html2bbcode($eventptr['content']);
+ if (array_path_exists('location/content', $eventptr))
+ $s['obj']['location'] = $eventptr['location']['content'];
+
+ }
+ else {
+ $s['obj'] = $act->obj;
+ }
+*/
foreach (['name', 'summary', 'content'] as $a) {
if (($x = self::get_textfield($act, $a)) !== false) {
$content[$a] = $x;
@@ -3786,7 +3974,7 @@ class Activity {
return $ret;
}
- foreach ($tag as $t) {
+ foreach ($actor['tag'] as $t) {
if ((isset($t['type']) && $t['type'] === 'PropertyValue') &&
(isset($t['name']) && $t['name'] === 'Protocol') &&
(isset($t['value']) && in_array($t['value'], ['zot6', 'activitypub', 'diaspora']))
@@ -3797,4 +3985,32 @@ class Activity {
return $ret;
}
+
+ static function get_quote_bbcode($url) {
+
+ $ret = '';
+
+ $a = self::fetch($url);
+ if ($a) {
+ $act = new ActivityStreams($a);
+
+ if ($act->is_valid()) {
+ $content = self::get_content($act->obj);
+
+ $ret .= "[share author='" . urlencode($act->actor['name']) .
+ "' profile='" . $act->actor['id'] .
+ "' avatar='" . $act->actor['icon']['url'] .
+ "' link='" . $act->obj['id'] .
+ "' auth='" . ((is_matrix_url($act->actor['id'])) ? 'true' : 'false') .
+ "' posted='" . $act->obj['published'] .
+ "' message_id='" . $act->obj['id'] .
+ "']";
+ $ret .= self::bb_content($content, 'content');
+ $ret .= '[/share]';
+ }
+ }
+
+ return $ret;
+ }
+
}
diff --git a/Zotlabs/Lib/ActivityStreams.php b/Zotlabs/Lib/ActivityStreams.php
index 275f6eff4..1c278f2ee 100644
--- a/Zotlabs/Lib/ActivityStreams.php
+++ b/Zotlabs/Lib/ActivityStreams.php
@@ -422,15 +422,19 @@ class ActivityStreams {
static function get_accept_header_string($channel = null) {
+ $ret = '';
+
$hookdata = [];
if ($channel)
$hookdata['channel'] = $channel;
- $hookdata['data'] = 'application/x-zot-activity+json';
+ $hookdata['data'] = ['application/x-zot-activity+json'];
call_hooks('get_accept_header_string', $hookdata);
- return $hookdata['data'];
+ $ret = implode(', ', $hookdata['data']);
+
+ return $ret;
}
diff --git a/Zotlabs/Lib/Crypto.php b/Zotlabs/Lib/Crypto.php
index f1794ae64..188c6bd81 100644
--- a/Zotlabs/Lib/Crypto.php
+++ b/Zotlabs/Lib/Crypto.php
@@ -87,6 +87,10 @@ class Crypto {
return false;
}
+ if (!$alg) {
+ $alg = 'sha256';
+ }
+
try {
$verify = openssl_verify($data, $sig, $key, $alg);
} catch (Exception $e) {
diff --git a/Zotlabs/Lib/Enotify.php b/Zotlabs/Lib/Enotify.php
index 2e483cb92..1421c72ae 100644
--- a/Zotlabs/Lib/Enotify.php
+++ b/Zotlabs/Lib/Enotify.php
@@ -845,6 +845,10 @@ class Enotify {
// convert this logic into a json array just like the system notifications
$who = (($item['verb'] === ACTIVITY_SHARE) ? 'owner' : 'author');
+ $body = html2plain(bbcode($item['body'], ['drop_media']), 75, true);
+ if ($body) {
+ $body = htmlentities($body, ENT_QUOTES, 'UTF-8', false);
+ }
$x = array(
'notify_link' => $item['llink'],
@@ -858,7 +862,7 @@ class Enotify {
//'b64mid' => ((in_array($item['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) ? gen_link_id($item['thr_parent']) : gen_link_id($item['mid'])),
'thread_top' => (($item['item_thread_top']) ? true : false),
'message' => bbcode(escape_tags($itemem_text)),
- 'body' => htmlentities(html2plain(bbcode($item['body'], ['drop_media', true]), 75, true), ENT_QUOTES, 'UTF-8', false),
+ 'body' => $body,
// these are for the superblock addon
'hash' => $item[$who]['xchan_hash'],
'uid' => $item['uid'],
diff --git a/Zotlabs/Lib/LDSignatures.php b/Zotlabs/Lib/LDSignatures.php
index 1c2095f10..00042bc7a 100644
--- a/Zotlabs/Lib/LDSignatures.php
+++ b/Zotlabs/Lib/LDSignatures.php
@@ -75,22 +75,23 @@ class LDSignatures {
}
static function hash($obj) {
-
- return hash('sha256',self::normalise($obj));
+ return hash('sha256', self::normalise($obj));
}
static function normalise($data) {
+ $ret = '';
+
if(is_string($data)) {
$data = json_decode($data);
}
if(! is_object($data))
- return '';
+ return $ret;
jsonld_set_document_loader('jsonld_document_loader');
try {
- $d = jsonld_normalize($data,[ 'algorithm' => 'URDNA2015', 'format' => 'application/nquads' ]);
+ $ret = jsonld_normalize($data,[ 'algorithm' => 'URDNA2015', 'format' => 'application/nquads' ]);
}
catch (\Exception $e) {
// Don't log the exception - this can exhaust memory
@@ -98,7 +99,7 @@ class LDSignatures {
logger('normalise error: ' . print_r($data,true));
}
- return $d;
+ return $ret;
}
static function salmon_sign($data,$channel) {
diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php
index e4d8d2275..2ed18d10b 100644
--- a/Zotlabs/Lib/Libzot.php
+++ b/Zotlabs/Lib/Libzot.php
@@ -676,6 +676,10 @@ class Libzot {
logger('import_xchan: ' . $xchan_hash, LOGGER_DEBUG);
+ if (isset($arr['signing_algorithm']) && $arr['signing_algorithm']) {
+ set_xconfig($xchan_hash, 'system', 'signing_algorithm', $arr['signing_algorithm']);
+ }
+
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
dbesc($xchan_hash)
);
@@ -1003,7 +1007,7 @@ class Libzot {
$x = Crypto::unencapsulate($x, get_config('system', 'prvkey'));
- if (!is_array($x)) {
+ if ($x && !is_array($x)) {
$x = json_decode($x, true);
}
@@ -1227,6 +1231,16 @@ class Libzot {
dbesc($AS->actor['id'])
);
+ if (! $r) {
+ // Author is unknown to this site. Perform channel discovery and try again.
+ $z = discover_by_webbie($AS->actor['id']);
+ if ($z) {
+ $r = q("select hubloc_hash, hubloc_network, hubloc_url from hubloc where hubloc_id_url = '%s'",
+ dbesc($AS->actor['id'])
+ );
+ }
+ }
+
if ($r) {
$r = self::zot_record_preferred($r);
$arr['author_xchan'] = $r['hubloc_hash'];
@@ -1280,22 +1294,12 @@ class Libzot {
if ($AS->data['hubloc']) {
$arr['item_verified'] = true;
+ }
- if (!array_key_exists('comment_policy', $arr)) {
- // set comment policy depending on source hub. Unknown or osada is ActivityPub.
- // Anything else we'll say is zot - which could have a range of project names
- $s = q("select site_project from site where site_url = '%s' limit 1",
- dbesc($r[0]['hubloc_url'])
- );
-
- if ((!$s) || (in_array($s[0]['site_project'], ['', 'osada']))) {
- $arr['comment_policy'] = 'authenticated';
- }
- else {
- $arr['comment_policy'] = 'contacts';
- }
- }
+ if (!array_key_exists('comment_policy', $arr)) {
+ $arr['comment_policy'] = 'authenticated';
}
+
if ($AS->meta['signed_data']) {
IConfig::Set($arr, 'activitypub', 'signed_data', $AS->meta['signed_data'], false);
}
@@ -1568,7 +1572,11 @@ class Libzot {
$local_public = false;
continue;
}
- if (!MessageFilter::evaluate($arr, get_config('system', 'pubstream_incl'), get_config('system', 'pubstream_excl'))) {
+
+ $incl = get_config('system','pubstream_incl');
+ $excl = get_config('system','pubstream_excl');
+
+ if(($incl || $excl) && !MessageFilter::evaluate($arr, $incl, $excl)) {
$local_public = false;
continue;
}
@@ -1743,11 +1751,13 @@ class Libzot {
}
}
- $ab = q("select * from abook where abook_channel = %d and abook_xchan = '%s'",
+ // This is used to fetch allow/deny rules if either the sender
+ // or owner is a connection. post_is_importable() evaluates all of them
+ $abook = q("select * from abook where abook_channel = %d and ( abook_xchan = '%s' OR abook_xchan = '%s' )",
intval($channel['channel_id']),
- dbesc($arr['owner_xchan'])
+ dbesc($arr['owner_xchan']),
+ dbesc($arr['author_xchan'])
);
- $abook = (($ab) ? $ab[0] : null);
if (intval($arr['item_deleted'])) {
@@ -1798,17 +1808,18 @@ class Libzot {
elseif ($arr['edited'] > $r[0]['edited']) {
$arr['id'] = $r[0]['id'];
$arr['uid'] = $channel['channel_id'];
- if (($arr['mid'] == $arr['parent_mid']) && (!post_is_importable($arr, $abook))) {
- $DR->update('update ignored');
- $result[] = $DR->get();
- }
- else {
- $item_result = self::update_imported_item($sender, $arr, $r[0], $channel['channel_id'], $tag_delivery);
- $DR->update('updated');
- $result[] = $DR->get();
- if (!$relay)
- add_source_route($item_id, $sender);
- }
+
+ if (post_is_importable($channel['channel_id'], $arr, $abook)) {
+ $item_result = self::update_imported_item($sender, $arr, $r[0], $channel['channel_id'], $tag_delivery);
+ $DR->update('updated');
+ $result[] = $DR->get();
+ if (!$relay) {
+ add_source_route($item_id, $sender);
+ }
+ } else {
+ $DR->update('update ignored');
+ $result[] = $DR->get();
+ }
}
else {
$DR->update('update ignored');
@@ -1838,20 +1849,29 @@ class Libzot {
$item_id = 0;
- if (($arr['mid'] == $arr['parent_mid']) && (!post_is_importable($arr, $abook))) {
- $DR->update('post ignored');
- $result[] = $DR->get();
+ $maxlen = get_max_import_size();
+
+ if ($maxlen && mb_strlen($arr['body']) > $maxlen) {
+ $arr['body'] = mb_substr($arr['body'], 0, $maxlen, 'UTF-8');
+ logger('message length exceeds max_import_size: truncated');
}
- else {
+
+ if ($maxlen && mb_strlen($arr['summary']) > $maxlen) {
+ $arr['summary'] = mb_substr($arr['summary'], 0, $maxlen, 'UTF-8');
+ logger('message summary length exceeds max_import_size: truncated');
+ }
+
+ if (post_is_importable($arr['uid'], $arr, $abook)) {
$item_result = item_store($arr);
if ($item_result['success']) {
$item_id = $item_result['item_id'];
- $parr = [
+ $parr = [
'item_id' => $item_id,
- 'item' => $arr,
- 'sender' => $sender,
+ 'item' => $arr,
+ 'sender' => $sender,
'channel' => $channel
];
+
/**
* @hooks activity_received
* Called when an activity (post, comment, like, etc.) has been received from a zot source.
@@ -1861,13 +1881,19 @@ class Libzot {
* * \e array \b channel
*/
call_hooks('activity_received', $parr);
+
// don't add a source route if it's a relay or later recipients will get a route mismatch
- if (!$relay)
+ if (!$relay) {
add_source_route($item_id, $sender);
+ }
}
$DR->update(($item_id) ? 'posted' : 'storage failed: ' . $item_result['message']);
$result[] = $DR->get();
+ } else {
+ $DR->update('post ignored');
+ $result[] = $DR->get();
}
+
}
// preserve conversations with which you are involved from expiration
@@ -2845,6 +2871,7 @@ class Libzot {
];
$ret['public_key'] = $e['xchan_pubkey'];
+ $ret['signing_algorithm'] = 'rsa-sha256';
$ret['username'] = $e['channel_address'];
$ret['name'] = $e['xchan_name'];
$ret['name_updated'] = $e['xchan_name_date'];
diff --git a/Zotlabs/Lib/MessageFilter.php b/Zotlabs/Lib/MessageFilter.php
index 21e6ca26a..95721e7c7 100644
--- a/Zotlabs/Lib/MessageFilter.php
+++ b/Zotlabs/Lib/MessageFilter.php
@@ -2,85 +2,104 @@
namespace Zotlabs\Lib;
-
+require_once('include/html2plain.php');
class MessageFilter {
+ public static function evaluate($item, $incl, $excl) {
- static public function evaluate($item,$incl,$excl) {
-
- require_once('include/html2plain.php');
-
- $text = prepare_text($item['body'],$item['mimetype']);
+ $text = prepare_text($item['body'],((isset($item['mimetype'])) ? $item['mimetype'] : 'text/x-multicode'));
$text = html2plain(($item['title']) ? $item['title'] . ' ' . $text : $text);
-
$lang = null;
- if((strpos($incl,'lang=') !== false) || (strpos($excl,'lang=') !== false) || (strpos($incl,'lang!=') !== false) || (strpos($excl,'lang!=') !== false)) {
+ if ((strpos($incl, 'lang=') !== false) || (strpos($excl, 'lang=') !== false) || (strpos($incl, 'lang!=') !== false) || (strpos($excl, 'lang!=') !== false)) {
$lang = detect_language($text);
}
- $tags = ((is_array($item['term']) && count($item['term'])) ? $item['term'] : false);
+ $tags = ((isset($item['term']) && is_array($item['term']) && count($item['term'])) ? $item['term'] : false);
// exclude always has priority
- $exclude = (($excl) ? explode("\n",$excl) : null);
+ $exclude = (($excl) ? explode("\n", $excl) : null);
- if($exclude) {
- foreach($exclude as $word) {
+ if ($exclude) {
+ foreach ($exclude as $word) {
$word = trim($word);
- if(! $word)
+ if (! $word) {
continue;
- if(substr($word,0,1) === '#' && $tags) {
- foreach($tags as $t)
- if((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*')))
- return false;
}
- elseif(substr($word,0,1) === '$' && $tags) {
- foreach($tags as $t)
- if(($t['ttype'] == TERM_CATEGORY) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*')))
+ if (substr($word, 0, 1) === '#' && $tags) {
+ foreach ($tags as $t) {
+ if ((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word, 1)) || (substr($word, 1) === '*'))) {
return false;
- }
- elseif((strpos($word,'/') === 0) && preg_match($word,$text))
+ }
+ }
+ } elseif (substr($word, 0, 1) === '$' && $tags) {
+ foreach ($tags as $t) {
+ if (($t['ttype'] == TERM_CATEGORY) && (($t['term'] === substr($word, 1)) || (substr($word, 1) === '*'))) {
+ return false;
+ }
+ }
+ } elseif (substr($word, 0, 2) === '?+') {
+ if (self::test_condition(substr($word, 2), $item['obj'])) {
+ return false;
+ }
+ } elseif (substr($word, 0, 1) === '?') {
+ if (self::test_condition(substr($word, 1), $item)) {
+ return false;
+ }
+ } elseif ((strpos($word, '/') === 0) && preg_match($word, $text)) {
return false;
- elseif((strpos($word,'lang=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,5))) == 0))
+ } elseif ((strpos($word, 'lang=') === 0) && ($lang) && (strcasecmp($lang, trim(substr($word, 5))) == 0)) {
return false;
- elseif((strpos($word,'lang!=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,6))) != 0))
+ } elseif ((strpos($word, 'lang!=') === 0) && ($lang) && (strcasecmp($lang, trim(substr($word, 6))) != 0)) {
return false;
- elseif(stristr($text,$word) !== false)
+ } elseif (stristr($text, $word) !== false) {
return false;
+ }
}
}
- $include = (($incl) ? explode("\n",$incl) : null);
+ $include = (($incl) ? explode("\n", $incl) : null);
- if($include) {
- foreach($include as $word) {
+ if ($include) {
+ foreach ($include as $word) {
$word = trim($word);
- if(! $word)
+ if (! $word) {
continue;
- if(substr($word,0,1) === '#' && $tags) {
- foreach($tags as $t)
- if((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*')))
- return true;
}
- elseif(substr($word,0,1) === '$' && $tags) {
- foreach($tags as $t)
- if(($t['ttype'] == TERM_CATEGORY) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*')))
+ if (substr($word, 0, 1) === '#' && $tags) {
+ foreach ($tags as $t) {
+ if ((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word, 1)) || (substr($word, 1) === '*'))) {
return true;
- }
- elseif((strpos($word,'/') === 0) && preg_match($word,$text))
+ }
+ }
+ } elseif (substr($word, 0, 1) === '$' && $tags) {
+ foreach ($tags as $t) {
+ if (($t['ttype'] == TERM_CATEGORY) && (($t['term'] === substr($word, 1)) || (substr($word, 1) === '*'))) {
+ return true;
+ }
+ }
+ } elseif (substr($word, 0, 2) === '?+') {
+ if (self::test_condition(substr($word, 2), $item['obj'])) {
+ return true;
+ }
+ } elseif (substr($word, 0, 1) === '?') {
+ if (self::test_condition(substr($word, 1), $item)) {
+ return true;
+ }
+ } elseif ((strpos($word, '/') === 0) && preg_match($word, $text)) {
return true;
- elseif((strpos($word,'lang=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,5))) == 0))
+ } elseif ((strpos($word, 'lang=') === 0) && ($lang) && (strcasecmp($lang, trim(substr($word, 5))) == 0)) {
return true;
- elseif((strpos($word,'lang!=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,6))) != 0))
+ } elseif ((strpos($word, 'lang!=') === 0) && ($lang) && (strcasecmp($lang, trim(substr($word, 6))) != 0)) {
return true;
- elseif(stristr($text,$word) !== false)
+ } elseif (stristr($text, $word) !== false) {
return true;
+ }
}
- }
- else {
+ } else {
return true;
}
@@ -88,4 +107,113 @@ class MessageFilter {
}
+ /**
+ * @brief Test for Conditional Execution conditions. Shamelessly ripped off from Code/Render/Comanche
+ *
+ * This is extensible. The first version of variable testing supports tests of the forms:
+ *
+ * - ?foo ~= baz which will check if item.foo contains the string 'baz';
+ * - ?foo == baz which will check if item.foo is the string 'baz';
+ * - ?foo != baz which will check if item.foo is not the string 'baz';
+ * - ?foo >= 3 which will check if item.foo is greater than or equal to 3;
+ * - ?foo > 3 which will check if item.foo is greater than 3;
+ * - ?foo <= 3 which will check if item.foo is less than or equal to 3;
+ * - ?foo < 3 which will check if item.foo is less than 3;
+ *
+ * - ?foo {} baz which will check if 'baz' is an array element in item.foo
+ * - ?foo {*} baz which will check if 'baz' is an array key in item.foo
+ * - ?foo which will check for a return of a true condition for item.foo;
+ *
+ * The values 0, '', an empty array, and an unset value will all evaluate to false.
+ *
+ * @param string $s
+ * @param array $item
+ * @return bool
+ */
+
+ public static function test_condition($s,$item) {
+
+ if (preg_match('/(.*?)\s\~\=\s(.*?)$/', $s, $matches)) {
+ $x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
+ if (stripos($x, trim($matches[2])) !== false) {
+ return true;
+ }
+ return false;
+ }
+
+ if (preg_match('/(.*?)\s\=\=\s(.*?)$/', $s, $matches)) {
+ $x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
+ if ($x == trim($matches[2])) {
+ return true;
+ }
+ return false;
+ }
+
+ if (preg_match('/(.*?)\s\!\=\s(.*?)$/', $s, $matches)) {
+ $x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
+ if ($x != trim($matches[2])) {
+ return true;
+ }
+ return false;
+ }
+
+ if (preg_match('/(.*?)\s\>\=\s(.*?)$/', $s, $matches)) {
+ $x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
+ if ($x >= trim($matches[2])) {
+ return true;
+ }
+ return false;
+ }
+
+ if (preg_match('/(.*?)\s\<\=\s(.*?)$/', $s, $matches)) {
+ $x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
+ if ($x <= trim($matches[2])) {
+ return true;
+ }
+ return false;
+ }
+
+ if (preg_match('/(.*?)\s\>\s(.*?)$/', $s, $matches)) {
+ $x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
+ if ($x > trim($matches[2])) {
+ return true;
+ }
+ return false;
+ }
+
+ if (preg_match('/(.*?)\s\>\s(.*?)$/', $s, $matches)) {
+ $x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
+ if ($x < trim($matches[2])) {
+ return true;
+ }
+ return false;
+ }
+
+ if (preg_match('/[\$](.*?)\s\{\}\s(.*?)$/', $s, $matches)) {
+ $x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
+ if (is_array($x) && in_array(trim($matches[2]), $x)) {
+ return true;
+ }
+ return false;
+ }
+
+ if (preg_match('/(.*?)\s\{\*\}\s(.*?)$/', $s, $matches)) {
+ $x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
+ if (is_array($x) && array_key_exists(trim($matches[2]), $x)) {
+ return true;
+ }
+ return false;
+ }
+
+ if (preg_match('/(.*?)$/', $s, $matches)) {
+ $x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
+ if ($x) {
+ return true;
+ }
+ return false;
+ }
+
+ return false;
+ }
+
}
diff --git a/Zotlabs/Module/Directory.php b/Zotlabs/Module/Directory.php
index b39887c9e..da37c582f 100644
--- a/Zotlabs/Module/Directory.php
+++ b/Zotlabs/Module/Directory.php
@@ -254,21 +254,21 @@ class Directory extends Controller {
$connect_link = '';
$location = '';
- if(strlen($rr['locale']))
+ if(isset($rr['locale']))
$location .= $rr['locale'];
- if(strlen($rr['region'])) {
- if(strlen($rr['locale']))
+ if(isset($rr['region'])) {
+ if($location)
$location .= ', ';
$location .= $rr['region'];
}
- if(strlen($rr['country'])) {
- if(strlen($location))
+ if(isset($rr['country'])) {
+ if($location)
$location .= ', ';
$location .= $rr['country'];
}
$age = '';
- if(strlen($rr['birthday'])) {
+ if(isset($rr['birthday'])) {
if(($years = age($rr['birthday'],'UTC','')) > 0)
$age = $years;
}
diff --git a/Zotlabs/Module/Hq.php b/Zotlabs/Module/Hq.php
index 29b0df739..5001bbe62 100644
--- a/Zotlabs/Module/Hq.php
+++ b/Zotlabs/Module/Hq.php
@@ -27,6 +27,8 @@ class Hq extends \Zotlabs\Web\Controller {
return;
}
+ $item_hash = '';
+
if(argc() > 1 && argv(1) !== 'load') {
$item_hash = unpack_link_id(argv(1));
}
@@ -97,7 +99,7 @@ class Hq extends \Zotlabs\Web\Controller {
'allow_location' => ((intval(get_pconfig($channel['channel_id'],'system','use_browser_location'))) ? '1' : ''),
'default_location' => $channel['channel_location'],
'nickname' => $channel['channel_address'],
- 'lockstate' => (($group || $cid || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
+ 'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
'acl' => populate_acl($channel_acl,true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
'permissions' => $channel_acl,
'bang' => '',
@@ -112,6 +114,7 @@ class Hq extends \Zotlabs\Web\Controller {
'reset' => t('Reset form')
];
+ $a = '';
$o = status_editor($a, $x, true);
}
diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php
index 41a4e120d..574a90c1a 100644
--- a/Zotlabs/Module/Item.php
+++ b/Zotlabs/Module/Item.php
@@ -695,6 +695,7 @@ class Item extends Controller {
$expires = $orig_post['expires'];
$comments_closed = $orig_post['comments_closed'];
$mid = $orig_post['mid'];
+ $thr_parent = $orig_post['thr_parent'];
$parent_mid = $orig_post['parent_mid'];
$plink = $orig_post['plink'];
}
@@ -1092,7 +1093,7 @@ class Item extends Controller {
$datarray['created'] = $created;
$datarray['edited'] = (($orig_post) ? datetime_convert() : $created);
$datarray['expires'] = $expires;
- $datarray['comments_closed'] = $comments_closed;
+ $datarray['comments_closed'] = (($nocomment) ? $created : $comments_closed);
$datarray['commented'] = (($orig_post) ? datetime_convert() : $created);
$datarray['received'] = (($orig_post) ? datetime_convert() : $created);
$datarray['changed'] = (($orig_post) ? datetime_convert() : $created);
diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php
index 016a0a309..f4f6cc8d1 100644
--- a/Zotlabs/Module/Network.php
+++ b/Zotlabs/Module/Network.php
@@ -272,15 +272,17 @@ class Network extends \Zotlabs\Web\Controller {
$likes_sql = " AND verb NOT IN ('" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') ";
// This is for nouveau view public forum cid queries (if a forum notification is clicked)
- $p = q("SELECT oid AS parent FROM term WHERE uid = %d AND ttype = %d AND term = '%s'",
- intval(local_channel()),
- intval(TERM_FORUM),
- dbesc($cid_r[0]['xchan_name'])
- );
-
- $p_str = ids_to_querystr($p, 'parent');
- if($p_str)
- $p_sql = " OR item.parent IN ( $p_str ) ";
+ //$p = q("SELECT oid AS parent FROM term WHERE uid = %d AND ttype = %d AND term = '%s'",
+ //intval(local_channel()),
+ //intval(TERM_FORUM),
+ //dbesc($cid_r[0]['xchan_name'])
+ //);
+
+ //$p_str = ids_to_querystr($p, 'parent');
+
+ $p_sql = '';
+ //if($p_str)
+ //$p_sql = " OR item.parent IN ( $p_str ) ";
$sql_extra = " AND ( owner_xchan = '" . protect_sprintf(dbesc($cid_r[0]['abook_xchan'])) . "' OR owner_xchan = '" . protect_sprintf(dbesc($cid_r[0]['abook_xchan'])) . "' $p_sql ) AND item_unseen = 1 $likes_sql ";
}
diff --git a/Zotlabs/Module/Pdledit_gui.php b/Zotlabs/Module/Pdledit_gui.php
new file mode 100644
index 000000000..b550b92d3
--- /dev/null
+++ b/Zotlabs/Module/Pdledit_gui.php
@@ -0,0 +1,553 @@
+<?php
+
+namespace Zotlabs\Module;
+
+use App;
+use Zotlabs\Web\Controller;
+use Zotlabs\Render\Comanche;
+use Zotlabs\Lib\Libsync;
+
+class Pdledit_gui extends Controller {
+
+ function post() {
+
+ if (!local_channel()) {
+ return;
+ }
+
+ if (!$_REQUEST['module']) {
+ return;
+ }
+
+ $module = $_REQUEST['module'];
+
+ $ret = [
+ 'success' => false,
+ 'module' => $module
+ ];
+
+ if ($_REQUEST['reset']) {
+ del_pconfig(local_channel(), 'system', 'mod_' . $module . '.pdl');
+ Libsync::build_sync_packet();
+ $ret['success'] = true;
+ json_return_and_die($ret);
+ }
+
+ if ($_REQUEST['save']) {
+ if (!$_REQUEST['data']) {
+ return $ret;
+ }
+
+ $data = json_decode($_REQUEST['data'],true);
+ $stored_pdl_result = self::get_pdl($module);
+ $pdl = $stored_pdl_result['pdl'];
+
+ foreach ($data as $region => $entries) {
+ $region_pdl = '';
+ foreach ($entries as $entry) {
+ $region_pdl .= base64_decode($entry) . "\r\n";
+ }
+ $pdl = preg_replace('/\[region=' . $region . '\](.*?)\[\/region\]/ism', '[region=' . $region . ']' . "\r\n" . $region_pdl . "\r\n" . '[/region]', $pdl);
+ }
+
+ set_pconfig(local_channel(), 'system', 'mod_' . $module . '.pdl', escape_tags($pdl));
+ Libsync::build_sync_packet();
+
+ $ret['success'] = true;
+ json_return_and_die($ret);
+ }
+
+ if ($_REQUEST['save_src']) {
+ set_pconfig(local_channel(), 'system', 'mod_' . $module . '.pdl', escape_tags($_REQUEST['src']));
+ Libsync::build_sync_packet();
+
+ $ret['success'] = true;
+ json_return_and_die($ret);
+ }
+
+ if ($_REQUEST['save_template']) {
+ if (!$_REQUEST['data']) {
+ return $ret;
+ }
+
+ $template = $_REQUEST['data'][0]['value'];
+ $pdl_result = self::get_pdl($module);
+ $stored_template = self::get_template($pdl_result['pdl']);
+
+ if ($template === $stored_template) {
+ $ret['success'] = true;
+ return $ret;
+ }
+
+ $cnt = preg_match("/\[template\](.*?)\[\/template\]/ism", $pdl_result['pdl'], $matches);
+ if ($cnt) {
+ $pdl = str_replace('[template]' . $stored_template . '[/template]', '[template]' . $template . '[/template]', $pdl_result['pdl']);
+ }
+ else {
+ $pdl = '[template]' . $template . '[/template]' . "\r\n";
+ $pdl .= $pdl_result['pdl'];
+ }
+
+ set_pconfig(local_channel(), 'system', 'mod_' . $module . '.pdl', escape_tags($pdl));
+ Libsync::build_sync_packet();
+
+ $ret['success'] = true;
+ json_return_and_die($ret);
+ }
+
+ }
+
+ function get() {
+
+ if(! local_channel()) {
+ return EMPTY_STR;
+ }
+
+ $module = argv(1);
+
+ if (!$module) {
+ goaway(z_root() . '/pdledit_gui/hq');
+ }
+
+ $pdl_result = self::get_pdl($module);
+
+ $pdl = $pdl_result['pdl'];
+ $modified = $pdl_result['modified'];
+
+ if(!$pdl) {
+ return t('Layout not found');
+ }
+
+ $template = self::get_template($pdl);
+
+ $template_info = self::get_template_info($template);
+
+ if(empty($template_info['contentregion'])) {
+ return t('This template does not support pdledi_gui (no content regions defined)');
+ }
+
+ App::$page['template'] = $template;
+
+ $regions = self::get_regions($pdl);
+
+ foreach ($regions as $k => $v) {
+ $region_str = '';
+ if (is_array($v)) {
+ ksort($v);
+ foreach ($v as $entry) {
+ // Get the info from the file and replace entry if we get anything useful
+ $widget_info = get_widget_info($entry['name']);
+ $entry['name'] = (($widget_info['name']) ? $widget_info['name'] : $entry['name']);
+ $entry['desc'] = (($widget_info['description']) ? $widget_info['description'] : $entry['desc']);
+
+ $region_str .= replace_macros(get_markup_template('pdledit_gui_item.tpl'), [
+ '$entry' => $entry
+ ]);
+ }
+ }
+ App::$layout['region_' . $k] = $region_str;
+ }
+
+ $templates = self::get_templates();
+ $templates_html = replace_macros(get_markup_template('pdledit_gui_templates.tpl'), [
+ '$templates' => $templates,
+ '$active' => $template
+ ]);
+
+ $items_html = '';
+
+ //$items_html .= replace_macros(get_markup_template('pdledit_gui_item.tpl'), [
+ //'$entry' => [
+ //'type' => 'content',
+ //'name' => t('Main page content'),
+ //'src' => base64_encode('$content')
+ //],
+ //'$disable_controls' => true
+ //]);
+
+ foreach (self::get_widgets($module) as $entry) {
+ $items_html .= replace_macros(get_markup_template('pdledit_gui_item.tpl'), [
+ '$entry' => $entry,
+ '$disable_controls' => true
+ ]);
+ }
+
+ foreach (self::get_menus() as $entry) {
+ $items_html .= replace_macros(get_markup_template('pdledit_gui_item.tpl'), [
+ '$entry' => $entry,
+ '$disable_controls' => true
+ ]);
+ }
+
+ foreach (self::get_blocks() as $entry) {
+ $items_html .= replace_macros(get_markup_template('pdledit_gui_item.tpl'), [
+ '$entry' => $entry,
+ '$disable_controls' => true
+ ]);
+ }
+
+ App::$layout['region_content'] .= replace_macros(get_markup_template('pdledit_gui.tpl'), [
+ '$content_regions' => $template_info['contentregion'],
+ '$page_src' => base64_encode($pdl),
+ '$templates' => base64_encode($templates_html),
+ '$modules' => base64_encode(self::get_modules()),
+ '$items' => base64_encode($items_html),
+ '$module_modified' => $modified,
+ '$module' => $module
+ ]);
+
+ }
+
+ function get_templates() {
+ $ret = [];
+
+ $files = glob('view/php/*.php');
+ if($files) {
+ foreach($files as $f) {
+ $name = basename($f, '.php');
+ $x = get_template_info($name);
+ if(!empty($x['contentregion'])) {
+ $ret[] = [
+ 'name' => $name,
+ 'desc' => $x['description']
+ ];
+ }
+ }
+ }
+
+ return $ret;
+ }
+
+ function get_modules() {
+ $ret = '';
+
+ $files = glob('Zotlabs/Module/*.php');
+ if($files) {
+ foreach($files as $f) {
+ $name = lcfirst(basename($f,'.php'));
+
+ if ($name === 'admin' && !is_site_admin()) {
+ continue;
+ }
+
+ $x = theme_include('mod_' . $name . '.pdl');
+ if($x) {
+ $ret .= '<div class="mb-2"><a href="pdledit_gui/' . $name . '">' . $name . '</a></div>';
+ }
+ }
+ }
+
+ return $ret;
+ }
+
+ function get_widgets($module) {
+ $ret = [];
+
+ $checkpaths = [
+ 'Zotlabs/Widget/*.php'
+ ];
+
+ foreach ($checkpaths as $path) {
+ $files = glob($path);
+ if($files) {
+ foreach($files as $f) {
+ $name = lcfirst(basename($f, '.php'));
+
+ $widget_info = get_widget_info($name);
+ if ($widget_info['requires'] && strpos($widget_info['requires'], 'admin') !== false && !is_site_admin()) {
+ continue;
+ }
+
+ if ($widget_info['requires'] && strpos($widget_info['requires'], $module) === false) {
+ continue;
+ }
+
+ $ret[] = [
+ 'type' => 'widget',
+ 'name' => $widget_info['name'] ?? $name,
+ 'desc' => $widget_info['description'] ?? '',
+ 'src' => base64_encode('[widget=' . $name . '][/widget]')
+ ];
+ }
+ }
+ }
+
+ return $ret;
+ }
+
+ function get_menus() {
+ $ret = [];
+
+ $r = q("select * from menu where menu_channel_id = %d and menu_flags = 0",
+ intval(local_channel())
+ );
+
+ foreach ($r as $rr) {
+ $name = $rr['menu_name'];
+ $desc = $rr['menu_desc'];
+ $ret[] = [
+ 'type' => 'menu',
+ 'name' => $name,
+ 'desc' => $desc,
+ 'src' => base64_encode('[menu]' . $name . '[/menu]')
+ ];
+ }
+
+ return $ret;
+ }
+
+ function get_blocks() {
+ $ret = [];
+
+ $r = q("select v, title, summary from item join iconfig on iconfig.iid = item.id and item.uid = %d
+ and iconfig.cat = 'system' and iconfig.k = 'BUILDBLOCK'",
+ intval(local_channel())
+ );
+
+ foreach ($r as $rr) {
+ $name = $rr['v'];
+ $desc = (($rr['title']) ? $rr['title'] : $rr['summary']);
+ $ret[] = [
+ 'type' => 'block',
+ 'name' => $name,
+ 'desc' => $desc,
+ 'src' => base64_encode('[block]' . $name . '[/block]')
+ ];
+ }
+
+ return $ret;
+ }
+
+ function get_template($pdl) {
+ $ret = 'default';
+
+ $cnt = preg_match("/\[template\](.*?)\[\/template\]/ism", $pdl, $matches);
+ if($cnt && isset($matches[1])) {
+ $ret = trim($matches[1]);
+ }
+
+ return $ret;
+ }
+
+ function get_regions($pdl) {
+ $ret = [];
+ $supported_regions = ['aside', 'content', 'right_aside'];
+
+ $cnt = preg_match_all("/\[region=(.*?)\](.*?)\[\/region\]/ism", $pdl, $matches, PREG_SET_ORDER);
+ if($cnt) {
+ foreach($matches as $mtch) {
+ if (!in_array($mtch[1], $supported_regions)) {
+ continue;
+ }
+ $ret[$mtch[1]] = self::parse_region($mtch[2]);
+ }
+ }
+
+ return $ret;
+ }
+
+ function parse_region($pdl) {
+ $ret = [];
+
+ $cnt = preg_match_all('/\$content\b/ism', $pdl, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE);
+ if($cnt) {
+ foreach($matches as $mtch) {
+ $offset = intval($mtch[0][1]);
+ $name = trim($mtch[0][0]);
+ //$src = base64url_encode(preg_replace(['/\s*\[/', '/\]\s*/'], ['[', ']'], $mtch[0][0]));
+ $src = base64_encode($mtch[0][0]);
+ $ret[$offset] = [
+ 'type' => 'content',
+ 'name' => t('Main page content'),
+ 'desc' => t('The main page content can not be edited!'),
+ 'src' => $src
+ ];
+ }
+ }
+
+ $cnt = preg_match_all("/\[menu\](.*?)\[\/menu\]/ism", $pdl, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE);
+ if($cnt) {
+ foreach($matches as $mtch) {
+ $offset = intval($mtch[1][1]);
+ $name = trim($mtch[1][0]);
+ //$src = base64url_encode(preg_replace(['/\s*\[/', '/\]\s*/'], ['[', ']'], $mtch[0][0]));
+ $src = base64_encode($mtch[0][0]);
+
+ $ret[$offset] = [
+ 'type' => 'menu',
+ 'name' => $name,
+ 'desc' => '',
+ 'src' => $src
+ ];
+ }
+ }
+
+ // menu class e.g. [menu=horizontal]my_menu[/menu] or [menu=tabbed]my_menu[/menu]
+ // allows different menu renderings to be applied
+
+ //$cnt = preg_match_all("/\[menu=(.*?)\](.*?)\[\/menu\]/ism", $s, $matches, PREG_SET_ORDER);
+ //if($cnt) {
+ //foreach($matches as $mtch) {
+ //$s = str_replace($mtch[0],$this->menu(trim($mtch[2]),$mtch[1]),$s);
+ //}
+ //}
+
+
+ $cnt = preg_match_all("/\[block\](.*?)\[\/block\]/ism", $pdl, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE);
+ if($cnt) {
+ foreach($matches as $mtch) {
+ $offset = intval($mtch[1][1]);
+ $name = trim($mtch[1][0]);
+ //$src = base64url_encode(preg_replace(['/\s*\[/', '/\]\s*/'], ['[', ']'], $mtch[0][0]));
+ $src = base64_encode($mtch[0][0]);
+ $ret[$offset] = [
+ 'type' => 'block',
+ 'name' => $name,
+ 'desc' => '',
+ 'src' => $src
+ ];
+ }
+ }
+
+ //$cnt = preg_match_all("/\[block=(.*?)\](.*?)\[\/block\]/ism", $s, $matches, PREG_SET_ORDER);
+ //if($cnt) {
+ //foreach($matches as $mtch) {
+ //$s = str_replace($mtch[0],$this->block(trim($mtch[2]),trim($mtch[1])),$s);
+ //}
+ //}
+
+ //$cnt = preg_match_all("/\[js\](.*?)\[\/js\]/ism", $s, $matches, PREG_SET_ORDER);
+ //if($cnt) {
+ //foreach($matches as $mtch) {
+ //$s = str_replace($mtch[0],$this->js(trim($mtch[1])),$s);
+ //}
+ //}
+
+ //$cnt = preg_match_all("/\[css\](.*?)\[\/css\]/ism", $s, $matches, PREG_SET_ORDER);
+ //if($cnt) {
+ //foreach($matches as $mtch) {
+ //$s = str_replace($mtch[0],$this->css(trim($mtch[1])),$s);
+ //}
+ //}
+
+ // need to modify this to accept parameters
+
+ $cnt = preg_match_all("/\[widget=(.*?)\](.*?)\[\/widget\]/ism", $pdl, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE);
+
+ if($cnt) {
+ foreach($matches as $mtch) {
+ $offset = intval($mtch[1][1]);
+ $name = trim($mtch[1][0]);
+ //$src = base64url_encode(preg_replace(['/\s*\[/', '/\]\s*/'], ['[', ']'], $mtch[0][0]));
+ $src = base64_encode($mtch[0][0]);
+ $ret[$offset] = [
+ 'type' => 'widget',
+ 'name' => $name,
+ 'desc' => '',
+ 'src' => $src
+ ];
+ }
+ }
+
+ return $ret;
+
+ }
+
+
+ /**
+ * @brief Parse template comment in search of template info.
+ *
+ * like
+ * \code
+ * * Name: MyWidget
+ * * Description: A widget
+ * * Version: 1.2.3
+ * * Author: John <profile url>
+ * * Author: Jane <email>
+ * * ContentRegionID: some_id
+ * * ContentRegionID: some_other_id
+ * *
+ *\endcode
+ * @param string $template the name of the template
+ * @return array with the information
+ */
+ function get_template_info($template){
+ $m = [];
+ $info = [
+ 'name' => $template,
+ 'description' => '',
+ 'author' => [],
+ 'maintainer' => [],
+ 'version' => '',
+ 'contentregion' => []
+ ];
+
+ $checkpaths = [
+ 'view/php/' . $template . '.php',
+ ];
+
+ $template_found = false;
+
+ foreach ($checkpaths as $path) {
+ if (is_file($path)) {
+ $template_found = true;
+ $f = file_get_contents($path);
+ break;
+ }
+ }
+
+ if(!($template_found && $f))
+ return $info;
+
+ $f = escape_tags($f);
+ $r = preg_match('|/\*.*\*/|msU', $f, $m);
+
+ if ($r) {
+ $ll = explode("\n", $m[0]);
+ foreach($ll as $l) {
+ $l = trim($l, "\t\n\r */");
+ if ($l != ''){
+ list($k, $v) = array_map('trim', explode(':', $l, 2));
+ $k = strtolower($k);
+ if (in_array($k, ['author', 'maintainer'])){
+ $r = preg_match('|([^<]+)<([^>]+)>|', $v, $m);
+ if ($r) {
+ $info[$k][] = array('name' => $m[1], 'link' => $m[2]);
+ } else {
+ $info[$k][] = array('name' => $v);
+ }
+ }
+ elseif (in_array($k, ['contentregion'])){
+ $info[$k][] = array_map('trim', explode(',', $v));
+ }
+ else {
+ $info[$k] = $v;
+ }
+ }
+ }
+ }
+
+ return $info;
+ }
+
+ function get_pdl($module) {
+ $ret = [
+ 'pdl' => null,
+ 'modified' => true
+ ];
+
+ $pdl_path = 'mod_' . $module . '.pdl';
+
+ $ret['pdl'] = get_pconfig(local_channel(), 'system', $pdl_path);
+
+ if(!$ret['pdl']) {
+ $pdl_path = theme_include($pdl_path);
+ if ($pdl_path) {
+ $ret['pdl'] = file_get_contents($pdl_path);
+ $ret['modified'] = false;
+ }
+ }
+
+ return $ret;
+ }
+}
diff --git a/Zotlabs/Module/Settings/Calendar.php b/Zotlabs/Module/Settings/Calendar.php
index ab85eb450..65240c635 100644
--- a/Zotlabs/Module/Settings/Calendar.php
+++ b/Zotlabs/Module/Settings/Calendar.php
@@ -11,14 +11,14 @@ class Calendar {
$module = substr(strrchr(strtolower(static::class), '\\'), 1);
check_form_security_token_redirectOnErr('/settings/' . $module, 'settings_' . $module);
-
+
$features = get_module_features($module);
process_module_features_post(local_channel(), $features, $_POST);
-
+
Libsync::build_sync_packet();
- if($_POST['rpath'])
+ if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
goaway($_POST['rpath']);
return;
@@ -34,14 +34,14 @@ class Calendar {
$tpl = get_markup_template("settings_module.tpl");
$o .= replace_macros($tpl, array(
- '$rpath' => $rpath,
+ '$rpath' => escape_url($rpath),
'$action_url' => 'settings/' . $module,
'$form_security_token' => get_form_security_token('settings_' . $module),
'$title' => t('Calendar Settings'),
'$features' => process_module_features_get(local_channel(), $features),
'$submit' => t('Submit')
));
-
+
return $o;
}
diff --git a/Zotlabs/Module/Settings/Channel.php b/Zotlabs/Module/Settings/Channel.php
index a0da020b7..840efc162 100644
--- a/Zotlabs/Module/Settings/Channel.php
+++ b/Zotlabs/Module/Settings/Channel.php
@@ -35,6 +35,8 @@ class Channel {
$pageflags = $channel['channel_pageflags'];
$existing_adult = (($pageflags & PAGE_ADULT) ? 1 : 0);
$expire = ((x($_POST, 'expire')) ? intval($_POST['expire']) : 0);
+ $incl = ((x($_POST['message_filter_incl'])) ? htmlspecialchars_decode(trim($_POST['message_filter_incl']), ENT_QUOTES) : '');
+ $excl = ((x($_POST['message_filter_excl'])) ? htmlspecialchars_decode(trim($_POST['message_filter_excl']), ENT_QUOTES) : '');
if ($adult != $existing_adult) {
$pageflags = ($pageflags ^ PAGE_ADULT);
@@ -131,6 +133,8 @@ class Channel {
set_pconfig(local_channel(), 'system', 'photo_path', $photo_path);
set_pconfig(local_channel(), 'system', 'attach_path', $attach_path);
set_pconfig(local_channel(), 'system', 'email_notify_host', $mailhost);
+ set_pconfig(local_channel(), 'system', 'message_filter_incl', $incl);
+ set_pconfig(local_channel(), 'system', 'message_filter_excl', $excl);
$r = q("update channel set channel_pageflags = %d, channel_timezone = '%s',
channel_location = '%s', channel_notifyflags = %d, channel_expire_days = %d
@@ -277,6 +281,8 @@ class Channel {
'$removeme' => t('Remove Channel'),
'$removechannel' => t('Remove this channel.'),
'$expire' => ['expire', t('Expire other channel content after this many days'), $expire, t('0 or blank to use the website limit.') . ' ' . ((intval($sys_expire)) ? sprintf(t('This website expires after %d days.'), intval($sys_expire)) : t('This website does not expire imported content.')) . ' ' . t('The website limit takes precedence if lower than your limit.')],
+ '$message_filter_excl' => ['message_filter_excl', t('Do not import posts with this text'), get_pconfig(local_channel(), 'system', 'message_filter_excl', ''), t('Words one per line or #tags, $categories, /patterns/, lang=xx, lang!=xx - leave blank to import all posts')],
+ '$message_filter_incl' => ['message_filter_incl', t('Only import posts with this text'), get_pconfig(local_channel(), 'system', 'message_filter_incl', ''), t('Words one per line or #tags, $categories, /patterns/, lang=xx, lang!=xx - leave blank to import all posts')]
]);
call_hooks('settings_form', $o);
diff --git a/Zotlabs/Module/Settings/Channel_home.php b/Zotlabs/Module/Settings/Channel_home.php
index e8faa7fb2..470dbe4c3 100644
--- a/Zotlabs/Module/Settings/Channel_home.php
+++ b/Zotlabs/Module/Settings/Channel_home.php
@@ -13,7 +13,7 @@ class Channel_home {
$module = substr(strrchr(strtolower(static::class), '\\'), 1);
check_form_security_token_redirectOnErr('/settings/' . $module, 'settings_' . $module);
-
+
$features = get_module_features($module);
process_module_features_post(local_channel(), $features, $_POST);
@@ -25,10 +25,10 @@ class Channel_home {
$channel_menu = ((x($_POST['channel_menu'])) ? htmlspecialchars_decode(trim($_POST['channel_menu']),ENT_QUOTES) : '');
set_pconfig(local_channel(),'system','channel_menu',$channel_menu);
-
+
Libsync::build_sync_packet();
- if($_POST['rpath'])
+ if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
goaway($_POST['rpath']);
return;
@@ -82,7 +82,7 @@ class Channel_home {
$tpl = get_markup_template("settings_module.tpl");
$o .= replace_macros($tpl, array(
- '$rpath' => $rpath,
+ '$rpath' => escape_url($rpath),
'$action_url' => 'settings/' . $module,
'$form_security_token' => get_form_security_token('settings_' . $module),
'$title' => t('Channel Home Settings'),
@@ -90,7 +90,7 @@ class Channel_home {
'$extra_settings_html' => $extra_settings_html,
'$submit' => t('Submit')
));
-
+
return $o;
}
diff --git a/Zotlabs/Module/Settings/Connections.php b/Zotlabs/Module/Settings/Connections.php
index 4369deb27..52a95a3d1 100644
--- a/Zotlabs/Module/Settings/Connections.php
+++ b/Zotlabs/Module/Settings/Connections.php
@@ -11,14 +11,14 @@ class Connections {
$module = substr(strrchr(strtolower(static::class), '\\'), 1);
check_form_security_token_redirectOnErr('/settings/' . $module, 'settings_' . $module);
-
+
$features = get_module_features($module);
process_module_features_post(local_channel(), $features, $_POST);
-
+
Libsync::build_sync_packet();
- if($_POST['rpath'])
+ if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
goaway($_POST['rpath']);
return;
@@ -34,14 +34,14 @@ class Connections {
$tpl = get_markup_template("settings_module.tpl");
$o .= replace_macros($tpl, array(
- '$rpath' => $rpath,
+ '$rpath' => escape_url($rpath),
'$action_url' => 'settings/' . $module,
'$form_security_token' => get_form_security_token('settings_' . $module),
'$title' => t('Connections Settings'),
'$features' => process_module_features_get(local_channel(), $features),
'$submit' => t('Submit')
));
-
+
return $o;
}
diff --git a/Zotlabs/Module/Settings/Directory.php b/Zotlabs/Module/Settings/Directory.php
index d1dd0677e..09ea61f60 100644
--- a/Zotlabs/Module/Settings/Directory.php
+++ b/Zotlabs/Module/Settings/Directory.php
@@ -11,14 +11,14 @@ class Directory {
$module = substr(strrchr(strtolower(static::class), '\\'), 1);
check_form_security_token_redirectOnErr('/settings/' . $module, 'settings_' . $module);
-
+
$features = get_module_features($module);
process_module_features_post(local_channel(), $features, $_POST);
-
+
Libsync::build_sync_packet();
- if($_POST['rpath'])
+ if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
goaway($_POST['rpath']);
return;
@@ -34,14 +34,14 @@ class Directory {
$tpl = get_markup_template("settings_module.tpl");
$o .= replace_macros($tpl, array(
- '$rpath' => $rpath,
+ '$rpath' => escape_url($rpath),
'$action_url' => 'settings/' . $module,
'$form_security_token' => get_form_security_token('settings_' . $module),
'$title' => t('Directory Settings'),
'$features' => process_module_features_get(local_channel(), $features),
'$submit' => t('Submit')
));
-
+
return $o;
}
diff --git a/Zotlabs/Module/Settings/Editor.php b/Zotlabs/Module/Settings/Editor.php
index cf6dd2807..85c3e69ae 100644
--- a/Zotlabs/Module/Settings/Editor.php
+++ b/Zotlabs/Module/Settings/Editor.php
@@ -11,14 +11,14 @@ class Editor {
$module = substr(strrchr(strtolower(static::class), '\\'), 1);
check_form_security_token_redirectOnErr('/settings/' . $module, 'settings_' . $module);
-
+
$features = get_module_features($module);
process_module_features_post(local_channel(), $features, $_POST);
-
+
Libsync::build_sync_packet();
- if($_POST['rpath'])
+ if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
goaway($_POST['rpath']);
return;
@@ -34,14 +34,14 @@ class Editor {
$tpl = get_markup_template("settings_module.tpl");
$o .= replace_macros($tpl, array(
- '$rpath' => $rpath,
+ '$rpath' => escape_url($rpath),
'$action_url' => 'settings/' . $module,
'$form_security_token' => get_form_security_token('settings_' . $module),
'$title' => t('Editor Settings'),
'$features' => process_module_features_get(local_channel(), $features),
'$submit' => t('Submit')
));
-
+
return $o;
}
diff --git a/Zotlabs/Module/Settings/Events.php b/Zotlabs/Module/Settings/Events.php
index ab393c932..0a0e3516c 100644
--- a/Zotlabs/Module/Settings/Events.php
+++ b/Zotlabs/Module/Settings/Events.php
@@ -11,14 +11,14 @@ class Events {
$module = substr(strrchr(strtolower(static::class), '\\'), 1);
check_form_security_token_redirectOnErr('/settings/' . $module, 'settings_' . $module);
-
+
$features = get_module_features($module);
process_module_features_post(local_channel(), $features, $_POST);
-
+
Libsync::build_sync_packet();
- if($_POST['rpath'])
+ if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
goaway($_POST['rpath']);
return;
@@ -34,14 +34,14 @@ class Events {
$tpl = get_markup_template("settings_module.tpl");
$o .= replace_macros($tpl, array(
- '$rpath' => $rpath,
+ '$rpath' => escape_url($rpath),
'$action_url' => 'settings/' . $module,
'$form_security_token' => get_form_security_token('settings_' . $module),
'$title' => t('Events Settings'),
'$features' => process_module_features_get(local_channel(), $features),
'$submit' => t('Submit')
));
-
+
return $o;
}
diff --git a/Zotlabs/Module/Settings/Manage.php b/Zotlabs/Module/Settings/Manage.php
index cbc494cf8..6fb57eafb 100644
--- a/Zotlabs/Module/Settings/Manage.php
+++ b/Zotlabs/Module/Settings/Manage.php
@@ -12,14 +12,14 @@ class Manage {
$module = substr(strrchr(strtolower(static::class), '\\'), 1);
check_form_security_token_redirectOnErr('/settings/' . $module, 'settings_' . $module);
-
+
$features = get_module_features($module);
process_module_features_post(local_channel(), $features, $_POST);
-
+
Libsync::build_sync_packet();
- if($_POST['rpath'])
+ if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
goaway($_POST['rpath']);
return;
@@ -35,14 +35,14 @@ class Manage {
$tpl = get_markup_template("settings_module.tpl");
$o .= replace_macros($tpl, array(
- '$rpath' => $rpath,
+ '$rpath' => escape_url($rpath),
'$action_url' => 'settings/' . $module,
'$form_security_token' => get_form_security_token('settings_' . $module),
'$title' => t('Channel Manager Settings'),
'$features' => process_module_features_get(local_channel(), $features),
'$submit' => t('Submit')
));
-
+
return $o;
}
diff --git a/Zotlabs/Module/Settings/Network.php b/Zotlabs/Module/Settings/Network.php
index 9f5bdb2e5..eae963a25 100644
--- a/Zotlabs/Module/Settings/Network.php
+++ b/Zotlabs/Module/Settings/Network.php
@@ -21,10 +21,10 @@ class Network {
$network_divmore_height = 50;
set_pconfig(local_channel(),'system','network_divmore_height', $network_divmore_height);
-
+
Libsync::build_sync_packet();
- if($_POST['rpath'])
+ if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
goaway($_POST['rpath']);
return;
@@ -53,7 +53,7 @@ class Network {
$tpl = get_markup_template("settings_module.tpl");
$o .= replace_macros($tpl, array(
- '$rpath' => $rpath,
+ '$rpath' => escape_url($rpath),
'$action_url' => 'settings/' . $module,
'$form_security_token' => get_form_security_token('settings_' . $module),
'$title' => t('Stream Settings'),
@@ -61,7 +61,7 @@ class Network {
'$extra_settings_html' => $extra_settings_html,
'$submit' => t('Submit')
));
-
+
return $o;
}
diff --git a/Zotlabs/Module/Settings/Photos.php b/Zotlabs/Module/Settings/Photos.php
index 8195d660b..f68c8847b 100644
--- a/Zotlabs/Module/Settings/Photos.php
+++ b/Zotlabs/Module/Settings/Photos.php
@@ -7,18 +7,18 @@ use Zotlabs\Lib\Libsync;
class Photos {
function post() {
-
+
$module = substr(strrchr(strtolower(static::class), '\\'), 1);
check_form_security_token_redirectOnErr('/settings/' . $module, 'settings_' . $module);
-
+
$features = get_module_features($module);
process_module_features_post(local_channel(), $features, $_POST);
-
+
Libsync::build_sync_packet();
- if($_POST['rpath'])
+ if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
goaway($_POST['rpath']);
return;
@@ -34,14 +34,14 @@ class Photos {
$tpl = get_markup_template("settings_module.tpl");
$o .= replace_macros($tpl, array(
- '$rpath' => $rpath,
+ '$rpath' => escape_url($rpath),
'$action_url' => 'settings/' . $module,
'$form_security_token' => get_form_security_token('settings_' . $module),
'$title' => t('Photos Settings'),
'$features' => process_module_features_get(local_channel(), $features),
'$submit' => t('Submit')
));
-
+
return $o;
}
diff --git a/Zotlabs/Module/Settings/Privacy.php b/Zotlabs/Module/Settings/Privacy.php
index fbda78a6f..847bb3b8f 100644
--- a/Zotlabs/Module/Settings/Privacy.php
+++ b/Zotlabs/Module/Settings/Privacy.php
@@ -119,7 +119,7 @@ class Privacy {
],
'$autoperms' => ['autoperms', t('Automatically approve new contacts'), $autoperms, '', [t('No'), t('Yes')]],
'$index_opt_out' => ['index_opt_out', t('Opt-out of search engine indexing'), $index_opt_out, '', [t('No'), t('Yes')]],
- '$group_actor' => ['group_actor', t('Group actor'), $group_actor, t('Allow this channel to act as a forum'), [t('No'), t('Yes')]],
+ '$group_actor' => ['group_actor', t('Group actor'), $group_actor, t('Allow this channel to act as a forum'), [t('No'), t('Yes')]]
]);
return $o;
diff --git a/Zotlabs/Module/Settings/Profiles.php b/Zotlabs/Module/Settings/Profiles.php
index a1a1b8d96..0ff2dfb6d 100644
--- a/Zotlabs/Module/Settings/Profiles.php
+++ b/Zotlabs/Module/Settings/Profiles.php
@@ -23,7 +23,7 @@ class Profiles {
Libsync::build_sync_packet();
- if($_POST['rpath'])
+ if(isset($_POST['rpath']) && is_local_url($_POST['rpath']))
goaway($_POST['rpath']);
return;
@@ -43,7 +43,7 @@ class Profiles {
$tpl = get_markup_template("settings_module.tpl");
$o .= replace_macros($tpl, array(
- '$rpath' => $rpath,
+ '$rpath' => escape_url($rpath),
'$action_url' => 'settings/' . $module,
'$form_security_token' => get_form_security_token('settings_' . $module),
'$title' => t('Profiles Settings'),
diff --git a/Zotlabs/Photo/PhotoDriver.php b/Zotlabs/Photo/PhotoDriver.php
index 4c4f26e32..6bdb89ab1 100644
--- a/Zotlabs/Photo/PhotoDriver.php
+++ b/Zotlabs/Photo/PhotoDriver.php
@@ -2,7 +2,7 @@
namespace Zotlabs\Photo;
-use Zotlabs\Lib\Hashpath;
+use Zotlabs\Lib\Hashpath;
/**
* @brief Abstract photo driver class.
@@ -494,11 +494,11 @@ abstract class PhotoDriver {
( aid, uid, xchan, resource_id, created, edited, filename, mimetype, album, height, width, content, os_storage, filesize, imgscale, photo_usage, title, description, os_path, display_path, allow_cid, allow_gid, deny_cid, deny_gid, expires, profile )
VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)", intval($p['aid']), intval($p['uid']), dbesc($p['xchan']), dbesc($p['resource_id']), dbescdate($p['created']), dbescdate($p['edited']), dbesc(basename($p['filename'])), dbesc($p['mimetype']), dbesc($p['album']), intval($p['height']), intval($p['width']), (intval($p['os_storage']) ? dbescbin($p['os_syspath']) : dbescbin($this->imageString())), intval($p['os_storage']), (intval($p['os_storage']) ? @filesize($p['os_syspath']) : strlen($this->imageString())), intval($p['imgscale']), intval($p['photo_usage']), dbesc($p['title']), dbesc($p['description']), dbesc($p['os_path']), dbesc($p['display_path']), dbesc($p['allow_cid']), dbesc($p['allow_gid']), dbesc($p['deny_cid']), dbesc($p['deny_gid']), dbescdate($p['expires']), intval($p['profile']));
}
- logger('Photo save imgscale ' . $p['imgscale'] . ' returned ' . intval($r));
+ logger('Photo save imgscale ' . $p['imgscale'] . ' returned: ' . (($r) ? 1 : 0));
return $r;
}
-
+
/**
* @brief Stores thumbnail to database or filesystem.
*
@@ -530,13 +530,13 @@ abstract class PhotoDriver {
}
else
$arr['os_storage'] = 0;
-
+
if(! $this->save($arr)) {
if(array_key_exists('os_syspath', $arr))
@unlink($arr['os_syspath']);
return false;
}
-
+
return true;
}
diff --git a/Zotlabs/Web/HTTPSig.php b/Zotlabs/Web/HTTPSig.php
index a7a59b8cf..4177477a1 100644
--- a/Zotlabs/Web/HTTPSig.php
+++ b/Zotlabs/Web/HTTPSig.php
@@ -127,6 +127,7 @@ class HTTPSig {
if (array_key_exists($h, $headers)) {
$signed_data .= $h . ': ' . $headers[$h] . "\n";
}
+
if ($h === 'date') {
$d = new DateTime($headers[$h]);
$d->setTimeZone(new DateTimeZone('UTC'));
@@ -142,20 +143,34 @@ class HTTPSig {
$signed_data = rtrim($signed_data, "\n");
$algorithm = null;
+
if ($sig_block['algorithm'] === 'rsa-sha256') {
$algorithm = 'sha256';
}
+
if ($sig_block['algorithm'] === 'rsa-sha512') {
$algorithm = 'sha512';
}
- if (!array_key_exists('keyId', $sig_block))
+ if (!array_key_exists('keyId', $sig_block)) {
return $result;
+ }
$result['signer'] = $sig_block['keyId'];
$cached_key = self::get_key($key, $keytype, $result['signer']);
+ if ($sig_block['algorithm'] === 'hs2019') {
+ if (isset($cached_key['algorithm'])) {
+ if (strpos($cached_key['algorithm'], 'rsa-sha256') !== false) {
+ $algorithm = 'sha256';
+ }
+
+ if (strpos($cached_key['algorithm'], 'rsa-sha512') !== false) {
+ $algorithm = 'sha512';
+ }
+ }
+ }
if (!($cached_key && $cached_key['public_key'])) {
return $result;
@@ -296,7 +311,7 @@ class HTTPSig {
$best = Libzot::zot_record_preferred($x);
}
if ($best && $best['xchan_pubkey']) {
- return ['portable_id' => $best['xchan_hash'], 'public_key' => $best['xchan_pubkey'], 'hubloc' => $best];
+ return ['portable_id' => $best['xchan_hash'], 'public_key' => $best['xchan_pubkey'], 'algorithm' => get_xconfig($best['xchan_hash'], 'system', 'signing_algorithm'), 'hubloc' => $best];
}
}
@@ -308,12 +323,38 @@ class HTTPSig {
// The record wasn't in cache. Fetch it now.
$r = ActivityStreams::fetch($id);
+ $signatureAlgorithm = EMPTY_STR;
if ($r) {
if (array_key_exists('publicKey', $r) && array_key_exists('publicKeyPem', $r['publicKey']) && array_key_exists('id', $r['publicKey'])) {
if ($r['publicKey']['id'] === $id || $r['id'] === $id) {
$portable_id = ((array_key_exists('owner', $r['publicKey'])) ? $r['publicKey']['owner'] : EMPTY_STR);
- return ['public_key' => self::convertKey($r['publicKey']['publicKeyPem']), 'portable_id' => $portable_id, 'hubloc' => []];
+
+ // the w3c sec context has conflicting names and no defined values for this property except
+ // "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
+
+ // Since the names conflict, it could mess up LD-signatures but we will accept both, and at this
+ // time we will only look for the substrings 'rsa-sha256' and 'rsa-sha512' within those properties.
+ // We will also accept a toplevel 'sigAlgorithm' regardless of namespace with the same constraints.
+ // Default to rsa-sha256 if we can't figure out. If they're sending 'hs2019' we have to
+ // look for something.
+
+ if (isset($r['publicKey']['signingAlgorithm'])) {
+ $signatureAlgorithm = $r['publicKey']['signingAlgorithm'];
+ set_xconfig($portable_id, 'system', 'signing_algorithm', $signatureAlgorithm);
+ }
+
+ if (isset($r['publicKey']['signatureAlgorithm'])) {
+ $signatureAlgorithm = $r['publicKey']['signatureAlgorithm'];
+ set_xconfig($portable_id, 'system', 'signing_algorithm', $signatureAlgorithm);
+ }
+
+ if (isset($r['sigAlgorithm'])) {
+ $signatureAlgorithm = $r['sigAlgorithm'];
+ set_xconfig($portable_id, 'system', 'signing_algorithm', $signatureAlgorithm);
+ }
+
+ return ['public_key' => self::convertKey($r['publicKey']['publicKeyPem']), 'portable_id' => $portable_id, 'algorithm' => (($signatureAlgorithm) ? $signatureAlgorithm : 'rsa-sha256'), 'hubloc' => []];
}
}
}
@@ -343,7 +384,7 @@ class HTTPSig {
}
if ($best && $best['xchan_pubkey']) {
- return ['portable_id' => $best['xchan_hash'], 'public_key' => $best['xchan_pubkey'], 'hubloc' => $best];
+ return ['portable_id' => $best['xchan_hash'], 'public_key' => $best['xchan_pubkey'], 'algorithm' => get_xconfig($best['xchan_hash'], 'system', 'signing_algorithm'), 'hubloc' => $best];
}
}
@@ -389,7 +430,7 @@ class HTTPSig {
}
if ($best && $best['xchan_pubkey']) {
- return ['portable_id' => $best['xchan_hash'], 'public_key' => $best['xchan_pubkey'], 'hubloc' => $best];
+ return ['portable_id' => $best['xchan_hash'], 'public_key' => $best['xchan_pubkey'], 'algorithm' => get_xconfig($best['xchan_hash'], 'system', 'signing_algorithm'), 'hubloc' => $best];
}
}
@@ -461,6 +502,9 @@ class HTTPSig {
$x = self::sign($head, $prvkey, $alg);
+ // TODO: should we default to hs2019?
+ // $headerval = 'keyId="' . $keyid . '",algorithm="' . (($algorithm === 'rsa-sha256') ? 'hs2019' : $algorithm) . '",headers="' . $x['headers'] . '",signature="' . $x['signature'] . '"';
+
$headerval = 'keyId="' . $keyid . '",algorithm="' . $algorithm . '",headers="' . $x['headers'] . '",signature="' . $x['signature'] . '"';
if ($encryption) {
@@ -528,11 +572,14 @@ class HTTPSig {
if ($head) {
foreach ($head as $k => $v) {
- $headers .= strtolower($k) . ': ' . trim($v) . "\n";
+ $k = strtolower($k);
+ $v = (($v) ? trim($v) : '');
+
+ $headers .= $k . ': ' . $v . "\n";
if ($fields)
$fields .= ' ';
- $fields .= strtolower($k);
+ $fields .= $k;
}
// strip the trailing linefeed
$headers = rtrim($headers, "\n");
diff --git a/Zotlabs/Web/WebServer.php b/Zotlabs/Web/WebServer.php
index de0d5a883..70c6eb9b8 100644
--- a/Zotlabs/Web/WebServer.php
+++ b/Zotlabs/Web/WebServer.php
@@ -107,7 +107,8 @@ class WebServer {
$Router->Dispatch();
- $this->set_homebase();
+ // TODO: this is not used for anything atm and messes up comanche templates by adding some javascript
+ //$this->set_homebase();
// now that we've been through the module content, see if the page reported
// a permission problem and if so, a 403 response would seem to be in order.
diff --git a/Zotlabs/Widget/Activity.php b/Zotlabs/Widget/Activity.php
index 5d9795c7e..34e0f67dc 100644
--- a/Zotlabs/Widget/Activity.php
+++ b/Zotlabs/Widget/Activity.php
@@ -1,5 +1,10 @@
<?php
+/**
+ * * Name: Activity
+ * * Description: Shows the unseen activity count per contact
+ */
+
namespace Zotlabs\Widget;
class Activity {
diff --git a/Zotlabs/Widget/Activity_filter.php b/Zotlabs/Widget/Activity_filter.php
index b7a69752e..daaf5fb67 100644
--- a/Zotlabs/Widget/Activity_filter.php
+++ b/Zotlabs/Widget/Activity_filter.php
@@ -1,5 +1,12 @@
<?php
+/**
+ * * Name: Activity filters
+ * * Description: Filters for the network stream
+ * * Requires: network
+ */
+
+
namespace Zotlabs\Widget;
use App;
diff --git a/Zotlabs/Widget/Activity_order.php b/Zotlabs/Widget/Activity_order.php
index d3fe2a30f..e8ee11508 100644
--- a/Zotlabs/Widget/Activity_order.php
+++ b/Zotlabs/Widget/Activity_order.php
@@ -2,6 +2,12 @@
namespace Zotlabs\Widget;
+/**
+ * * Name: Activity order
+ * * Description: Order the network stream by posted date, last commented or by date unthreaded
+ * * Requires: network
+ */
+
class Activity_order {
function widget($arr) {
@@ -22,7 +28,7 @@ class Activity_order {
switch($_GET['order']){
case 'post':
$postord_active = 'active';
- set_pconfig(local_channel(), 'mod_network', 'order', 1);
+ set_pconfig(local_channel(), 'mod_network', 'order', 1);
break;
case 'comment':
$commentord_active = 'active';
diff --git a/Zotlabs/Widget/Admin.php b/Zotlabs/Widget/Admin.php
index f349377a0..0a7a6925f 100644
--- a/Zotlabs/Widget/Admin.php
+++ b/Zotlabs/Widget/Admin.php
@@ -1,5 +1,10 @@
<?php
+/**
+ * * Name: Admin menu
+ * * Requires: admin
+ */
+
namespace Zotlabs\Widget;
class Admin {
diff --git a/Zotlabs/Widget/Affinity.php b/Zotlabs/Widget/Affinity.php
index 572af0503..e083e576c 100644
--- a/Zotlabs/Widget/Affinity.php
+++ b/Zotlabs/Widget/Affinity.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Affinity Tool
+ * * Description: Filter the network stream by affinity, requires the Affinity Tool App
+ * * Requires: network
+ */
+
namespace Zotlabs\Widget;
use Zotlabs\Lib\Apps;
@@ -13,7 +19,7 @@ class Affinity {
if(! Apps::system_app_installed(local_channel(),'Affinity Tool'))
return;
-
+
$default_cmin = ((Apps::system_app_installed(local_channel(),'Affinity Tool')) ? get_pconfig(local_channel(),'affinity','cmin',0) : 0);
$default_cmax = ((Apps::system_app_installed(local_channel(),'Affinity Tool')) ? get_pconfig(local_channel(),'affinity','cmax',99) : 99);
@@ -54,7 +60,7 @@ class Affinity {
'$refresh' => t('Refresh'),
'$labels' => $label_str,
));
-
+
$arr = array('html' => $x);
call_hooks('main_slider',$arr);
@@ -63,4 +69,4 @@ class Affinity {
}
}
-
+
diff --git a/Zotlabs/Widget/Album.php b/Zotlabs/Widget/Album.php
index f359e6d0f..003f6f49d 100644
--- a/Zotlabs/Widget/Album.php
+++ b/Zotlabs/Widget/Album.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Album
+ * * Description: Displays an album with a title which can be defined via the 'album' and 'title' variable
+ * * Requires: channel, articles, cards, wiki
+ */
+
namespace Zotlabs\Widget;
require_once('include/attach.php');
@@ -99,7 +105,7 @@ class Album {
'$upload_form' => $upload_form,
'$usage' => $usage_message
));
-
+
return $o;
}
}
diff --git a/Zotlabs/Widget/Appcategories.php b/Zotlabs/Widget/Appcategories.php
index e916f095f..31fb2542e 100644
--- a/Zotlabs/Widget/Appcategories.php
+++ b/Zotlabs/Widget/Appcategories.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: App categories
+ * * Description: Shows a menu with various app categories
+ * * Requires: apps
+ */
+
namespace Zotlabs\Widget;
class Appcategories {
diff --git a/Zotlabs/Widget/Appcloud.php b/Zotlabs/Widget/Appcloud.php
index 2a4671eee..791d534c2 100644
--- a/Zotlabs/Widget/Appcloud.php
+++ b/Zotlabs/Widget/Appcloud.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: App cloud
+ * * Description: Shows a cloud with various app categories
+ * * Requires: apps
+ */
+
namespace Zotlabs\Widget;
class Appcloud {
diff --git a/Zotlabs/Widget/Appstore.php b/Zotlabs/Widget/Appstore.php
index da05c0b62..d8499152a 100644
--- a/Zotlabs/Widget/Appstore.php
+++ b/Zotlabs/Widget/Appstore.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: App store menu
+ * * Description: Shows a menu with links to installed and available apps
+ * * Requires: apps
+ */
+
namespace Zotlabs\Widget;
diff --git a/Zotlabs/Widget/Archive.php b/Zotlabs/Widget/Archive.php
index 9adaac38f..e712a8236 100644
--- a/Zotlabs/Widget/Archive.php
+++ b/Zotlabs/Widget/Archive.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Archive
+ * * Description: A menu with links to content sorted by years and months
+ * * Requires: channel, articles, cards
+ */
+
namespace Zotlabs\Widget;
diff --git a/Zotlabs/Widget/Bookmarkedchats.php b/Zotlabs/Widget/Bookmarkedchats.php
index d64bbdb4b..5d6d000c1 100644
--- a/Zotlabs/Widget/Bookmarkedchats.php
+++ b/Zotlabs/Widget/Bookmarkedchats.php
@@ -1,14 +1,15 @@
<?php
+/**
+ * * Name: Bookmarked chats
+ * * Description: A menu with bookmarked chats
+ */
+
namespace Zotlabs\Widget;
class Bookmarkedchats {
function widget($arr) {
-
- if(! feature_enabled(\App::$profile['profile_uid'],'ajaxchat'))
- return '';
-
$h = get_observer_hash();
if(! $h)
return;
diff --git a/Zotlabs/Widget/Catcloud.php b/Zotlabs/Widget/Catcloud.php
index c53f9bbf6..5740caab7 100644
--- a/Zotlabs/Widget/Catcloud.php
+++ b/Zotlabs/Widget/Catcloud.php
@@ -2,6 +2,13 @@
namespace Zotlabs\Widget;
+/**
+ * * Name: Category cloud
+ * * Description: Display category links in a cloud
+ * * Requires: channel, cards, articles
+ */
+
+
class Catcloud {
function widget($arr) {
@@ -22,7 +29,7 @@ class Catcloud {
return card_catblock(\App::$profile['profile_uid'], $limit, '', \App::$profile['channel_hash']);
case 'articles':
-
+
if(! perm_is_allowed(\App::$profile['profile_uid'], get_observer_hash(), 'view_pages'))
return '';
diff --git a/Zotlabs/Widget/Catcloud_wall.php b/Zotlabs/Widget/Catcloud_wall.php
index 3795987cc..4ee30d023 100644
--- a/Zotlabs/Widget/Catcloud_wall.php
+++ b/Zotlabs/Widget/Catcloud_wall.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Category cloud wall
+ * * Description: Display category links in a cloud restricted to wall posts
+ * * Requires: channel
+ */
+
namespace Zotlabs\Widget;
class Catcloud_wall {
diff --git a/Zotlabs/Widget/Categories.php b/Zotlabs/Widget/Categories.php
index 94ad469da..0c6996d55 100644
--- a/Zotlabs/Widget/Categories.php
+++ b/Zotlabs/Widget/Categories.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Categories
+ * * Description: Display a menu with links to categories
+ * * Requires: channel, articles, cards, cloud
+ */
+
namespace Zotlabs\Widget;
use App;
diff --git a/Zotlabs/Widget/Cdav.php b/Zotlabs/Widget/Cdav.php
index ce716b455..f84f5cb04 100644
--- a/Zotlabs/Widget/Cdav.php
+++ b/Zotlabs/Widget/Cdav.php
@@ -1,8 +1,12 @@
<?php
-namespace Zotlabs\Widget;
-
+/**
+ * * Name: CalDAV/CardDAV tools
+ * * Description: A widget with various CalDAV and CardDAV tools
+ * * Requires: cdav
+ */
+namespace Zotlabs\Widget;
class Cdav {
@@ -164,7 +168,7 @@ class Cdav {
'uri' => $sabreabook['uri'],
'displayname' => $sabreabook['{DAV:}displayname'],
'id' => $sabreabook['id']
-
+
];
}
diff --git a/Zotlabs/Widget/Chatroom_list.php b/Zotlabs/Widget/Chatroom_list.php
index e2aad0e05..d80e40bf9 100644
--- a/Zotlabs/Widget/Chatroom_list.php
+++ b/Zotlabs/Widget/Chatroom_list.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Chatroom list
+ * * Description: A menu with links to your chatrooms
+ * * Requires: chat, channel, articles, cards, wiki
+ */
+
namespace Zotlabs\Widget;
class Chatroom_list {
diff --git a/Zotlabs/Widget/Chatroom_members.php b/Zotlabs/Widget/Chatroom_members.php
index 8ed77fb3c..0846192ce 100644
--- a/Zotlabs/Widget/Chatroom_members.php
+++ b/Zotlabs/Widget/Chatroom_members.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Chatroom members
+ * * Description: A widget that shows members of a chatroom
+ * * Requires: chat
+ */
+
namespace Zotlabs\Widget;
class Chatroom_members {
diff --git a/Zotlabs/Widget/Clock.php b/Zotlabs/Widget/Clock.php
index b63b5f748..3b9751cc5 100644
--- a/Zotlabs/Widget/Clock.php
+++ b/Zotlabs/Widget/Clock.php
@@ -1,5 +1,10 @@
<?php
+/**
+ * * Name: Clock
+ * * Description: A simple widget that shows the current time
+ */
+
namespace Zotlabs\Widget;
class Clock {
diff --git a/Zotlabs/Widget/Collections.php b/Zotlabs/Widget/Collections.php
deleted file mode 100644
index ad1a10f4b..000000000
--- a/Zotlabs/Widget/Collections.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-
-namespace Zotlabs\Widget;
-
-use Zotlabs\Lib\AccessList;
-
-class Collections {
-
- function widget($args) {
-
- if(argc() < 2)
- // return;
-
- $mode = ((array_key_exists('mode',$args)) ? $args['mode'] : 'conversation');
- switch($mode) {
- case 'conversation':
- $every = argv(0);
- $each = argv(0);
- $edit = true;
- $current = $_REQUEST['gid'];
- $abook_id = 0;
- $wmode = 0;
- break;
- case 'connections':
- $every = 'connections';
- $each = 'group';
- $edit = true;
- $current = $_REQUEST['gid'];
- $abook_id = 0;
- $wmode = 0;
- case 'groups':
- $every = 'connections';
- $each = argv(0);
- $edit = false;
- $current = intval(argv(1));
- $abook_id = 0;
- $wmode = 1;
- break;
- case 'abook':
- $every = 'connections';
- $each = 'group';
- $edit = false;
- $current = 0;
- $abook_id = \App::$poi['abook_xchan'];
- $wmode = 1;
- break;
- default:
- return '';
- break;
- }
-
- return AccessList::widget($every, $each, $edit, $current, $abook_id, $wmode);
- }
-}
diff --git a/Zotlabs/Widget/Common_friends.php b/Zotlabs/Widget/Common_friends.php
index a67b9312c..6024f82f5 100644
--- a/Zotlabs/Widget/Common_friends.php
+++ b/Zotlabs/Widget/Common_friends.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Common friends
+ * * Description: Display common friends to visitors
+ * * Requires: channel, articles, cards, wiki
+ */
+
namespace Zotlabs\Widget;
require_once('include/contact_widgets.php');
@@ -8,7 +14,7 @@ class Common_friends {
function widget($arr) {
- if((! \App::$profile['profile_uid'])
+ if((! \App::$profile['profile_uid'])
|| (! perm_is_allowed(\App::$profile['profile_uid'],get_observer_hash(),'view_contacts'))) {
return '';
}
diff --git a/Zotlabs/Widget/Cover_photo.php b/Zotlabs/Widget/Cover_photo.php
index 97323ea8c..11d9c4715 100644
--- a/Zotlabs/Widget/Cover_photo.php
+++ b/Zotlabs/Widget/Cover_photo.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Cover photo
+ * * Description: Display a cover photo in the banner region
+ * * Requires: disabled_for_pdledit_gui
+ */
+
namespace Zotlabs\Widget;
class Cover_photo {
diff --git a/Zotlabs/Widget/Design_tools.php b/Zotlabs/Widget/Design_tools.php
index a15c0c98d..0f94577d8 100644
--- a/Zotlabs/Widget/Design_tools.php
+++ b/Zotlabs/Widget/Design_tools.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Design tools
+ * * Description: Links to useful tools for webpages
+ * * Requires: webpages
+ */
+
namespace Zotlabs\Widget;
class Design_tools {
@@ -11,4 +17,4 @@ class Design_tools {
return EMPTY_STR;
}
-} \ No newline at end of file
+}
diff --git a/Zotlabs/Widget/Dirsort.php b/Zotlabs/Widget/Dirsort.php
index 2fb38b7df..569782bb9 100644
--- a/Zotlabs/Widget/Dirsort.php
+++ b/Zotlabs/Widget/Dirsort.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Dirsort
+ * * Description: Various options to provide different vies of the directory
+ * * Requires: directory
+ */
+
namespace Zotlabs\Widget;
use Zotlabs\Lib\Libzotdir;
diff --git a/Zotlabs/Widget/Dirtags.php b/Zotlabs/Widget/Dirtags.php
index 246c47dde..183c2f20f 100644
--- a/Zotlabs/Widget/Dirtags.php
+++ b/Zotlabs/Widget/Dirtags.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Directory tags
+ * * Description: Show directory tags in a cloud
+ * * Requires: directory
+ */
+
namespace Zotlabs\Widget;
class Dirtags {
diff --git a/Zotlabs/Widget/Eventstools.php b/Zotlabs/Widget/Eventstools.php
deleted file mode 100644
index 7efd3f72e..000000000
--- a/Zotlabs/Widget/Eventstools.php
+++ /dev/null
@@ -1,19 +0,0 @@
-<?php
-
-namespace Zotlabs\Widget;
-
-class Eventstools {
-
- function widget($arr) {
-
- if(! local_channel())
- return;
-
- return replace_macros(get_markup_template('events_tools_side.tpl'), array(
- '$title' => t('Events Tools'),
- '$export' => t('Export Calendar'),
- '$import' => t('Import Calendar'),
- '$submit' => t('Submit')
- ));
- }
-}
diff --git a/Zotlabs/Widget/Filer.php b/Zotlabs/Widget/Filer.php
index 5d6f96a87..6c5ac47a9 100644
--- a/Zotlabs/Widget/Filer.php
+++ b/Zotlabs/Widget/Filer.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Saved folders
+ * * Description: A menu containing saved folders
+ * * Requires: network
+ */
+
namespace Zotlabs\Widget;
require_once('include/contact_widgets.php');
@@ -10,7 +16,6 @@ class Filer {
if(! local_channel())
return '';
-
$selected = ((x($_REQUEST,'file')) ? $_REQUEST['file'] : '');
$terms = array();
diff --git a/Zotlabs/Widget/Findpeople.php b/Zotlabs/Widget/Findpeople.php
index f450b96ae..45d62bb7f 100644
--- a/Zotlabs/Widget/Findpeople.php
+++ b/Zotlabs/Widget/Findpeople.php
@@ -1,5 +1,10 @@
<?php
+/**
+ * * Name: Find channels
+ * * Description: A simple form to search for channels in the directory
+ */
+
namespace Zotlabs\Widget;
require_once('include/contact_widgets.php');
diff --git a/Zotlabs/Widget/Follow.php b/Zotlabs/Widget/Follow.php
index c4aecc8e1..2a0abb027 100644
--- a/Zotlabs/Widget/Follow.php
+++ b/Zotlabs/Widget/Follow.php
@@ -1,5 +1,10 @@
<?php
+/**
+ * * Name: Follow
+ * * Description: A simple form which allows you to enter an address and send a follow request
+ */
+
namespace Zotlabs\Widget;
@@ -24,7 +29,7 @@ class Follow {
else {
$abook_usage_message = '';
}
-
+
return replace_macros(get_markup_template('follow.tpl'),array(
'$connect' => t('Add New Connection'),
'$desc' => t('Enter channel address'),
diff --git a/Zotlabs/Widget/Forums.php b/Zotlabs/Widget/Forums.php
index 2af7347f1..c40556273 100644
--- a/Zotlabs/Widget/Forums.php
+++ b/Zotlabs/Widget/Forums.php
@@ -1,5 +1,10 @@
<?php
+/**
+ * * Name: Forums
+ * * Description: A list of forum channels with unseen item counts
+ */
+
namespace Zotlabs\Widget;
class Forums {
@@ -21,35 +26,7 @@ class Forums {
$unseen = 1;
$perms_sql = item_permissions_sql(local_channel()) . item_normal();
-
- $xf = false;
-
- $x1 = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = 'send_stream' and v = '0'",
- intval(local_channel())
- );
- if($x1) {
- $xc = ids_to_querystr($x1,'xchan',true);
-
- $x2 = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = 'tag_deliver' and v = '1' and xchan in (" . $xc . ") ",
- intval(local_channel())
- );
-
- if($x2) {
- $xf = ids_to_querystr($x2,'xchan',true);
-
- // private forums
- $x3 = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = 'post_wall' and v = '1' and xchan in (" . $xc . ") and not xchan in (" . $xf . ") ",
- intval(local_channel())
- );
- if($x3) {
- $xf = ids_to_querystr(array_merge($x2,$x3),'xchan',true);
- }
- }
- }
-
- $sql_extra = (($xf) ? " and ( xchan_hash in (" . $xf . ") or xchan_pubforum = 1 ) " : " and xchan_pubforum = 1 ");
-
-
+ $sql_extra = " and xchan_pubforum = 1 ";
$r1 = q("select abook_id, xchan_hash, xchan_name, xchan_url, xchan_photo_s from abook left join xchan on abook_xchan = xchan_hash where xchan_deleted = 0 and abook_channel = %d and abook_pending = 0 and abook_ignored = 0 and abook_blocked = 0 and abook_archived = 0 $sql_extra order by xchan_name $limit ",
intval(local_channel())
diff --git a/Zotlabs/Widget/Fullprofile.php b/Zotlabs/Widget/Fullprofile.php
index e8ed13811..edff88e31 100644
--- a/Zotlabs/Widget/Fullprofile.php
+++ b/Zotlabs/Widget/Fullprofile.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Full profile
+ * * Description: Profile card with extended profile info
+ * * Requires: channel, articles, cards, wiki, cloud, photos
+ */
+
namespace Zotlabs\Widget;
class Fullprofile {
diff --git a/Zotlabs/Widget/Helpindex.php b/Zotlabs/Widget/Helpindex.php
index 6c8748194..fbcd8c8b2 100644
--- a/Zotlabs/Widget/Helpindex.php
+++ b/Zotlabs/Widget/Helpindex.php
@@ -1,11 +1,18 @@
<?php
+/**
+ * * Name: Help index
+ * * Description: Help pages index
+ */
+
namespace Zotlabs\Widget;
class Helpindex {
function widget($arr) {
+ require_once('include/help.php');
+
$o .= '<div class="widget">';
$level_0 = get_help_content('sitetoc');
diff --git a/Zotlabs/Widget/Hq_controls.php b/Zotlabs/Widget/Hq_controls.php
index 91335fd76..7b1fe817d 100644
--- a/Zotlabs/Widget/Hq_controls.php
+++ b/Zotlabs/Widget/Hq_controls.php
@@ -1,5 +1,12 @@
<?php
+/**
+ * * Name: HQ Controls
+ * * Description: Control buttons for the HQ module
+ * * Author: Mario Vavti
+ * * Requires: hq
+ */
+
namespace Zotlabs\Widget;
use Zotlabs\Lib\Apps;
diff --git a/Zotlabs/Widget/Item.php b/Zotlabs/Widget/Item.php
index 273d5649c..9fd703dfe 100644
--- a/Zotlabs/Widget/Item.php
+++ b/Zotlabs/Widget/Item.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Item
+ * * Description: Display a webpage by title or mid,
+ * * Requires: channel, articles, cards, wiki
+ */
+
namespace Zotlabs\Widget;
require_once('include/security.php');
@@ -35,7 +41,7 @@ class Item {
);
}
else {
- $r = q("select * from item where mid = '%s' and uid = %d and item_type = "
+ $r = q("select * from item where mid = '%s' and uid = %d and item_type = "
. intval(ITEM_TYPE_WEBPAGE) . " $sql_extra limit 1",
dbesc($arr['mid']),
intval($channel_id)
diff --git a/Zotlabs/Widget/Menu_preview.php b/Zotlabs/Widget/Menu_preview.php
index 51218f6cf..ddeb4d12c 100644
--- a/Zotlabs/Widget/Menu_preview.php
+++ b/Zotlabs/Widget/Menu_preview.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Menu preview
+ * * Description: Shows a preview of the current menu
+ * * Requires: mitem
+ */
+
namespace Zotlabs\Widget;
require_once('include/menu.php');
diff --git a/Zotlabs/Widget/Messages.php b/Zotlabs/Widget/Messages.php
index 71f4bd310..d045ae85b 100644
--- a/Zotlabs/Widget/Messages.php
+++ b/Zotlabs/Widget/Messages.php
@@ -1,5 +1,13 @@
<?php
+/**
+ * * Name: HQ Messages
+ * * Description: Quick access to messages, direct messages, starred messages (if enabled) and notifications
+ * * Author: Mario Vavti
+ * * Requires: hq
+ */
+
+
namespace Zotlabs\Widget;
use App;
@@ -17,8 +25,8 @@ class Messages {
$tpl = get_markup_template('messages_widget.tpl');
$o = replace_macros($tpl, [
- '$entries' => $page['entries'],
- '$offset' => $page['offset'],
+ '$entries' => $page['entries'] ?? [],
+ '$offset' => $page['offset'] ?? 0,
'$feature_star' => feature_enabled(local_channel(), 'star_posts'),
'$strings' => [
'messages_title' => t('Public and restricted messages'),
@@ -37,11 +45,11 @@ class Messages {
if (!local_channel())
return;
- if ($options['offset'] == -1) {
+ if (isset($options['offset']) && $options['offset'] == -1) {
return;
}
- if ($options['type'] == 'notification') {
+ if (isset($options['type']) && $options['type'] == 'notification') {
return self::get_notices_page($options);
}
@@ -103,13 +111,20 @@ class Messages {
if (!$summary) {
$summary = $item['summary'];
}
+
if (!$summary) {
- $summary = htmlentities(html2plain(bbcode($item['body'], ['drop_media' => true]), 75, true), ENT_QUOTES, 'UTF-8', false);
+ $summary = html2plain(bbcode($item['body'], ['drop_media' => true]), 75, true);
+ if ($summary) {
+ $summary = htmlentities($summary, ENT_QUOTES, 'UTF-8', false);
+ }
}
+
if (!$summary) {
$summary = '...';
}
- $summary = substr_words($summary, 68);
+ else {
+ $summary = substr_words($summary, 68);
+ }
switch(intval($item['item_private'])) {
case 1:
diff --git a/Zotlabs/Widget/Newmember.php b/Zotlabs/Widget/Newmember.php
index 224f7a8a2..70a858fb0 100644
--- a/Zotlabs/Widget/Newmember.php
+++ b/Zotlabs/Widget/Newmember.php
@@ -1,5 +1,10 @@
<?php
+/**
+ * * Name: New member
+ * * Description: Display useful links for new members to help them get started
+ */
+
namespace Zotlabs\Widget;
class Newmember {
@@ -29,7 +34,7 @@ class Newmember {
$options = [
t('Profile Creation'),
- [
+ [
'profile_photo' => t('Upload profile photo'),
'cover_photo' => t('Upload cover photo'),
'profiles' => t('Edit your profile'),
@@ -84,4 +89,4 @@ class Newmember {
}
-
+
diff --git a/Zotlabs/Widget/Notes.php b/Zotlabs/Widget/Notes.php
index 659b62390..2e8e04e93 100644
--- a/Zotlabs/Widget/Notes.php
+++ b/Zotlabs/Widget/Notes.php
@@ -1,5 +1,13 @@
<?php
+/**
+ * * Name: Notes
+ * * Description: A simple notes widget, requires the Notes App
+ * * Author: Mike Macgirvin
+ * * Author: Mario Vavti
+ * * Maintainer: Mario Vavti
+ */
+
namespace Zotlabs\Widget;
use Zotlabs\Lib\Apps;
@@ -33,9 +41,6 @@ class Notes {
]
));
-
-
-
return $o;
}
}
diff --git a/Zotlabs/Widget/Notifications.php b/Zotlabs/Widget/Notifications.php
index a818ae40a..0e02d5cc1 100644
--- a/Zotlabs/Widget/Notifications.php
+++ b/Zotlabs/Widget/Notifications.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Notifications
+ * * Description: Shows all kind of notifications
+ * * Author: Mario Vavti
+ */
+
namespace Zotlabs\Widget;
class Notifications {
diff --git a/Zotlabs/Widget/Permcats.php b/Zotlabs/Widget/Permcats.php
index a908f6220..9226b3c71 100644
--- a/Zotlabs/Widget/Permcats.php
+++ b/Zotlabs/Widget/Permcats.php
@@ -1,5 +1,12 @@
<?php
+/**
+ * * Name: Contact roles
+ * * Description: Display a menu with all defined contact roles and contacts which are assigned to the selected role
+ * * Author: Mario Vavti
+ * * Requires: permcats
+ */
+
namespace Zotlabs\Widget;
use Zotlabs\Lib\Permcat;
diff --git a/Zotlabs/Widget/Photo.php b/Zotlabs/Widget/Photo.php
index 10031f028..5ad6c604c 100644
--- a/Zotlabs/Widget/Photo.php
+++ b/Zotlabs/Widget/Photo.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Photo
+ * * Description: Displays a single photo
+ */
+
+
namespace Zotlabs\Widget;
diff --git a/Zotlabs/Widget/Photo_albums.php b/Zotlabs/Widget/Photo_albums.php
index 6df8ddf3c..2ce916048 100644
--- a/Zotlabs/Widget/Photo_albums.php
+++ b/Zotlabs/Widget/Photo_albums.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Photo albums
+ * * Description: Displays a menu with links to existing photo albums
+ * * Requires: photos
+ */
+
namespace Zotlabs\Widget;
require_once('include/photos.php');
diff --git a/Zotlabs/Widget/Photo_rand.php b/Zotlabs/Widget/Photo_rand.php
index af80a3b9f..cfe026b19 100644
--- a/Zotlabs/Widget/Photo_rand.php
+++ b/Zotlabs/Widget/Photo_rand.php
@@ -1,5 +1,10 @@
<?php
+/**
+ * * Name: Random photo
+ * * Description: Display a random photo
+ */
+
namespace Zotlabs\Widget;
require_once('include/photos.php');
@@ -40,15 +45,15 @@ class Photo_rand {
if(strpos($url, 'http') !== 0)
return '';
-
+
if(array_key_exists('style', $arr) && isset($arr['style']))
$style = $arr['style'];
-
+
// ensure they can't sneak in an eval(js) function
if(strpos($style,'(') !== false)
return '';
-
+
$url = zid($url);
$o = '<div class="widget">';
diff --git a/Zotlabs/Widget/Pinned.php b/Zotlabs/Widget/Pinned.php
index 66d06bbd3..83036e98c 100644
--- a/Zotlabs/Widget/Pinned.php
+++ b/Zotlabs/Widget/Pinned.php
@@ -1,11 +1,14 @@
<?php
namespace Zotlabs\Widget;
-/*
- * Show pinned content
- *
+/**
+ * * Name: Pinned items
+ * * Description: Display pinned items
+ * * Author: Max Kostikov
+ * * Requires: disabled_for_pdledit_gui
*/
+
class Pinned {
private $allowed_types = 0;
diff --git a/Zotlabs/Widget/Portfolio.php b/Zotlabs/Widget/Portfolio.php
index 0cd043246..a06f56e30 100644
--- a/Zotlabs/Widget/Portfolio.php
+++ b/Zotlabs/Widget/Portfolio.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Portfolio
+ * * Description: Display a photo album in a portfolio style
+ * * Requires: channel, articles, cards, wiki
+ */
+
namespace Zotlabs\Widget;
require_once('include/attach.php');
@@ -8,11 +14,9 @@ class Portfolio {
function widget($args) {
-
$owner_uid = \App::$profile_uid;
$sql_extra = permissions_sql($owner_uid);
-
if(! perm_is_allowed($owner_uid,get_observer_hash(),'view_storage'))
return '';
@@ -112,7 +116,7 @@ class Portfolio {
'$upload_form' => $upload_form,
'$usage' => $usage_message
));
-
+
return $o;
}
}
diff --git a/Zotlabs/Widget/Privacygroups.php b/Zotlabs/Widget/Privacygroups.php
index a6b16c552..62f343ea6 100644
--- a/Zotlabs/Widget/Privacygroups.php
+++ b/Zotlabs/Widget/Privacygroups.php
@@ -1,5 +1,12 @@
<?php
+/**
+ * * Name: Privacy Groups
+ * * Description: Display a menu with links to existing privacy groups
+ * * Requires: group
+ */
+
+
namespace Zotlabs\Widget;
use Zotlabs\Lib\AccessList;
diff --git a/Zotlabs/Widget/Profile.php b/Zotlabs/Widget/Profile.php
index 0e5444a56..a0bb1a66a 100644
--- a/Zotlabs/Widget/Profile.php
+++ b/Zotlabs/Widget/Profile.php
@@ -1,5 +1,12 @@
<?php
+/**
+ * * Name: Profile
+ * * Description: Your profile card
+ * * Requires: channel, articles, cards, wiki, cloud, photos
+ */
+
+
namespace Zotlabs\Widget;
use App;
diff --git a/Zotlabs/Widget/Pubsites.php b/Zotlabs/Widget/Pubsites.php
deleted file mode 100644
index 958ba68c2..000000000
--- a/Zotlabs/Widget/Pubsites.php
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-
-namespace Zotlabs\Widget;
-
-class Pubsites {
-
- // used by site ratings pages to provide a return link
-
- function widget($arr) {
- if(\App::$poi)
- return;
- return '<div class="widget"><ul class="nav nav-pills"><li><a href="pubsites">' . t('Public Hubs') . '</a></li></ul></div>';
- }
-}
-
-
diff --git a/Zotlabs/Widget/Pubtagcloud.php b/Zotlabs/Widget/Pubtagcloud.php
index 826e3e6ae..db7ea02e7 100644
--- a/Zotlabs/Widget/Pubtagcloud.php
+++ b/Zotlabs/Widget/Pubtagcloud.php
@@ -1,5 +1,10 @@
<?php
+/**
+ * * Name: Public stream tags
+ * * Description: Display public stream tags in a cloud
+ */
+
namespace Zotlabs\Widget;
class Pubtagcloud {
diff --git a/Zotlabs/Widget/Random_block.php b/Zotlabs/Widget/Random_block.php
index 465a51f97..9052bea03 100644
--- a/Zotlabs/Widget/Random_block.php
+++ b/Zotlabs/Widget/Random_block.php
@@ -1,5 +1,10 @@
<?php
+/**
+ * * Name: Random block
+ * * Description: Display a random block item
+ */
+
namespace Zotlabs\Widget;
class Random_block {
diff --git a/Zotlabs/Widget/Rating.php b/Zotlabs/Widget/Rating.php
index 5e09f457b..20c27ff1c 100644
--- a/Zotlabs/Widget/Rating.php
+++ b/Zotlabs/Widget/Rating.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Rating
+ * * Description: Deprecated rating tool
+ * * Requires: disabled_for_pdledit_gui
+ */
+
namespace Zotlabs\Widget;
class Rating {
diff --git a/Zotlabs/Widget/Savedsearch.php b/Zotlabs/Widget/Savedsearch.php
index 378c27139..660fd6d81 100644
--- a/Zotlabs/Widget/Savedsearch.php
+++ b/Zotlabs/Widget/Savedsearch.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Saved searches
+ * * Description: A search form which also displays saved searches if the feature is enabled
+ * * Requires: network
+ */
+
namespace Zotlabs\Widget;
class Savedsearch {
diff --git a/Zotlabs/Widget/Settings_menu.php b/Zotlabs/Widget/Settings_menu.php
index 4d0f1d2dd..ef269d84b 100644
--- a/Zotlabs/Widget/Settings_menu.php
+++ b/Zotlabs/Widget/Settings_menu.php
@@ -1,5 +1,10 @@
<?php
+/**
+ * * Name: Settings menu
+ * * Description: Display the channel settings menu
+ */
+
namespace Zotlabs\Widget;
class Settings_menu {
diff --git a/Zotlabs/Widget/Shortprofile.php b/Zotlabs/Widget/Shortprofile.php
deleted file mode 100644
index 9c2a46e75..000000000
--- a/Zotlabs/Widget/Shortprofile.php
+++ /dev/null
@@ -1,18 +0,0 @@
-<?php
-
-namespace Zotlabs\Widget;
-
-class Shortprofile {
-
- function widget($arr) {
-
- if(! \App::$profile['profile_uid'])
- return;
-
- $block = observer_prohibited();
-
- return profile_sidebar(\App::$profile, $block, true, true);
- }
-
-}
-
diff --git a/Zotlabs/Widget/Sitesearch.php b/Zotlabs/Widget/Sitesearch.php
index b3a25d76a..a5f1a5935 100644
--- a/Zotlabs/Widget/Sitesearch.php
+++ b/Zotlabs/Widget/Sitesearch.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Search
+ * * Description: A search form
+ * * Requires: search, network, channel
+ */
+
namespace Zotlabs\Widget;
diff --git a/Zotlabs/Widget/Suggestedchats.php b/Zotlabs/Widget/Suggestedchats.php
index 7df42944d..75df0c9e6 100644
--- a/Zotlabs/Widget/Suggestedchats.php
+++ b/Zotlabs/Widget/Suggestedchats.php
@@ -1,14 +1,18 @@
<?php
+/**
+ * * Name: Suggested chats
+ * * Description: A menu with chatroom suggestions
+ * * Requires: disabled_due_to_reasons
+ */
+
+
namespace Zotlabs\Widget;
class Suggestedchats {
function widget($arr) {
- if(! feature_enabled(\App::$profile['profile_uid'],'ajaxchat'))
- return '';
-
// There are reports that this tool does not ever remove chatrooms on dead sites,
// and also will happily link to private chats which you cannot enter.
// For those reasons, it will be disabled until somebody decides it's worth
diff --git a/Zotlabs/Widget/Suggestions.php b/Zotlabs/Widget/Suggestions.php
index b4f384e9d..e7d23bda4 100644
--- a/Zotlabs/Widget/Suggestions.php
+++ b/Zotlabs/Widget/Suggestions.php
@@ -1,5 +1,10 @@
<?php
+/**
+ * * Name: Suggestions
+ * * Description: Display suggestions for new contacts
+ */
+
namespace Zotlabs\Widget;
use Zotlabs\Lib\Apps;
@@ -12,7 +17,7 @@ class Suggestions {
function widget($arr) {
- if((! local_channel()) || (! Apps::system_app_installed(local_channel(), 'Suggest Channels')))
+ if(! local_channel())
return EMPTY_STR;
$r = suggestion_query(local_channel(),get_observer_hash(),0,20);
@@ -23,14 +28,14 @@ class Suggestions {
$arr = array();
- // Get two random entries from the top 20 returned.
+ // Get four random entries from the top 20 returned.
// We'll grab the first one and the one immediately following.
// This will throw some entropy intot he situation so you won't
// be looking at the same two mug shots every time the widget runs
- $index = ((count($r) > 2) ? mt_rand(0,count($r) - 2) : 0);
+ $index = ((count($r) > 4) ? mt_rand(0,count($r) - 4) : 0);
- for($x = $index; $x <= ($index+1); $x ++) {
+ for($x = $index; $x <= ($index+3); $x ++) {
$rr = $r[$x];
if(! $rr['xchan_url'])
break;
diff --git a/Zotlabs/Widget/Tagcloud.php b/Zotlabs/Widget/Tagcloud.php
index f79bd59ad..00456f24f 100644
--- a/Zotlabs/Widget/Tagcloud.php
+++ b/Zotlabs/Widget/Tagcloud.php
@@ -2,6 +2,11 @@
namespace Zotlabs\Widget;
+/**
+ * * Name: Tag cloud
+ * * Description: Display hashtags of your network items in a cloud
+ * * Requires: network, hq
+ */
class Tagcloud {
diff --git a/Zotlabs/Widget/Tagcloud_wall.php b/Zotlabs/Widget/Tagcloud_wall.php
index 7cff6ce09..20def4ab1 100644
--- a/Zotlabs/Widget/Tagcloud_wall.php
+++ b/Zotlabs/Widget/Tagcloud_wall.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Tag cloud wall
+ * * Description: Display hashtags of your channel wall items in a cloud if the feature is enabled
+ * * Requires: channel
+ */
+
namespace Zotlabs\Widget;
class Tagcloud_wall {
diff --git a/Zotlabs/Widget/Tasklist.php b/Zotlabs/Widget/Tasklist.php
index 56342bd17..5ecfd5a27 100644
--- a/Zotlabs/Widget/Tasklist.php
+++ b/Zotlabs/Widget/Tasklist.php
@@ -1,8 +1,11 @@
<?php
-namespace Zotlabs\Widget;
+/**
+ * * Name: Task list
+ * * Description: Simple task list mangager
+ */
-require_once('include/event.php');
+namespace Zotlabs\Widget;
class Tasklist {
@@ -20,7 +23,7 @@ class Tasklist {
}
</script>';
- $o .= '<div class="widget">' . '<h3>' . t('Tasks') . '</h3><div class="tasklist-tasks">';
+ $o .= '<div class="widget">' . '<h3>' . t('Tasks') . '</h3><div class="tasklist-tasks mb-1">';
$o .= '</div><form id="tasklist-new-form" action="" ><input class="form-control" id="tasklist-new-summary" type="text" name="summary" value="" /></form>';
$o .= '</div>';
return $o;
diff --git a/Zotlabs/Widget/Tokens.php b/Zotlabs/Widget/Tokens.php
index 8c31003fc..69452d628 100644
--- a/Zotlabs/Widget/Tokens.php
+++ b/Zotlabs/Widget/Tokens.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Tokens
+ * * Description: Display a menu with links to existing guest access tokens
+ * * Requires: tokens
+ */
+
namespace Zotlabs\Widget;
class Tokens {
diff --git a/Zotlabs/Widget/Vcard.php b/Zotlabs/Widget/Vcard.php
index cab05dfdd..25bb8592c 100644
--- a/Zotlabs/Widget/Vcard.php
+++ b/Zotlabs/Widget/Vcard.php
@@ -1,5 +1,10 @@
<?php
+/**
+ * * Name: Vcard
+ * * Description: Your default profile card
+ */
+
namespace Zotlabs\Widget;
class Vcard {
diff --git a/Zotlabs/Widget/Website_portation_tools.php b/Zotlabs/Widget/Website_portation_tools.php
index 1cf3bb78a..61fe48169 100644
--- a/Zotlabs/Widget/Website_portation_tools.php
+++ b/Zotlabs/Widget/Website_portation_tools.php
@@ -1,7 +1,12 @@
<?php
-namespace Zotlabs\Widget;
+/**
+ * * Name: Website import/export
+ * * Description: Tools to import and export websites
+ * * Requires: website
+ */
+namespace Zotlabs\Widget;
class Website_portation_tools {
diff --git a/Zotlabs/Widget/Wiki_list.php b/Zotlabs/Widget/Wiki_list.php
index 64c988ee7..217ab8706 100644
--- a/Zotlabs/Widget/Wiki_list.php
+++ b/Zotlabs/Widget/Wiki_list.php
@@ -1,5 +1,10 @@
<?php
+/**
+ * * Name: Wiki list
+ * * Description: A list of existing wikis
+ */
+
namespace Zotlabs\Widget;
class Wiki_list {
diff --git a/Zotlabs/Widget/Wiki_page_history.php b/Zotlabs/Widget/Wiki_page_history.php
index dbb322dc3..3c9f5ed1a 100644
--- a/Zotlabs/Widget/Wiki_page_history.php
+++ b/Zotlabs/Widget/Wiki_page_history.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Wiki page history
+ * * Description: History of an existing wiki page
+ * * Requires: wiki
+ */
+
namespace Zotlabs\Widget;
class Wiki_page_history {
@@ -10,7 +16,7 @@ class Wiki_page_history {
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
$pageHistory = \Zotlabs\Lib\NativeWikiPage::page_history([
- 'channel_id' => \App::$profile_uid,
+ 'channel_id' => \App::$profile_uid,
'observer_hash' => get_observer_hash(),
'resource_id' => $resource_id,
'pageUrlName' => $pageUrlName
diff --git a/Zotlabs/Widget/Wiki_pages.php b/Zotlabs/Widget/Wiki_pages.php
index dee0a2229..ece712334 100644
--- a/Zotlabs/Widget/Wiki_pages.php
+++ b/Zotlabs/Widget/Wiki_pages.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * * Name: Wiki pages
+ * * Description: A list of existing pages of a wiki
+ * * Requires: wiki
+ */
+
namespace Zotlabs\Widget;
use Zotlabs\Lib\NativeWiki;
@@ -34,7 +40,7 @@ class Wiki_pages {
'$addnew' => t('Add new page'),
'$typelock' => $typelock,
'$lockedtype' => $w['mimeType'],
- '$mimetype' => mimetype_select(0,$w['mimeType'],
+ '$mimetype' => mimetype_select(0,$w['mimeType'],
[ 'text/markdown' => t('Markdown'), 'text/bbcode' => t('BBcode'), 'text/plain' => t('Text') ]),
'$pageName' => array('missingPageName', 'Create Page' , $pageName),
'$refresh' => $arr['refresh'],
@@ -91,7 +97,7 @@ class Wiki_pages {
'$addnew' => t('Add new page'),
'$typelock' => $typelock,
'$lockedtype' => $w['mimeType'],
- '$mimetype' => mimetype_select(0,$w['mimeType'],
+ '$mimetype' => mimetype_select(0,$w['mimeType'],
[ 'text/markdown' => t('Markdown'), 'text/bbcode' => t('BBcode'), 'text/plain' => t('Text') ]),
'$pageName' => array('pageName', t('Page name')),
'$refresh' => $arr['refresh'],
diff --git a/Zotlabs/Widget/Zcard.php b/Zotlabs/Widget/Zcard.php
index 12e53eaab..35362c50e 100644
--- a/Zotlabs/Widget/Zcard.php
+++ b/Zotlabs/Widget/Zcard.php
@@ -1,5 +1,10 @@
<?php
+/**
+ * * Name: Zcard
+ * * Description: Your default profile card including your cover photo
+ */
+
namespace Zotlabs\Widget;
class Zcard {